Skip to content

Commit 93dfc33

Browse files
Merge pull request #6221 from lxcmyf/feature/consensus_optimize_tx
feat(validate): strengthen transaction result verification
2 parents 7a15f50 + af3a002 commit 93dfc33

File tree

4 files changed

+76
-6
lines changed

4 files changed

+76
-6
lines changed

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -878,4 +878,17 @@ public void checkExpiration(long nextSlotTime) throws TransactionExpirationExcep
878878
getExpiration(), nextSlotTime));
879879
}
880880
}
881+
882+
public boolean retCountIsGreatThanContractCount() {
883+
int contractCount = getContractCount();
884+
return getRetCount() > contractCount && contractCount > 0;
885+
}
886+
887+
public int getRetCount() {
888+
return this.getInstance().getRetCount();
889+
}
890+
891+
public int getContractCount() {
892+
return this.getInstance().getRawData().getContractCount();
893+
}
881894
}

chainbase/src/main/java/org/tron/core/db/BandwidthProcessor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public void consume(TransactionCapsule trx, TransactionTrace trace)
101101
long resultSizeWithMaxContractRet = trx.getResultSizeWithMaxContractRet();
102102
boolean optimizeTxs = !trx.isInBlock() || chainBaseManager
103103
.getDynamicPropertiesStore().allowConsensusLogicOptimization();
104-
if (optimizeTxs && resultSizeWithMaxContractRet >
104+
if (!trx.isInBlock() && resultSizeWithMaxContractRet >
105105
Constant.MAX_RESULT_SIZE_IN_TX * contracts.size()) {
106106
throw new TooBigTransactionResultException(String.format(
107107
"Too big transaction result, TxId %s, the result size is %d bytes, maxResultSize %d",

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1802,6 +1802,12 @@ private void processBlock(BlockCapsule block, List<TransactionCapsule> txs)
18021802
List<TransactionInfo> results = new ArrayList<>();
18031803
long num = block.getNum();
18041804
for (TransactionCapsule transactionCapsule : block.getTransactions()) {
1805+
if (chainBaseManager.getDynamicPropertiesStore().allowConsensusLogicOptimization()
1806+
&& transactionCapsule.retCountIsGreatThanContractCount()) {
1807+
throw new BadBlockException(String.format("The result count %d of this transaction %s is "
1808+
+ "greater than its contract count %d", transactionCapsule.getRetCount(),
1809+
transactionCapsule.getTransactionId(), transactionCapsule.getContractCount()));
1810+
}
18051811
transactionCapsule.setBlockNum(num);
18061812
if (block.generatedByMyself) {
18071813
transactionCapsule.setVerified(true);

framework/src/test/java/org/tron/core/db/ManagerTest.java

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@
77
import static org.tron.common.utils.Commons.adjustAssetBalanceV2;
88
import static org.tron.common.utils.Commons.adjustTotalShieldedPoolValue;
99
import static org.tron.common.utils.Commons.getExchangeStoreFinal;
10+
import static org.tron.common.utils.StringUtil.encode58Check;
1011
import static org.tron.core.exception.BadBlockException.TypeEnum.CALC_MERKLE_ROOT_FAILED;
12+
import static org.tron.protos.Protocol.Transaction.Result.contractResult.SUCCESS;
1113

14+
import com.beust.jcommander.internal.Lists;
1215
import com.google.common.collect.Maps;
1316
import com.google.common.collect.Sets;
1417
import com.google.protobuf.Any;
@@ -481,7 +484,7 @@ public void adjustAssetBalanceV2Test() {
481484
} catch (BalanceInsufficientException e) {
482485
Assert.assertTrue(e instanceof BalanceInsufficientException);
483486
Assert.assertEquals(
484-
"reduceAssetAmount failed! account: " + StringUtil.encode58Check(account.createDbKey()),
487+
"reduceAssetAmount failed! account: " + encode58Check(account.createDbKey()),
485488
e.getMessage());
486489
}
487490

@@ -744,7 +747,7 @@ public void fork()
744747
chainManager.addWitness(ByteString.copyFrom(address));
745748
chainManager.getWitnessStore().put(address, witnessCapsule);
746749

747-
Block block = getSignedBlock(witnessCapsule.getAddress(), 1533529947843L, privateKey);
750+
Block block = getSignedBlock(witnessCapsule.getAddress(), 1533529947000L, privateKey);
748751

749752
dbManager.pushBlock(new BlockCapsule(block));
750753

@@ -754,15 +757,15 @@ public void fork()
754757
long num = chainManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber();
755758
BlockCapsule blockCapsule0 =
756759
createTestBlockCapsule(
757-
1533529947843L + 3000,
760+
1533529947000L + 3000,
758761
num + 1,
759762
chainManager.getDynamicPropertiesStore().getLatestBlockHeaderHash()
760763
.getByteString(),
761764
addressToProvateKeys);
762765

763766
BlockCapsule blockCapsule1 =
764767
createTestBlockCapsule(
765-
1533529947843L + 3000,
768+
1533529947000L + 3000,
766769
num + 1,
767770
chainManager.getDynamicPropertiesStore().getLatestBlockHeaderHash()
768771
.getByteString(),
@@ -773,7 +776,7 @@ public void fork()
773776

774777
BlockCapsule blockCapsule2 =
775778
createTestBlockCapsule(
776-
1533529947843L + 6000,
779+
1533529947000L + 6000,
777780
num + 2, blockCapsule1.getBlockId().getByteString(), addressToProvateKeys);
778781

779782
dbManager.pushBlock(blockCapsule2);
@@ -800,6 +803,24 @@ public void fork()
800803
Assert.assertEquals(
801804
chainManager.getHead().getBlockId(),
802805
chainManager.getDynamicPropertiesStore().getLatestBlockHeaderHash());
806+
807+
dbManager.getDynamicPropertiesStore().saveConsensusLogicOptimization(1);
808+
BlockCapsule blockCapsule3 =
809+
createTestBlockCapsule2(1533529947000L + 9000,
810+
num + 3, blockCapsule2.getBlockId().getByteString(), addressToProvateKeys);
811+
812+
assertThrows(BadBlockException.class, () -> dbManager.pushBlock(blockCapsule3));
813+
}
814+
815+
private Transaction buildTransaction(com.google.protobuf.Message message,
816+
ContractType contractType) {
817+
Transaction.raw.Builder rawBuilder = Transaction.raw.newBuilder().addContract(
818+
Transaction.Contract.newBuilder().setType(contractType).setParameter(
819+
(message instanceof Any ? (Any) message : Any.pack(message))).build());
820+
Transaction.Builder transactionBuilder = Transaction.newBuilder().setRawData(rawBuilder)
821+
.addRet(Transaction.Result.newBuilder().setContractRet(SUCCESS).build())
822+
.addRet(Transaction.Result.newBuilder().setContractRet(SUCCESS).build());
823+
return transactionBuilder.build();
803824
}
804825

805826
@Test
@@ -1095,6 +1116,36 @@ private BlockCapsule createTestBlockCapsule(long time,
10951116
return blockCapsule;
10961117
}
10971118

1119+
private BlockCapsule createTestBlockCapsule2(long time, long number, ByteString hash,
1120+
Map<ByteString, String> addressToProvateKeys) {
1121+
TransferContract c1 = TransferContract.newBuilder()
1122+
.setOwnerAddress(ByteString.copyFrom("f1".getBytes()))
1123+
.setAmount(1).build();
1124+
ByteString witnessAddress = dposSlot.getScheduledWitness(dposSlot.getSlot(time));
1125+
Protocol.BlockHeader.raw.Builder blockHeaderRawBuild = Protocol.BlockHeader.raw.newBuilder();
1126+
Protocol.BlockHeader.raw blockHeaderRaw = blockHeaderRawBuild
1127+
.setTimestamp(time)
1128+
.setParentHash(hash)
1129+
.setWitnessAddress(witnessAddress)
1130+
.setNumber(number)
1131+
.build();
1132+
1133+
// block header
1134+
Protocol.BlockHeader.Builder blockHeaderBuild = Protocol.BlockHeader.newBuilder();
1135+
Protocol.BlockHeader blockHeader = blockHeaderBuild.setRawData(blockHeaderRaw).build();
1136+
1137+
// block
1138+
Block.Builder blockBuild = Block.newBuilder();
1139+
List<Transaction> transactions = Lists.newArrayList(buildTransaction(c1,
1140+
ContractType.TransferContract));
1141+
transactions.forEach(blockBuild::addTransactions);
1142+
BlockCapsule blockCapsule = new BlockCapsule(blockBuild.setBlockHeader(blockHeader).build());
1143+
blockCapsule.generatedByMyself = true;
1144+
blockCapsule.setMerkleRoot();
1145+
blockCapsule.sign(ByteArray.fromHexString(addressToProvateKeys.get(witnessAddress)));
1146+
return blockCapsule;
1147+
}
1148+
10981149
private BlockCapsule createTestBlockCapsuleError(long time,
10991150
long number, ByteString hash,
11001151
Map<ByteString, String> addressToProvateKeys) {

0 commit comments

Comments
 (0)