Skip to content

Commit

Permalink
Merge pull request tronprotocol#4741 from tronprotocol/feature/unfree…
Browse files Browse the repository at this point in the history
…ze_vote

feat(freezeV2): optimize unfreeze vote
  • Loading branch information
zhang0125 authored Oct 29, 2022
2 parents da581e3 + 24f141b commit 79a190a
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 72 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
package org.tron.core.actuator;

import static org.tron.core.actuator.ActuatorConstant.ACCOUNT_EXCEPTION_STR;
import static org.tron.core.config.Parameter.ChainConstant.FROZEN_PERIOD;
import static org.tron.core.config.Parameter.ChainConstant.TRX_PRECISION;

import com.google.common.collect.Lists;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.tron.common.utils.DecodeUtil;
Expand All @@ -19,17 +26,10 @@
import org.tron.protos.Protocol;
import org.tron.protos.Protocol.Transaction.Contract.ContractType;
import org.tron.protos.Protocol.Transaction.Result.code;
import org.tron.protos.Protocol.Vote;
import org.tron.protos.contract.BalanceContract.UnfreezeBalanceV2Contract;
import org.tron.protos.contract.Common;

import java.util.Iterator;
import java.util.List;
import java.util.Objects;

import static org.tron.core.actuator.ActuatorConstant.ACCOUNT_EXCEPTION_STR;
import static org.tron.core.config.Parameter.ChainConstant.FROZEN_PERIOD;
import static org.tron.core.config.Parameter.ChainConstant.TRX_PRECISION;

@Slf4j(topic = "actuator")
public class UnfreezeBalanceV2Actuator extends AbstractActuator {

Expand Down Expand Up @@ -81,7 +81,7 @@ public boolean execute(Object result) throws ContractExeException {
accountCapsule.addUnfrozenV2List(freezeType, unfreezeBalance, expireTime);

this.updateTotalResourceWeight(unfreezeBalanceV2Contract, unfreezeBalance);
this.clearVotes(accountCapsule,unfreezeBalanceV2Contract, ownerAddress);
this.updateVote(accountCapsule, unfreezeBalanceV2Contract, ownerAddress);

if (dynamicStore.supportAllowNewResourceModel()
&& !accountCapsule.oldTronPowerIsInvalid()) {
Expand Down Expand Up @@ -155,7 +155,7 @@ public boolean validate() throws ContractValidateException {
throw new ContractValidateException("no frozenBalance(TronPower)");
}
} else {
throw new ContractValidateException("ResourceCode error.valid ResourceCode[BANDWIDTH、Energy]");
throw new ContractValidateException("ResourceCode error.valid ResourceCode[BANDWIDTH、Energy]");
}
break;
default:
Expand All @@ -168,7 +168,7 @@ public boolean validate() throws ContractValidateException {

if (!checkUnfreezeBalance(accountCapsule, unfreezeBalanceV2Contract, unfreezeBalanceV2Contract.getResource())) {
throw new ContractValidateException(
"Invalid unfreeze_balance, [" + unfreezeBalanceV2Contract.getUnfreezeBalance() + "] is error"
"Invalid unfreeze_balance, [" + unfreezeBalanceV2Contract.getUnfreezeBalance() + "] is error"
);
}

Expand Down Expand Up @@ -209,8 +209,8 @@ public boolean checkExistFreezedBalance(AccountCapsule accountCapsule, Common.Re
}

public boolean checkUnfreezeBalance(AccountCapsule accountCapsule,
final UnfreezeBalanceV2Contract unfreezeBalanceV2Contract,
Common.ResourceCode freezeType) {
final UnfreezeBalanceV2Contract unfreezeBalanceV2Contract,
Common.ResourceCode freezeType) {
boolean checkOk = false;

long frozenAmount = 0L;
Expand All @@ -223,7 +223,7 @@ public boolean checkUnfreezeBalance(AccountCapsule accountCapsule,
}

if (unfreezeBalanceV2Contract.getUnfreezeBalance() > 0
&& unfreezeBalanceV2Contract.getUnfreezeBalance() <= frozenAmount) {
&& unfreezeBalanceV2Contract.getUnfreezeBalance() <= frozenAmount) {
checkOk = true;
}

Expand All @@ -241,10 +241,10 @@ public void updateAccountFrozenInfo(Common.ResourceCode freezeType, AccountCapsu
List<Protocol.Account.FreezeV2> freezeV2List = accountCapsule.getFrozenV2List();
for (int i = 0; i < freezeV2List.size(); i++) {
if (freezeV2List.get(i).getType().equals(freezeType)) {
Protocol.Account.FreezeV2 freezeV2 = Protocol.Account.FreezeV2.newBuilder()
.setAmount(freezeV2List.get(i).getAmount() - unfreezeBalance)
.setType(freezeV2List.get(i).getType())
.build();
Protocol.Account.FreezeV2 freezeV2 = Protocol.Account.FreezeV2.newBuilder()
.setAmount(freezeV2List.get(i).getAmount() - unfreezeBalance)
.setType(freezeV2List.get(i).getType())
.build();
accountCapsule.updateFrozenV2List(i, freezeV2);
break;
}
Expand All @@ -267,7 +267,7 @@ public long unfreezeExpire(AccountCapsule accountCapsule, long now) {
}

accountCapsule.setInstance(
accountCapsule.getInstance().toBuilder()
accountCapsule.getInstance().toBuilder()
.setBalance(accountCapsule.getBalance() + unfreezeBalance)
.clearUnfrozenV2()
.addAllUnfrozenV2(unFrozenV2List).build()
Expand All @@ -276,7 +276,7 @@ public long unfreezeExpire(AccountCapsule accountCapsule, long now) {
}

public void updateTotalResourceWeight(final UnfreezeBalanceV2Contract unfreezeBalanceV2Contract,
long unfreezeBalance) {
long unfreezeBalance) {
DynamicPropertiesStore dynamicStore = chainBaseManager.getDynamicPropertiesStore();
switch (unfreezeBalanceV2Contract.getResource()) {
case BANDWIDTH:
Expand All @@ -294,38 +294,86 @@ public void updateTotalResourceWeight(final UnfreezeBalanceV2Contract unfreezeBa
}
}

private void clearVotes(AccountCapsule accountCapsule,
private void updateVote(AccountCapsule accountCapsule,
final UnfreezeBalanceV2Contract unfreezeBalanceV2Contract,
byte[] ownerAddress) {
DynamicPropertiesStore dynamicStore = chainBaseManager.getDynamicPropertiesStore();
VotesStore votesStore = chainBaseManager.getVotesStore();

boolean needToClearVote = true;
if (dynamicStore.supportAllowNewResourceModel()
&& accountCapsule.oldTronPowerIsInvalid()) {
switch (unfreezeBalanceV2Contract.getResource()) {
case BANDWIDTH:
case ENERGY:
needToClearVote = false;
break;
default:
break;
if (accountCapsule.getVotesList().isEmpty()) {
return;
}
if (dynamicStore.supportAllowNewResourceModel()) {
if (accountCapsule.oldTronPowerIsInvalid()) {
switch (unfreezeBalanceV2Contract.getResource()) {
case BANDWIDTH:
case ENERGY:
// there is no need to change votes
return;
default:
break;
}
} else {
// clear all votes at once when new resource model start
VotesCapsule votesCapsule;
if (!votesStore.has(ownerAddress)) {
votesCapsule = new VotesCapsule(
unfreezeBalanceV2Contract.getOwnerAddress(),
accountCapsule.getVotesList()
);
} else {
votesCapsule = votesStore.get(ownerAddress);
}
accountCapsule.clearVotes();
votesCapsule.clearNewVotes();
votesStore.put(ownerAddress, votesCapsule);
return;
}
}

if (needToClearVote) {
VotesCapsule votesCapsule;
if (!votesStore.has(ownerAddress)) {
votesCapsule = new VotesCapsule(
unfreezeBalanceV2Contract.getOwnerAddress(),
accountCapsule.getVotesList()
);
} else {
votesCapsule = votesStore.get(ownerAddress);
long totalVote = 0;
for (Protocol.Vote vote : accountCapsule.getVotesList()) {
totalVote += vote.getVoteCount();
}
long ownedTronPower;
if (dynamicStore.supportAllowNewResourceModel()) {
ownedTronPower = accountCapsule.getAllTronPower();
} else {
ownedTronPower = accountCapsule.getTronPower();
}

// tron power is enough to total votes
if (ownedTronPower >= totalVote * TRX_PRECISION) {
return;
}
if (totalVote == 0) {
return;
}

VotesCapsule votesCapsule;
if (!votesStore.has(ownerAddress)) {
votesCapsule = new VotesCapsule(
unfreezeBalanceV2Contract.getOwnerAddress(),
accountCapsule.getVotesList()
);
} else {
votesCapsule = votesStore.get(ownerAddress);
}

// Update Owner Voting
votesCapsule.clearNewVotes();
for (Vote vote : accountCapsule.getVotesList()) {
long newVoteCount = (long)
((double) vote.getVoteCount() / totalVote * ownedTronPower / TRX_PRECISION);
if (newVoteCount > 0) {
votesCapsule.addNewVotes(vote.getVoteAddress(), newVoteCount);
}
accountCapsule.clearVotes();
votesCapsule.clearNewVotes();
votesStore.put(ownerAddress, votesCapsule);
}
votesStore.put(ownerAddress, votesCapsule);

accountCapsule.clearVotes();
for (Vote vote : votesCapsule.getNewVotes()) {
accountCapsule.addVotes(vote.getVoteAddress(), vote.getVoteCount());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
import com.google.protobuf.Any;
import com.google.protobuf.ByteString;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.junit.AfterClass;
import org.junit.Assert;
Expand Down Expand Up @@ -318,57 +316,60 @@ public void noFrozenBalance() {
}

@Test
public void testClearVotes() {
public void testVotes() {
byte[] ownerAddressBytes = ByteArray.fromHexString(OWNER_ADDRESS);
ByteString ownerAddress = ByteString.copyFrom(ownerAddressBytes);
long unfreezeBalance = frozenBalance;
long unfreezeBalance = frozenBalance / 2;
long now = System.currentTimeMillis();
dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderTimestamp(now);

dbManager.getDynamicPropertiesStore().saveAllowNewResourceModel(0);
AccountCapsule accountCapsule = dbManager.getAccountStore().get(ownerAddressBytes);
accountCapsule.addFrozenBalanceForBandwidthV2(1_000_000_000L);

accountCapsule.addVotes(ByteString.copyFrom(RECEIVER_ADDRESS.getBytes()), 500);
accountCapsule.addVotes(ByteString.copyFrom(OWNER_ACCOUNT_INVALID.getBytes()), 500);
dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule);

UnfreezeBalanceV2Actuator actuator = new UnfreezeBalanceV2Actuator();
actuator.setChainBaseManager(dbManager.getChainBaseManager())
.setAny(getContractForBandwidthV2(OWNER_ADDRESS, unfreezeBalance));
TransactionResultCapsule ret = new TransactionResultCapsule();

dbManager.getVotesStore().reset();
Assert.assertNull(dbManager.getVotesStore().get(ownerAddressBytes));
try {
actuator.validate();
actuator.execute(ret);
VotesCapsule votesCapsule = dbManager.getVotesStore().get(ownerAddressBytes);
Assert.assertNotNull(votesCapsule);
Assert.assertEquals(0, votesCapsule.getNewVotes().size());
} catch (ContractValidateException e) {
Assert.assertFalse(e instanceof ContractValidateException);
} catch (ContractExeException e) {
Assert.assertFalse(e instanceof ContractExeException);
for (Vote vote : votesCapsule.getOldVotes()) {
Assert.assertEquals(vote.getVoteCount(), 500);
}
for (Vote vote : votesCapsule.getNewVotes()) {
Assert.assertEquals(vote.getVoteCount(), 250);
}
accountCapsule = dbManager.getAccountStore().get(ownerAddressBytes);
for (Vote vote : accountCapsule.getVotesList()) {
Assert.assertEquals(vote.getVoteCount(), 250);
}
} catch (ContractValidateException | ContractExeException e) {
Assert.fail("cannot run here.");
}

// if had votes
List<Vote> oldVotes = new ArrayList<Vote>();
VotesCapsule votesCapsule = new VotesCapsule(
ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)), oldVotes);
votesCapsule.addNewVotes(
ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)), 100);
dbManager.getVotesStore().put(ByteArray.fromHexString(OWNER_ADDRESS), votesCapsule);
accountCapsule.addFrozenBalanceForBandwidthV2(1_000_000_000L);
dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule);
// clear for new resource model
dbManager.getDynamicPropertiesStore().saveAllowNewResourceModel(1);
actuator.setChainBaseManager(dbManager.getChainBaseManager())
.setAny(getContractForBandwidthV2(OWNER_ADDRESS, unfreezeBalance / 2));
try {
actuator.validate();
actuator.execute(ret);
votesCapsule = dbManager.getVotesStore().get(ownerAddressBytes);
VotesCapsule votesCapsule = dbManager.getVotesStore().get(ownerAddressBytes);
Assert.assertNotNull(votesCapsule);
for (Vote vote : votesCapsule.getOldVotes()) {
Assert.assertEquals(vote.getVoteCount(), 500);
}
Assert.assertEquals(0, votesCapsule.getNewVotes().size());
} catch (ContractValidateException e) {
Assert.assertFalse(e instanceof ContractValidateException);
} catch (ContractExeException e) {
Assert.assertFalse(e instanceof ContractExeException);
accountCapsule = dbManager.getAccountStore().get(ownerAddressBytes);
Assert.assertEquals(0, accountCapsule.getVotesList().size());
} catch (ContractValidateException | ContractExeException e) {
Assert.fail("cannot run here.");
}

}

@Test
Expand Down

0 comments on commit 79a190a

Please sign in to comment.