22
33import static org .tron .core .actuator .ActuatorConstant .NOT_EXIST_STR ;
44import static org .tron .core .config .Parameter .ChainConstant .DELEGATE_PERIOD ;
5+ import static org .tron .core .config .Parameter .ChainConstant .MAX_BLOCK_NUM_DELEGATE_PERIOD ;
56import static org .tron .core .config .Parameter .ChainConstant .TRX_PRECISION ;
7+ import static org .tron .protos .contract .Common .ResourceCode ;
8+ import static org .tron .protos .contract .Common .ResourceCode .BANDWIDTH ;
9+ import static org .tron .protos .contract .Common .ResourceCode .ENERGY ;
610
711import com .google .protobuf .ByteString ;
812import com .google .protobuf .InvalidProtocolBufferException ;
@@ -46,8 +50,10 @@ public boolean execute(Object result) throws ContractExeException {
4650 long fee = calcFee ();
4751 final DelegateResourceContract delegateResourceContract ;
4852 AccountStore accountStore = chainBaseManager .getAccountStore ();
53+ byte [] ownerAddress ;
4954 try {
50- delegateResourceContract = any .unpack (DelegateResourceContract .class );
55+ delegateResourceContract = this .any .unpack (DelegateResourceContract .class );
56+ ownerAddress = getOwnerAddress ().toByteArray ();
5157 } catch (InvalidProtocolBufferException e ) {
5258 logger .debug (e .getMessage (), e );
5359 ret .setStatus (fee , code .FAILED );
@@ -59,21 +65,21 @@ public boolean execute(Object result) throws ContractExeException {
5965
6066 long delegateBalance = delegateResourceContract .getBalance ();
6167 boolean lock = delegateResourceContract .getLock ();
62- byte [] ownerAddress = delegateResourceContract .getOwnerAddress (). toByteArray ();
68+ long lockPeriod = delegateResourceContract .getLockPeriod ();
6369 byte [] receiverAddress = delegateResourceContract .getReceiverAddress ().toByteArray ();
6470
6571 // delegate resource to receiver
6672 switch (delegateResourceContract .getResource ()) {
6773 case BANDWIDTH :
6874 delegateResource (ownerAddress , receiverAddress , true ,
69- delegateBalance , lock );
75+ delegateBalance , lock , lockPeriod );
7076
7177 ownerCapsule .addDelegatedFrozenV2BalanceForBandwidth (delegateBalance );
7278 ownerCapsule .addFrozenBalanceForBandwidthV2 (-delegateBalance );
7379 break ;
7480 case ENERGY :
7581 delegateResource (ownerAddress , receiverAddress , false ,
76- delegateBalance , lock );
82+ delegateBalance , lock , lockPeriod );
7783
7884 ownerCapsule .addDelegatedFrozenV2BalanceForEnergy (delegateBalance );
7985 ownerCapsule .addFrozenBalanceForEnergyV2 (-delegateBalance );
@@ -100,6 +106,7 @@ public boolean validate() throws ContractValidateException {
100106 }
101107 AccountStore accountStore = chainBaseManager .getAccountStore ();
102108 DynamicPropertiesStore dynamicStore = chainBaseManager .getDynamicPropertiesStore ();
109+ DelegatedResourceStore delegatedResourceStore = chainBaseManager .getDelegatedResourceStore ();
103110 if (!any .is (DelegateResourceContract .class )) {
104111 throw new ContractValidateException (
105112 "contract type error,expected type [DelegateResourceContract],real type["
@@ -116,13 +123,14 @@ public boolean validate() throws ContractValidateException {
116123 }
117124
118125 final DelegateResourceContract delegateResourceContract ;
126+ byte [] ownerAddress ;
119127 try {
120128 delegateResourceContract = this .any .unpack (DelegateResourceContract .class );
129+ ownerAddress = getOwnerAddress ().toByteArray ();
121130 } catch (InvalidProtocolBufferException e ) {
122131 logger .debug (e .getMessage (), e );
123132 throw new ContractValidateException (e .getMessage ());
124133 }
125- byte [] ownerAddress = delegateResourceContract .getOwnerAddress ().toByteArray ();
126134 if (!DecodeUtil .addressValid (ownerAddress )) {
127135 throw new ContractValidateException ("Invalid address" );
128136 }
@@ -210,6 +218,36 @@ public boolean validate() throws ContractValidateException {
210218 + readableOwnerAddress + NOT_EXIST_STR );
211219 }
212220
221+ boolean lock = delegateResourceContract .getLock ();
222+ if (lock && dynamicStore .supportAllowOptimizeLockDelegateResource ()) {
223+ long lockPeriod = delegateResourceContract .getLockPeriod ();
224+ if (lockPeriod < 0 || lockPeriod > MAX_BLOCK_NUM_DELEGATE_PERIOD ) {
225+ throw new ContractValidateException (
226+ "The lock period of delegate resource cannot be less than 0 and cannot exceed 1 year!" );
227+ }
228+
229+ byte [] key = DelegatedResourceCapsule .createDbKeyV2 (ownerAddress , receiverAddress , true );
230+ DelegatedResourceCapsule delegatedResourceCapsule = delegatedResourceStore .get (key );
231+ long now = dynamicStore .getLatestBlockHeaderTimestamp ();
232+ if (delegatedResourceCapsule != null ) {
233+ switch (delegateResourceContract .getResource ()) {
234+ case BANDWIDTH : {
235+ validRemainTime (BANDWIDTH , lockPeriod ,
236+ delegatedResourceCapsule .getExpireTimeForBandwidth (), now );
237+ }
238+ break ;
239+ case ENERGY : {
240+ validRemainTime (ENERGY , lockPeriod ,
241+ delegatedResourceCapsule .getExpireTimeForEnergy (), now );
242+ }
243+ break ;
244+ default :
245+ throw new ContractValidateException (
246+ "ResourceCode error, valid ResourceCode[BANDWIDTH、ENERGY]" );
247+ }
248+ }
249+ }
250+
213251 if (receiverCapsule .getType () == AccountType .Contract ) {
214252 throw new ContractValidateException (
215253 "Do not allow delegate resources to contract addresses" );
@@ -218,6 +256,17 @@ public boolean validate() throws ContractValidateException {
218256 return true ;
219257 }
220258
259+ private void validRemainTime (ResourceCode resourceCode , long lockPeriod , long expireTime ,
260+ long now ) throws ContractValidateException {
261+ long remainTime = expireTime - now ;
262+ if (lockPeriod * 3 * 1000 < remainTime ) {
263+ throw new ContractValidateException (
264+ "The lock period for " + resourceCode .name () + " this time cannot be less than the "
265+ + "remaining time[" + remainTime + "s] of the last lock period for "
266+ + resourceCode .name () + "!" );
267+ }
268+ }
269+
221270 @ Override
222271 public ByteString getOwnerAddress () throws InvalidProtocolBufferException {
223272 return any .unpack (DelegateResourceContract .class ).getOwnerAddress ();
@@ -229,7 +278,7 @@ public long calcFee() {
229278 }
230279
231280 private void delegateResource (byte [] ownerAddress , byte [] receiverAddress , boolean isBandwidth ,
232- long balance , boolean lock ) {
281+ long balance , boolean lock , long lockPeriod ) {
233282 AccountStore accountStore = chainBaseManager .getAccountStore ();
234283 DynamicPropertiesStore dynamicPropertiesStore = chainBaseManager .getDynamicPropertiesStore ();
235284 DelegatedResourceStore delegatedResourceStore = chainBaseManager .getDelegatedResourceStore ();
@@ -241,12 +290,15 @@ private void delegateResource(byte[] ownerAddress, byte[] receiverAddress, boole
241290 delegatedResourceStore .unLockExpireResource (ownerAddress , receiverAddress , now );
242291
243292 //modify DelegatedResourceStore
244- byte [] key ;
245293 long expireTime = 0 ;
246294 if (lock ) {
247- expireTime = now + DELEGATE_PERIOD ;
295+ if (dynamicPropertiesStore .supportAllowOptimizeLockDelegateResource ()) {
296+ expireTime = now + (lockPeriod == 0 ? DELEGATE_PERIOD : lockPeriod * 3 * 1000 );
297+ } else {
298+ expireTime = now + DELEGATE_PERIOD ;
299+ }
248300 }
249- key = DelegatedResourceCapsule .createDbKeyV2 (ownerAddress , receiverAddress , lock );
301+ byte [] key = DelegatedResourceCapsule .createDbKeyV2 (ownerAddress , receiverAddress , lock );
250302 DelegatedResourceCapsule delegatedResourceCapsule = delegatedResourceStore .get (key );
251303 if (delegatedResourceCapsule == null ) {
252304 delegatedResourceCapsule = new DelegatedResourceCapsule (ByteString .copyFrom (ownerAddress ),
0 commit comments