Skip to content

Commit ab59a13

Browse files
committed
feat(freezeV2): add a lock option for delegate
1 parent 1d80094 commit ab59a13

File tree

6 files changed

+128
-42
lines changed

6 files changed

+128
-42
lines changed

actuator/src/main/java/org/tron/core/actuator/DelegateResourceActuator.java

+22-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.tron.core.actuator;
22

33
import static org.tron.core.actuator.ActuatorConstant.NOT_EXIST_STR;
4+
import static org.tron.core.config.Parameter.ChainConstant.DELEGATE_PERIOD;
45
import static org.tron.core.config.Parameter.ChainConstant.TRX_PRECISION;
56

67
import com.google.protobuf.ByteString;
@@ -57,21 +58,22 @@ public boolean execute(Object result) throws ContractExeException {
5758
.get(delegateResourceContract.getOwnerAddress().toByteArray());
5859

5960
long delegateBalance = delegateResourceContract.getBalance();
61+
boolean lock = delegateResourceContract.getLock();
6062
byte[] ownerAddress = delegateResourceContract.getOwnerAddress().toByteArray();
6163
byte[] receiverAddress = delegateResourceContract.getReceiverAddress().toByteArray();
6264

6365
// delegate resource to receiver
6466
switch (delegateResourceContract.getResource()) {
6567
case BANDWIDTH:
6668
delegateResource(ownerAddress, receiverAddress, true,
67-
delegateBalance);
69+
delegateBalance, lock);
6870

6971
ownerCapsule.addDelegatedFrozenV2BalanceForBandwidth(delegateBalance);
7072
ownerCapsule.addFrozenBalanceForBandwidthV2(-delegateBalance);
7173
break;
7274
case ENERGY:
7375
delegateResource(ownerAddress, receiverAddress, false,
74-
delegateBalance);
76+
delegateBalance, lock);
7577

7678
ownerCapsule.addDelegatedFrozenV2BalanceForEnergy(delegateBalance);
7779
ownerCapsule.addFrozenBalanceForEnergyV2(-delegateBalance);
@@ -227,26 +229,36 @@ public long calcFee() {
227229
}
228230

229231
private void delegateResource(byte[] ownerAddress, byte[] receiverAddress, boolean isBandwidth,
230-
long balance) {
232+
long balance, boolean lock) {
231233
AccountStore accountStore = chainBaseManager.getAccountStore();
232234
DynamicPropertiesStore dynamicPropertiesStore = chainBaseManager.getDynamicPropertiesStore();
233235
DelegatedResourceStore delegatedResourceStore = chainBaseManager.getDelegatedResourceStore();
234236
DelegatedResourceAccountIndexStore delegatedResourceAccountIndexStore = chainBaseManager
235237
.getDelegatedResourceAccountIndexStore();
236238

239+
// 1. unlock the expired delegate resource
240+
long now = chainBaseManager.getDynamicPropertiesStore().getLatestBlockHeaderTimestamp();
241+
delegatedResourceStore.unLockExpireResource(ownerAddress, receiverAddress, now);
242+
237243
//modify DelegatedResourceStore
238-
byte[] key = DelegatedResourceCapsule.createDbKeyV2(ownerAddress, receiverAddress);
239-
DelegatedResourceCapsule delegatedResourceCapsule = delegatedResourceStore
240-
.get(key);
244+
byte[] key;
245+
long expireTime = 0;
246+
if (lock) {
247+
expireTime = now + DELEGATE_PERIOD;
248+
key = DelegatedResourceCapsule.createLockDbKeyV2(ownerAddress, receiverAddress);
249+
} else {
250+
key = DelegatedResourceCapsule.createDbKeyV2(ownerAddress, receiverAddress);
251+
}
252+
DelegatedResourceCapsule delegatedResourceCapsule = delegatedResourceStore.get(key);
241253
if (delegatedResourceCapsule == null) {
242-
delegatedResourceCapsule = new DelegatedResourceCapsule(
243-
ByteString.copyFrom(ownerAddress),
254+
delegatedResourceCapsule = new DelegatedResourceCapsule(ByteString.copyFrom(ownerAddress),
244255
ByteString.copyFrom(receiverAddress));
245256
}
257+
246258
if (isBandwidth) {
247-
delegatedResourceCapsule.addFrozenBalanceForBandwidth(balance, 0);
259+
delegatedResourceCapsule.addFrozenBalanceForBandwidth(balance, expireTime);
248260
} else {
249-
delegatedResourceCapsule.addFrozenBalanceForEnergy(balance, 0);
261+
delegatedResourceCapsule.addFrozenBalanceForEnergy(balance, expireTime);
250262
}
251263
delegatedResourceStore.put(key, delegatedResourceCapsule);
252264

actuator/src/main/java/org/tron/core/actuator/UnDelegateResourceActuator.java

+56-26
Original file line numberDiff line numberDiff line change
@@ -121,16 +121,20 @@ public boolean execute(Object result) throws ContractExeException {
121121
accountStore.put(receiverCapsule.createDbKey(), receiverCapsule);
122122
}
123123

124+
// transfer lock delegate to unlock
125+
delegatedResourceStore.unLockExpireResource(ownerAddress, receiverAddress,
126+
dynamicStore.getLatestBlockHeaderTimestamp());
127+
128+
byte[] unlockKey = DelegatedResourceCapsule
129+
.createDbKeyV2(ownerAddress, receiverAddress);
130+
DelegatedResourceCapsule unlockResource = delegatedResourceStore
131+
.get(unlockKey);
132+
124133
// modify owner Account
125134
AccountCapsule ownerCapsule = accountStore.get(ownerAddress);
126-
byte[] key = DelegatedResourceCapsule
127-
.createDbKeyV2(unDelegateResourceContract.getOwnerAddress().toByteArray(),
128-
unDelegateResourceContract.getReceiverAddress().toByteArray());
129-
DelegatedResourceCapsule delegatedResourceCapsule = delegatedResourceStore
130-
.get(key);
131135
switch (unDelegateResourceContract.getResource()) {
132136
case BANDWIDTH: {
133-
delegatedResourceCapsule.addFrozenBalanceForBandwidth(-unDelegateBalance, 0);
137+
unlockResource.addFrozenBalanceForBandwidth(-unDelegateBalance, 0);
134138

135139
ownerCapsule.addDelegatedFrozenV2BalanceForBandwidth(-unDelegateBalance);
136140
ownerCapsule.addFrozenBalanceForBandwidthV2(unDelegateBalance);
@@ -146,7 +150,7 @@ public boolean execute(Object result) throws ContractExeException {
146150
}
147151
break;
148152
case ENERGY: {
149-
delegatedResourceCapsule.addFrozenBalanceForEnergy(-unDelegateBalance, 0);
153+
unlockResource.addFrozenBalanceForEnergy(-unDelegateBalance, 0);
150154

151155
ownerCapsule.addDelegatedFrozenV2BalanceForEnergy(-unDelegateBalance);
152156
ownerCapsule.addFrozenBalanceForEnergyV2(unDelegateBalance);
@@ -166,14 +170,21 @@ public boolean execute(Object result) throws ContractExeException {
166170
break;
167171
}
168172

169-
if (delegatedResourceCapsule.getFrozenBalanceForBandwidth() == 0
170-
&& delegatedResourceCapsule.getFrozenBalanceForEnergy() == 0) {
171-
delegatedResourceStore.delete(key);
173+
if (unlockResource.getFrozenBalanceForBandwidth() == 0
174+
&& unlockResource.getFrozenBalanceForEnergy() == 0) {
175+
delegatedResourceStore.delete(unlockKey);
176+
unlockResource = null;
177+
} else {
178+
delegatedResourceStore.put(unlockKey, unlockResource);
179+
}
172180

181+
byte[] lockKey = DelegatedResourceCapsule
182+
.createLockDbKeyV2(ownerAddress, receiverAddress);
183+
DelegatedResourceCapsule lockResource = delegatedResourceStore
184+
.get(lockKey);
185+
if (lockResource == null && unlockResource == null) {
173186
//modify DelegatedResourceAccountIndexStore
174187
delegatedResourceAccountIndexStore.unDelegateV2(ownerAddress, receiverAddress);
175-
} else {
176-
delegatedResourceStore.put(key, delegatedResourceCapsule);
177188
}
178189

179190
accountStore.put(ownerAddress, ownerCapsule);
@@ -244,11 +255,12 @@ public boolean validate() throws ContractValidateException {
244255
// "Receiver Account[" + readableReceiverAddress + "] does not exist");
245256
// }
246257

247-
byte[] key = DelegatedResourceCapsule
248-
.createDbKeyV2(unDelegateResourceContract.getOwnerAddress().toByteArray(),
249-
unDelegateResourceContract.getReceiverAddress().toByteArray());
258+
long now = dynamicStore.getLatestBlockHeaderTimestamp();
259+
byte[] key = DelegatedResourceCapsule.createDbKeyV2(ownerAddress, receiverAddress);
250260
DelegatedResourceCapsule delegatedResourceCapsule = delegatedResourceStore.get(key);
251-
if (delegatedResourceCapsule == null) {
261+
byte[] lockKey = DelegatedResourceCapsule.createLockDbKeyV2(ownerAddress, receiverAddress);
262+
DelegatedResourceCapsule lockResourceCapsule = delegatedResourceStore.get(lockKey);
263+
if (delegatedResourceCapsule == null && lockResourceCapsule == null) {
252264
throw new ContractValidateException(
253265
"delegated Resource does not exist");
254266
}
@@ -258,24 +270,42 @@ public boolean validate() throws ContractValidateException {
258270
throw new ContractValidateException("unDelegateBalance must be more than 0 TRX");
259271
}
260272
switch (unDelegateResourceContract.getResource()) {
261-
case BANDWIDTH:
262-
if (delegatedResourceCapsule.getFrozenBalanceForBandwidth() < unDelegateBalance) {
263-
throw new ContractValidateException("insufficient delegatedFrozenBalance(BANDWIDTH), request="
264-
+ unDelegateBalance + ", balance=" + delegatedResourceCapsule.getFrozenBalanceForBandwidth());
273+
case BANDWIDTH: {
274+
long delegateBalance = 0;
275+
if (delegatedResourceCapsule != null) {
276+
delegateBalance += delegatedResourceCapsule.getFrozenBalanceForBandwidth();
265277
}
266-
break;
267-
case ENERGY:
268-
if (delegatedResourceCapsule.getFrozenBalanceForEnergy() < unDelegateBalance) {
278+
if (lockResourceCapsule != null
279+
&& lockResourceCapsule.getExpireTimeForBandwidth() < now) {
280+
delegateBalance += lockResourceCapsule.getFrozenBalanceForBandwidth();
281+
}
282+
if (delegateBalance < unDelegateBalance) {
283+
throw new ContractValidateException(
284+
"insufficient delegatedFrozenBalance(BANDWIDTH), request="
285+
+ unDelegateBalance + ", unlock_balance=" + delegateBalance);
286+
}
287+
}
288+
break;
289+
case ENERGY: {
290+
long delegateBalance = 0;
291+
if (delegatedResourceCapsule != null) {
292+
delegateBalance += delegatedResourceCapsule.getFrozenBalanceForEnergy();
293+
}
294+
if (lockResourceCapsule != null
295+
&& lockResourceCapsule.getExpireTimeForEnergy() < now) {
296+
delegateBalance += lockResourceCapsule.getFrozenBalanceForEnergy();
297+
}
298+
if (delegateBalance < unDelegateBalance) {
269299
throw new ContractValidateException("insufficient delegateFrozenBalance(Energy), request="
270-
+ unDelegateBalance + ", balance=" + delegatedResourceCapsule.getFrozenBalanceForEnergy());
300+
+ unDelegateBalance + ", unlock_balance=" + delegateBalance);
271301
}
272-
break;
302+
}
303+
break;
273304
default:
274305
throw new ContractValidateException(
275306
"ResourceCode error.valid ResourceCode[BANDWIDTH、Energy]");
276307
}
277308

278-
279309
return true;
280310
}
281311

chainbase/src/main/java/org/tron/core/capsule/DelegatedResourceCapsule.java

+9-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.tron.core.capsule;
22

3+
import com.google.common.primitives.Bytes;
34
import com.google.protobuf.ByteString;
45
import com.google.protobuf.InvalidProtocolBufferException;
56
import lombok.extern.slf4j.Slf4j;
@@ -9,7 +10,9 @@
910
@Slf4j(topic = "capsule")
1011
public class DelegatedResourceCapsule implements ProtoCapsule<DelegatedResource> {
1112

12-
private static final byte[] V2_PREFIX = {0x01};
13+
public static final byte[] V2_PREFIX = new byte[]{0x01};
14+
public static final byte[] V2_LOCK_PREFIX = new byte[]{0x02};
15+
1316
private DelegatedResource delegatedResource;
1417

1518
public DelegatedResourceCapsule(final DelegatedResource delegatedResource) {
@@ -39,11 +42,11 @@ public static byte[] createDbKey(byte[] from, byte[] to) {
3942
}
4043

4144
public static byte[] createDbKeyV2(byte[] from, byte[] to) {
42-
byte[] key = new byte[V2_PREFIX.length + from.length + to.length];
43-
System.arraycopy(V2_PREFIX, 0, key, 0, V2_PREFIX.length);
44-
System.arraycopy(from, 0, key, V2_PREFIX.length, from.length);
45-
System.arraycopy(to, 0, key, V2_PREFIX.length + from.length, to.length);
46-
return key;
45+
return Bytes.concat(V2_PREFIX, from, to);
46+
}
47+
48+
public static byte[] createLockDbKeyV2(byte[] from, byte[] to) {
49+
return Bytes.concat(V2_LOCK_PREFIX, from, to);
4750
}
4851

4952
public ByteString getFrom() {

chainbase/src/main/java/org/tron/core/store/DelegatedResourceStore.java

+39
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.tron.core.store;
22

3+
import com.google.protobuf.ByteString;
34
import java.util.List;
45
import java.util.Objects;
56
import java.util.stream.Collectors;
@@ -33,4 +34,42 @@ public List<DelegatedResourceCapsule> getByFrom(byte[] key) {
3334
.collect(Collectors.toList());
3435
}
3536

37+
public void unLockExpireResource(byte[] from, byte[] to, long now) {
38+
byte[] lockKey = DelegatedResourceCapsule
39+
.createLockDbKeyV2(from, to);
40+
DelegatedResourceCapsule lockResource = get(lockKey);
41+
if (lockResource == null) {
42+
return;
43+
}
44+
if (lockResource.getExpireTimeForEnergy() >= now
45+
&& lockResource.getExpireTimeForBandwidth() >= now) {
46+
return;
47+
}
48+
49+
byte[] unlockKey = DelegatedResourceCapsule
50+
.createDbKeyV2(from, to);
51+
DelegatedResourceCapsule unlockResource = get(unlockKey);
52+
if (unlockResource == null) {
53+
unlockResource = new DelegatedResourceCapsule(ByteString.copyFrom(from),
54+
ByteString.copyFrom(to));
55+
}
56+
if (lockResource.getExpireTimeForEnergy() < now) {
57+
unlockResource.addFrozenBalanceForEnergy(
58+
lockResource.getFrozenBalanceForEnergy(), 0);
59+
lockResource.setFrozenBalanceForEnergy(0, 0);
60+
}
61+
if (lockResource.getExpireTimeForBandwidth() < now) {
62+
unlockResource.addFrozenBalanceForBandwidth(
63+
lockResource.getFrozenBalanceForBandwidth(), 0);
64+
lockResource.setFrozenBalanceForBandwidth(0, 0);
65+
}
66+
if (lockResource.getFrozenBalanceForBandwidth() == 0
67+
&& lockResource.getFrozenBalanceForEnergy() == 0) {
68+
delete(lockKey);
69+
} else {
70+
put(lockKey, lockResource);
71+
}
72+
put(unlockKey, unlockResource);
73+
}
74+
3675
}

common/src/main/java/org/tron/core/config/Parameter.java

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ public class ChainConstant {
6969
public static final int MAX_FROZEN_NUMBER = 1;
7070
public static final int BLOCK_VERSION = 25;
7171
public static final long FROZEN_PERIOD = 86_400_000L;
72+
public static final long DELEGATE_PERIOD = 3 * 86_400_000L;
7273
public static final long TRX_PRECISION = 1000_000L;
7374
public static final long DELEGATE_COST_BASE_SIZE = 275L;
7475
}

protocol/src/main/protos/core/contract/balance_contract.proto

+1
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ message DelegateResourceContract {
102102
ResourceCode resource = 2;
103103
int64 balance = 3;
104104
bytes receiver_address = 4;
105+
bool lock = 5;
105106
}
106107

107108
message UnDelegateResourceContract {

0 commit comments

Comments
 (0)