Skip to content

Commit

Permalink
feat(memo-fee): add a proposal for memo fee
Browse files Browse the repository at this point in the history
1. additional fees are charged when the transaction has memo information.
  • Loading branch information
zhang0125 committed Nov 1, 2022
1 parent e0a910e commit 58a6c1a
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 4 deletions.
14 changes: 13 additions & 1 deletion actuator/src/main/java/org/tron/core/utils/ProposalUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,17 @@ public static void validator(DynamicPropertiesStore dynamicPropertiesStore,
}
break;
}
case MEMO_FEE: {
if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_6)) {
throw new ContractValidateException(
"Bad chain parameter id [MEMO_FEE]");
}
if (value < 1 || value > 1_000_000_000) {
throw new ContractValidateException(
"This value[MEMO_FEE] is only allowed to be in the range 1-1000_000_000");
}
break;
}
default:
break;
}
Expand Down Expand Up @@ -639,7 +650,8 @@ public enum ProposalType { // current value, value range
ALLOW_TVM_LONDON(63), // 0, 1
ALLOW_HIGHER_LIMIT_FOR_MAX_CPU_TIME_OF_ONE_TX(65), // 0, 1
ALLOW_ASSET_OPTIMIZATION(66), // 0, 1
ALLOW_NEW_REWARD_ALGO(67); // 0, 1
ALLOW_NEW_REWARD_ALGO(67), // 0, 1
MEMO_FEE(68); // 0, [1, 1000_000_000]

private long code;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ public class ReceiptCapsule {
@Setter
private long multiSignFee;

@Getter
@Setter
private long memoFee;
/**
* Available energy of contract deployer before executing transaction
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ public static TransactionInfoCapsule buildTransactionInfoInstance(TransactionCap
}
builder.setId(ByteString.copyFrom(trxCap.getTransactionId().getBytes()));
ProgramResult programResult = trace.getRuntimeResult();
long fee =
programResult.getRet().getFee() + traceReceipt.getEnergyFee()
+ traceReceipt.getNetFee() + traceReceipt.getMultiSignFee();
long fee = programResult.getRet().getFee() + traceReceipt.getEnergyFee()
+ traceReceipt.getNetFee() + traceReceipt.getMultiSignFee()
+ traceReceipt.getMemoFee();

boolean supportTransactionFeePool = trace.getTransactionContext().getStoreFactory()
.getChainBaseManager().getDynamicPropertiesStore().supportTransactionFeePool();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ public class DynamicPropertiesStore extends TronStoreWithRevoking<BytesCapsule>
private static final byte[] ALLOW_HIGHER_LIMIT_FOR_MAX_CPU_TIME_OF_ONE_TX =
"ALLOW_HIGHER_LIMIT_FOR_MAX_CPU_TIME_OF_ONE_TX".getBytes();

private static final byte[] MEMO_FEE = "MEMO_FEE".getBytes();

@Autowired
private DynamicPropertiesStore(@Value("properties") String dbName) {
super(dbName);
Expand Down Expand Up @@ -857,6 +859,12 @@ private DynamicPropertiesStore(@Value("properties") String dbName) {
new BytesCapsule(ByteArray.fromLong(Long.MAX_VALUE)));
}
}

try {
this.getMemoFee();
} catch (IllegalArgumentException e) {
this.saveMemoFee(CommonParameter.getInstance().getMemoFee());
}
}

public String intArrayToString(int[] a) {
Expand Down Expand Up @@ -2528,6 +2536,17 @@ public long getAllowHigherLimitForMaxCpuTimeOfOneTx() {
() -> new IllegalArgumentException(msg));
}

public long getMemoFee() {
return Optional.ofNullable(getUnchecked(MEMO_FEE))
.map(BytesCapsule::getData)
.map(ByteArray::toLong)
.orElseThrow(() -> new IllegalArgumentException("not found MEMO_FEE"));
}

public void saveMemoFee(long value) {
this.put(MEMO_FEE, new BytesCapsule(ByteArray.fromLong(value)));
}

private static class DynamicResourceProperties {

private static final byte[] ONE_DAY_NET_LIMIT = "ONE_DAY_NET_LIMIT".getBytes();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,10 @@ public class CommonParameter {
@Setter
public long allowNewRewardAlgorithm;

@Getter
@Setter
public long memoFee = 0L;

private static double calcMaxTimeRatio() {
//return max(2.0, min(5.0, 5 * 4.0 / max(Runtime.getRuntime().availableProcessors(), 1)));
return 5.0;
Expand Down
1 change: 1 addition & 0 deletions common/src/main/java/org/tron/core/Constant.java
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ public class Constant {

public static final String ALLOW_ACCOUNT_ASSET_OPTIMIZATION = "committee.allowAccountAssetOptimization";
public static final String ALLOW_ASSET_OPTIMIZATION = "committee.allowAssetOptimization";
public static final String MEMO_FEE = "committee.memoFee";

public static final String LOCAL_HOST = "127.0.0.1";

Expand Down
5 changes: 5 additions & 0 deletions framework/src/main/java/org/tron/core/Wallet.java
Original file line number Diff line number Diff line change
Expand Up @@ -1103,6 +1103,11 @@ public Protocol.ChainParameters getChainParameters() {
.setValue(dbManager.getDynamicPropertiesStore().useNewRewardAlgorithm() ? 1 : 0)
.build());

builder.addChainParameter(Protocol.ChainParameters.ChainParameter.newBuilder()
.setKey("getMemoFee")
.setValue(dbManager.getDynamicPropertiesStore().getMemoFee())
.build());

return builder.build();
}

Expand Down
10 changes: 10 additions & 0 deletions framework/src/main/java/org/tron/core/config/args/Args.java
Original file line number Diff line number Diff line change
Expand Up @@ -1034,6 +1034,16 @@ public static void setParam(final String[] args, final String confFileName) {
PARAMETER.blockCacheTimeout = config.getLong(Constant.BLOCK_CACHE_TIMEOUT);
}

if (config.hasPath(Constant.MEMO_FEE)) {
PARAMETER.memoFee = config.getLong(Constant.MEMO_FEE);
if (PARAMETER.memoFee > 1_000_000_000) {
PARAMETER.memoFee = 1_000_000_000;
}
if (PARAMETER.memoFee < 0) {
PARAMETER.memoFee = 0;
}
}

logConfig();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,10 @@ public static boolean process(Manager manager, ProposalCapsule proposalCapsule)
manager.getDynamicPropertiesStore().saveNewRewardAlgorithmEffectiveCycle();
break;
}
case MEMO_FEE: {
manager.getDynamicPropertiesStore().saveMemoFee(entry.getValue());
break;
}
default:
find = false;
break;
Expand Down
37 changes: 37 additions & 0 deletions framework/src/main/java/org/tron/core/db/Manager.java
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,42 @@ public void consumeMultiSignFee(TransactionCapsule trx, TransactionTrace trace)
}
}

public void consumeMemoFee(TransactionCapsule trx, TransactionTrace trace)
throws AccountResourceInsufficientException {
if (trx.getInstance().getRawData().getData().isEmpty()) {
// no memo
return;
}

long fee = getDynamicPropertiesStore().getMemoFee();
if (fee == 0) {
return;
}

List<Contract> contracts = trx.getInstance().getRawData().getContractList();
for (Contract contract : contracts) {
byte[] address = TransactionCapsule.getOwner(contract);
AccountCapsule accountCapsule = getAccountStore().get(address);
try {
if (accountCapsule != null) {
adjustBalance(getAccountStore(), accountCapsule, -fee);

if (getDynamicPropertiesStore().supportBlackHoleOptimization()) {
getDynamicPropertiesStore().burnTrx(fee);
} else {
adjustBalance(getAccountStore(), this.getAccountStore().getBlackhole(), +fee);
}
}
} catch (BalanceInsufficientException e) {
throw new AccountResourceInsufficientException(
String.format("account %s insufficient balance[%d] to memo fee",
StringUtil.encode58Check(address), fee));
}
}

trace.getReceipt().setMemoFee(fee);
}

public void consumeBandwidth(TransactionCapsule trx, TransactionTrace trace)
throws ContractValidateException, AccountResourceInsufficientException,
TooBigTransactionResultException {
Expand Down Expand Up @@ -1338,6 +1374,7 @@ public TransactionInfo processTransaction(final TransactionCapsule trxCap, Block

consumeBandwidth(trxCap, trace);
consumeMultiSignFee(trxCap, trace);
consumeMemoFee(trxCap, trace);

trace.init(blockCap, eventPluginLoaded);
trace.checkIsConstant();
Expand Down

0 comments on commit 58a6c1a

Please sign in to comment.