Skip to content

Commit 1e952f3

Browse files
authored
Merge pull request #4758 from tronprotocol/feature/memo_fee
feat(memo-fee): add a proposal for memo fee
2 parents e0a910e + 8a3877b commit 1e952f3

12 files changed

Lines changed: 165 additions & 4 deletions

File tree

actuator/src/main/java/org/tron/core/utils/ProposalUtil.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,17 @@ public static void validator(DynamicPropertiesStore dynamicPropertiesStore,
575575
}
576576
break;
577577
}
578+
case MEMO_FEE: {
579+
if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_6)) {
580+
throw new ContractValidateException(
581+
"Bad chain parameter id [MEMO_FEE]");
582+
}
583+
if (value < 0 || value > 1_000_000_000) {
584+
throw new ContractValidateException(
585+
"This value[MEMO_FEE] is only allowed to be in the range 0-1000_000_000");
586+
}
587+
break;
588+
}
578589
default:
579590
break;
580591
}
@@ -639,7 +650,8 @@ public enum ProposalType { // current value, value range
639650
ALLOW_TVM_LONDON(63), // 0, 1
640651
ALLOW_HIGHER_LIMIT_FOR_MAX_CPU_TIME_OF_ONE_TX(65), // 0, 1
641652
ALLOW_ASSET_OPTIMIZATION(66), // 0, 1
642-
ALLOW_NEW_REWARD_ALGO(67); // 0, 1
653+
ALLOW_NEW_REWARD_ALGO(67), // 0, 1
654+
MEMO_FEE(68); // 0, [1, 1000_000_000]
643655

644656
private long code;
645657

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ public class ReceiptCapsule {
2424
@Setter
2525
private long multiSignFee;
2626

27+
@Getter
28+
@Setter
29+
private long memoFee;
2730
/**
2831
* Available energy of contract deployer before executing transaction
2932
*/

chainbase/src/main/java/org/tron/core/capsule/utils/TransactionUtil.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,9 @@ public static TransactionInfoCapsule buildTransactionInfoInstance(TransactionCap
7272
}
7373
builder.setId(ByteString.copyFrom(trxCap.getTransactionId().getBytes()));
7474
ProgramResult programResult = trace.getRuntimeResult();
75-
long fee =
76-
programResult.getRet().getFee() + traceReceipt.getEnergyFee()
77-
+ traceReceipt.getNetFee() + traceReceipt.getMultiSignFee();
75+
long fee = programResult.getRet().getFee() + traceReceipt.getEnergyFee()
76+
+ traceReceipt.getNetFee() + traceReceipt.getMultiSignFee()
77+
+ traceReceipt.getMemoFee();
7878

7979
boolean supportTransactionFeePool = trace.getTransactionContext().getStoreFactory()
8080
.getChainBaseManager().getDynamicPropertiesStore().supportTransactionFeePool();

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,9 @@ public class DynamicPropertiesStore extends TronStoreWithRevoking<BytesCapsule>
187187
private static final byte[] ALLOW_HIGHER_LIMIT_FOR_MAX_CPU_TIME_OF_ONE_TX =
188188
"ALLOW_HIGHER_LIMIT_FOR_MAX_CPU_TIME_OF_ONE_TX".getBytes();
189189

190+
private static final byte[] MEMO_FEE = "MEMO_FEE".getBytes();
191+
private static final byte[] MEMO_FEE_HISTORY = "MEMO_FEE_HISTORY".getBytes();
192+
190193
@Autowired
191194
private DynamicPropertiesStore(@Value("properties") String dbName) {
192195
super(dbName);
@@ -857,6 +860,14 @@ private DynamicPropertiesStore(@Value("properties") String dbName) {
857860
new BytesCapsule(ByteArray.fromLong(Long.MAX_VALUE)));
858861
}
859862
}
863+
864+
try {
865+
this.getMemoFee();
866+
} catch (IllegalArgumentException e) {
867+
long memoFee = CommonParameter.getInstance().getMemoFee();
868+
this.saveMemoFee(memoFee);
869+
this.saveMemoFeeHistory("0:" + memoFee);
870+
}
860871
}
861872

862873
public String intArrayToString(int[] a) {
@@ -2528,6 +2539,28 @@ public long getAllowHigherLimitForMaxCpuTimeOfOneTx() {
25282539
() -> new IllegalArgumentException(msg));
25292540
}
25302541

2542+
public long getMemoFee() {
2543+
return Optional.ofNullable(getUnchecked(MEMO_FEE))
2544+
.map(BytesCapsule::getData)
2545+
.map(ByteArray::toLong)
2546+
.orElseThrow(() -> new IllegalArgumentException("not found MEMO_FEE"));
2547+
}
2548+
2549+
public void saveMemoFee(long value) {
2550+
this.put(MEMO_FEE, new BytesCapsule(ByteArray.fromLong(value)));
2551+
}
2552+
2553+
public String getMemoFeeHistory() {
2554+
return Optional.ofNullable(getUnchecked(MEMO_FEE_HISTORY))
2555+
.map(BytesCapsule::getData)
2556+
.map(ByteArray::toStr)
2557+
.orElseThrow(() -> new IllegalArgumentException("not found MEMO_FEE_HISTORY"));
2558+
}
2559+
2560+
public void saveMemoFeeHistory(String value) {
2561+
this.put(MEMO_FEE_HISTORY, new BytesCapsule(ByteArray.fromString(value)));
2562+
}
2563+
25312564
private static class DynamicResourceProperties {
25322565

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

common/src/main/java/org/tron/common/parameter/CommonParameter.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,10 @@ public class CommonParameter {
561561
@Setter
562562
public long allowNewRewardAlgorithm;
563563

564+
@Getter
565+
@Setter
566+
public long memoFee = 0L;
567+
564568
private static double calcMaxTimeRatio() {
565569
//return max(2.0, min(5.0, 5 * 4.0 / max(Runtime.getRuntime().availableProcessors(), 1)));
566570
return 5.0;

common/src/main/java/org/tron/core/Constant.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ public class Constant {
307307

308308
public static final String ALLOW_ACCOUNT_ASSET_OPTIMIZATION = "committee.allowAccountAssetOptimization";
309309
public static final String ALLOW_ASSET_OPTIMIZATION = "committee.allowAssetOptimization";
310+
public static final String MEMO_FEE = "committee.memoFee";
310311

311312
public static final String LOCAL_HOST = "127.0.0.1";
312313

framework/src/main/java/org/tron/core/Wallet.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,6 +1103,11 @@ public Protocol.ChainParameters getChainParameters() {
11031103
.setValue(dbManager.getDynamicPropertiesStore().useNewRewardAlgorithm() ? 1 : 0)
11041104
.build());
11051105

1106+
builder.addChainParameter(Protocol.ChainParameters.ChainParameter.newBuilder()
1107+
.setKey("getMemoFee")
1108+
.setValue(dbManager.getDynamicPropertiesStore().getMemoFee())
1109+
.build());
1110+
11061111
return builder.build();
11071112
}
11081113

@@ -4080,5 +4085,13 @@ public Block getBlock(GrpcAPI.BlockReq request) {
40804085
return block.toBuilder().clearTransactions().build();
40814086
}
40824087

4088+
public String getMemoFeePrices() {
4089+
try {
4090+
return chainBaseManager.getDynamicPropertiesStore().getMemoFeeHistory();
4091+
} catch (Exception e) {
4092+
logger.error("getMemoFeePrices failed, error is {}", e.getMessage());
4093+
}
4094+
return null;
4095+
}
40834096
}
40844097

framework/src/main/java/org/tron/core/config/args/Args.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,6 +1034,16 @@ public static void setParam(final String[] args, final String confFileName) {
10341034
PARAMETER.blockCacheTimeout = config.getLong(Constant.BLOCK_CACHE_TIMEOUT);
10351035
}
10361036

1037+
if (config.hasPath(Constant.MEMO_FEE)) {
1038+
PARAMETER.memoFee = config.getLong(Constant.MEMO_FEE);
1039+
if (PARAMETER.memoFee > 1_000_000_000) {
1040+
PARAMETER.memoFee = 1_000_000_000;
1041+
}
1042+
if (PARAMETER.memoFee < 0) {
1043+
PARAMETER.memoFee = 0;
1044+
}
1045+
}
1046+
10371047
logConfig();
10381048
}
10391049

framework/src/main/java/org/tron/core/consensus/ProposalService.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,14 @@ public static boolean process(Manager manager, ProposalCapsule proposalCapsule)
288288
manager.getDynamicPropertiesStore().saveNewRewardAlgorithmEffectiveCycle();
289289
break;
290290
}
291+
case MEMO_FEE: {
292+
manager.getDynamicPropertiesStore().saveMemoFee(entry.getValue());
293+
// update memo fee history
294+
manager.getDynamicPropertiesStore().saveMemoFeeHistory(
295+
manager.getDynamicPropertiesStore().getMemoFeeHistory()
296+
+ "," + proposalCapsule.getExpirationTime() + ":" + entry.getValue());
297+
break;
298+
}
291299
default:
292300
find = false;
293301
break;

framework/src/main/java/org/tron/core/db/Manager.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,42 @@ public void consumeMultiSignFee(TransactionCapsule trx, TransactionTrace trace)
855855
}
856856
}
857857

858+
public void consumeMemoFee(TransactionCapsule trx, TransactionTrace trace)
859+
throws AccountResourceInsufficientException {
860+
if (trx.getInstance().getRawData().getData().isEmpty()) {
861+
// no memo
862+
return;
863+
}
864+
865+
long fee = getDynamicPropertiesStore().getMemoFee();
866+
if (fee == 0) {
867+
return;
868+
}
869+
870+
List<Contract> contracts = trx.getInstance().getRawData().getContractList();
871+
for (Contract contract : contracts) {
872+
byte[] address = TransactionCapsule.getOwner(contract);
873+
AccountCapsule accountCapsule = getAccountStore().get(address);
874+
try {
875+
if (accountCapsule != null) {
876+
adjustBalance(getAccountStore(), accountCapsule, -fee);
877+
878+
if (getDynamicPropertiesStore().supportBlackHoleOptimization()) {
879+
getDynamicPropertiesStore().burnTrx(fee);
880+
} else {
881+
adjustBalance(getAccountStore(), this.getAccountStore().getBlackhole(), +fee);
882+
}
883+
}
884+
} catch (BalanceInsufficientException e) {
885+
throw new AccountResourceInsufficientException(
886+
String.format("account %s insufficient balance[%d] to memo fee",
887+
StringUtil.encode58Check(address), fee));
888+
}
889+
}
890+
891+
trace.getReceipt().setMemoFee(fee);
892+
}
893+
858894
public void consumeBandwidth(TransactionCapsule trx, TransactionTrace trace)
859895
throws ContractValidateException, AccountResourceInsufficientException,
860896
TooBigTransactionResultException {
@@ -1338,6 +1374,7 @@ public TransactionInfo processTransaction(final TransactionCapsule trxCap, Block
13381374

13391375
consumeBandwidth(trxCap, trace);
13401376
consumeMultiSignFee(trxCap, trace);
1377+
consumeMemoFee(trxCap, trace);
13411378

13421379
trace.init(blockCap, eventPluginLoaded);
13431380
trace.checkIsConstant();

0 commit comments

Comments
 (0)