use of org.ethereum.core.TransactionReceipt in project rskj by rsksmart.
the class BlockHashesHelperTest method calculateReceiptsTrieRootForOK.
@Test
public void calculateReceiptsTrieRootForOK() {
World world = new World();
// Creation of transactions
Account acc1 = new AccountBuilder(world).name("acc1").balance(Coin.valueOf(2000000)).build();
Account acc2 = new AccountBuilder().name("acc2").build();
Transaction tx1 = new TransactionBuilder().sender(acc1).receiver(acc2).value(BigInteger.valueOf(1000000)).build();
Account acc3 = new AccountBuilder(world).name("acc3").balance(Coin.valueOf(2000000)).build();
Account acc4 = new AccountBuilder().name("acc4").build();
Transaction tx2 = new TransactionBuilder().sender(acc3).receiver(acc4).value(BigInteger.valueOf(500000)).build();
Account acc5 = new AccountBuilder(world).name("acc5").balance(Coin.valueOf(2000000)).build();
Account acc6 = new AccountBuilder().name("acc6").build();
Transaction tx3 = new TransactionBuilder().sender(acc5).receiver(acc6).value(BigInteger.valueOf(800000)).build();
List<Transaction> txs = new ArrayList<>();
txs.add(tx1);
txs.add(tx2);
txs.add(tx3);
Block block = mock(Block.class);
when(block.getTransactionsList()).thenReturn(txs);
when(block.getHash()).thenReturn(new Keccak256(Hex.decode("0246c165ac839255aab76c1bc3df7842673ee3673e20dd908bba60862cf41326")));
ReceiptStore receiptStore = mock(ReceiptStore.class);
byte[] rskBlockHash = new byte[] { 0x2 };
when(receiptStore.get(tx1.getHash().getBytes(), block.getHash().getBytes())).thenReturn(Optional.of(new TransactionInfo(new TransactionReceipt(), rskBlockHash, 0)));
when(receiptStore.get(tx2.getHash().getBytes(), block.getHash().getBytes())).thenReturn(Optional.of(new TransactionInfo(new TransactionReceipt(), rskBlockHash, 0)));
when(receiptStore.get(tx3.getHash().getBytes(), block.getHash().getBytes())).thenReturn(Optional.of(new TransactionInfo(new TransactionReceipt(), rskBlockHash, 0)));
List<Trie> trie = BlockHashesHelper.calculateReceiptsTrieRootFor(block, receiptStore, tx1.getHash());
assertNotNull(trie);
assertEquals(trie.size(), 2);
}
use of org.ethereum.core.TransactionReceipt in project rskj by rsksmart.
the class EthModuleGasEstimationDSLTest method estimateGas_callWithValuePlusSStoreRefund.
/**
* A contract call containing one storage refund + one call with value
*/
@Test
public void estimateGas_callWithValuePlusSStoreRefund() throws FileNotFoundException, DslProcessorException {
World world = World.processedWorld("dsl/eth_module/estimateGas/callWithValuePlusSstoreRefund.txt");
TransactionReceipt contractDeployReceipt = world.getTransactionReceiptByName("tx01");
String contractAddress = "0x" + contractDeployReceipt.getTransaction().getContractAddress().toHexString();
byte[] status = contractDeployReceipt.getStatus();
assertNotNull(status);
assertEquals(1, status.length);
assertEquals(0x01, status[0]);
EthModuleTestUtils.EthModuleGasEstimation eth = EthModuleTestUtils.buildBasicEthModuleForGasEstimation(world);
Block block = world.getBlockChain().getBlockByNumber(1);
// call clearStorageAndSendValue, it should estimate correctly the stipend cost and the gas refund
final CallArguments args = new CallArguments();
args.setTo(contractAddress);
args.setValue(TypeConverter.toQuantityJsonHex(1));
args.setNonce(TypeConverter.toQuantityJsonHex(1));
args.setGas(TypeConverter.toQuantityJsonHex(BLOCK_GAS_LIMIT));
// clearStorageAndSendValue()
args.setData("0x5b3f8140");
ProgramResult callConstant = eth.callConstant(args, block);
long callConstantGasUsed = callConstant.getGasUsed();
long estimatedGas = estimateGas(eth, args);
assertTrue(estimatedGas > callConstantGasUsed);
assertEquals(callConstant.getMaxGasUsed(), estimatedGas);
// it just moved STIPEND_CALL (2300) to child
assertFalse(callConstant.getMovedRemainingGasToChild());
assertTrue(eth.getEstimationResult().getDeductedRefund() > 0);
args.setGas(TypeConverter.toQuantityJsonHex(callConstantGasUsed));
assertFalse(runWithArgumentsAndBlock(eth, args, block));
args.setGas(TypeConverter.toQuantityJsonHex(estimatedGas));
assertTrue(runWithArgumentsAndBlock(eth, args, block));
args.setGas(TypeConverter.toQuantityJsonHex(estimatedGas - 1));
assertFalse(runWithArgumentsAndBlock(eth, args, block));
}
use of org.ethereum.core.TransactionReceipt in project rskj by rsksmart.
the class EthModuleGasEstimationDSLTest method estimateGas_gasCap.
/**
* Test if a user can estimate a transaction that exceeds the block limit
*/
@Test
public void estimateGas_gasCap() throws FileNotFoundException, DslProcessorException {
World world = World.processedWorld("dsl/eth_module/estimateGas/gasCap.txt");
TransactionReceipt deployTransactionReceipt = world.getTransactionReceiptByName("tx01");
String sender = "0x" + deployTransactionReceipt.getTransaction().getSender().toHexString();
String contractAddress = "0x" + deployTransactionReceipt.getTransaction().getContractAddress().toHexString();
byte[] status = deployTransactionReceipt.getStatus();
assertNotNull(status);
assertEquals(1, status.length);
assertEquals(0x01, status[0]);
EthModuleTestUtils.EthModuleGasEstimation eth = EthModuleTestUtils.buildBasicEthModuleForGasEstimation(world);
long gasEstimationCap = new TestSystemProperties().getGasEstimationCap();
CallArguments callArguments = new CallArguments();
// the creator
callArguments.setFrom(sender);
// deployed contract
callArguments.setTo(contractAddress);
// exceeding the gas cap
callArguments.setGas(TypeConverter.toQuantityJsonHex(gasEstimationCap + 1_000_000_000));
// call outOfGas()
callArguments.setData("0x31fe52e8");
String estimatedGas = eth.estimateGas(callArguments);
assertEquals(gasEstimationCap, Long.decode(estimatedGas).longValue());
}
use of org.ethereum.core.TransactionReceipt in project rskj by rsksmart.
the class EthModuleGasEstimationDSLTest method estimateGas_nestedCallsWithValueFixedGasRetainAndStorageRefund.
/**
* Send 1 rBTC accross three contracts, then the last contract frees a storage cell and does a CALL with value
* NOTE: this test uses a fixed amount of gas for each internal call
*/
@Test
public void estimateGas_nestedCallsWithValueFixedGasRetainAndStorageRefund() throws FileNotFoundException, DslProcessorException {
World world = World.processedWorld("dsl/eth_module/estimateGas/nestedCallsWithValueStorageRefundAndFixedGas.txt");
TransactionReceipt contractDeployA = world.getTransactionReceiptByName("tx01");
String contractAddressA = "0x" + contractDeployA.getTransaction().getContractAddress().toHexString();
byte[] status = contractDeployA.getStatus();
assertNotNull(status);
assertEquals(1, status.length);
assertEquals(0x01, status[0]);
assertEquals("0x6252703f5ba322ec64d3ac45e56241b7d9e481ad", contractAddressA);
TransactionReceipt contractDeployB = world.getTransactionReceiptByName("tx02");
String contractAddressB = "0x" + contractDeployB.getTransaction().getContractAddress().toHexString();
byte[] status2 = contractDeployB.getStatus();
assertNotNull(status2);
assertEquals(1, status2.length);
assertEquals(0x01, status2[0]);
assertEquals("0x56aa252dd82173789984fa164ee26ce2da9336ff", contractAddressB);
TransactionReceipt contractDeployC = world.getTransactionReceiptByName("tx03");
String contractAddressC = "0x" + contractDeployC.getTransaction().getContractAddress().toHexString();
byte[] status3 = contractDeployC.getStatus();
assertNotNull(status3);
assertEquals(1, status3.length);
assertEquals(0x01, status3[0]);
assertEquals("0x27444fbce96cb2d27b94e116d1506d7739c05862", contractAddressC);
EthModuleTestUtils.EthModuleGasEstimation eth = EthModuleTestUtils.buildBasicEthModuleForGasEstimation(world);
Block block = world.getBlockChain().getBestBlock();
// call callAddressWithValue, it should start the nested calls
final CallArguments args = new CallArguments();
args.setTo(contractAddressA);
args.setValue(TypeConverter.toQuantityJsonHex(1));
args.setNonce(TypeConverter.toQuantityJsonHex(6));
args.setGas(TypeConverter.toQuantityJsonHex(BLOCK_GAS_LIMIT));
// callAddressWithValue()
args.setData("0xfb60f709");
ProgramResult callConstant = eth.callConstant(args, block);
List<InternalTransaction> internalTransactions = callConstant.getInternalTransactions();
assertTrue(internalTransactions.stream().allMatch(i -> i.getValue().equals(Coin.valueOf(1))));
assertEquals(3, internalTransactions.size());
assertEquals(3, callConstant.getLogInfoList().size());
assertEvents(callConstant, "NestedCallWV", 2);
assertEvents(callConstant, "LastCall", 1);
long callConstantGasUsed = callConstant.getGasUsed();
long estimatedGas = estimateGas(eth, args);
assertTrue(eth.getEstimationResult().getDeductedRefund() > 0);
assertTrue(callConstant.getDeductedRefund() > 0);
assertEquals(callConstant.getGasUsedBeforeRefunds() / 2, callConstant.getDeductedRefund());
assertEquals(callConstantGasUsed + callConstant.getDeductedRefund(), estimatedGas);
assertTrue(callConstant.getMovedRemainingGasToChild());
args.setGas(TypeConverter.toQuantityJsonHex(callConstantGasUsed));
assertFalse(runWithArgumentsAndBlock(eth, args, block));
args.setGas(TypeConverter.toQuantityJsonHex(estimatedGas));
assertTrue(runWithArgumentsAndBlock(eth, args, block));
args.setGas(TypeConverter.toQuantityJsonHex(estimatedGas - 1));
assertFalse(runWithArgumentsAndBlock(eth, args, block));
}
use of org.ethereum.core.TransactionReceipt in project rskj by rsksmart.
the class EthModuleGasEstimationDSLTest method testEstimateGas_storageRefunds.
/**
* A contract with already initialized storage cells, the estimation should take into account the storage refunds
*/
@Test
public void testEstimateGas_storageRefunds() throws FileNotFoundException, DslProcessorException {
World world = World.processedWorld("dsl/eth_module/estimateGas/updateStorage.txt");
TransactionReceipt deployTransactionReceipt = world.getTransactionReceiptByName("tx01");
String contractAddress = "0x" + deployTransactionReceipt.getTransaction().getContractAddress().toHexString();
byte[] status = deployTransactionReceipt.getStatus();
assertNotNull(status);
assertEquals(1, status.length);
assertEquals(0x01, status[0]);
TransactionReceipt initStorageTransactionReceipt = world.getTransactionReceiptByName("tx02");
byte[] status2 = initStorageTransactionReceipt.getStatus();
long initStorageGasUsed = new BigInteger(1, initStorageTransactionReceipt.getGasUsed()).longValue();
assertNotNull(status2);
assertEquals(1, status2.length);
assertEquals(0x01, status2[0]);
EthModuleTestUtils.EthModuleGasEstimation eth = EthModuleTestUtils.buildBasicEthModuleForGasEstimation(world);
Block block = world.getBlockChain().getBestBlock();
// from non-zero to zero - setValue(1, 0) - it should have a refund
final CallArguments args = new CallArguments();
// "6252703f5ba322ec64d3ac45e56241b7d9e481ad";
args.setTo(contractAddress);
args.setValue(TypeConverter.toQuantityJsonHex(0));
args.setNonce(TypeConverter.toQuantityJsonHex(1));
args.setGas(TypeConverter.toQuantityJsonHex(BLOCK_GAS_LIMIT));
args.setData("0x7b8d56e3" + "0000000000000000000000000000000000000000000000000000000000000001" + // setValue(1,0)
"0000000000000000000000000000000000000000000000000000000000000000");
ProgramResult callConstantResult = eth.callConstant(args, block);
long clearStorageGasUsed = callConstantResult.getGasUsed();
long clearStoreageEstimatedGas = estimateGas(eth, args);
assertTrue(eth.getEstimationResult().getDeductedRefund() > 0);
assertTrue(0 < clearStorageGasUsed && clearStorageGasUsed < initStorageGasUsed);
assertTrue(clearStoreageEstimatedGas < initStorageGasUsed);
assertTrue(clearStoreageEstimatedGas > clearStorageGasUsed);
assertEquals(clearStoreageEstimatedGas, clearStorageGasUsed + callConstantResult.getDeductedRefund());
// Call same transaction with estimated gas
args.setGas(TypeConverter.toQuantityJsonHex(clearStoreageEstimatedGas));
assertTrue(runWithArgumentsAndBlock(eth, args, block));
// Call same transaction with estimated gas minus 1
args.setGas(TypeConverter.toQuantityJsonHex(clearStoreageEstimatedGas - 1));
assertFalse(runWithArgumentsAndBlock(eth, args, block));
// estimate gas for updating a storage cell from non-zero to non-zero
args.setGas(TypeConverter.toQuantityJsonHex(BLOCK_GAS_LIMIT));
args.setData("0x7b8d56e3" + "0000000000000000000000000000000000000000000000000000000000000001" + // setValue(1,1)
"0000000000000000000000000000000000000000000000000000000000000001");
long updateStorageGasUsed = eth.callConstant(args, block).getGasUsed();
long updateStoreageEstimatedGas = estimateGas(eth, args);
assertEquals(0, eth.getEstimationResult().getDeductedRefund());
// The estimated gas should be less than the gas used gas for initializing a storage cell
assertTrue(updateStorageGasUsed < initStorageGasUsed);
assertTrue(updateStoreageEstimatedGas < initStorageGasUsed);
assertEquals(updateStoreageEstimatedGas, updateStorageGasUsed);
// Call same transaction with estimated gas
args.setGas("0x" + Long.toString(updateStoreageEstimatedGas, 16));
assertTrue(runWithArgumentsAndBlock(eth, args, block));
// Call same transaction with estimated gas minus 1
args.setGas("0x" + Long.toString(updateStoreageEstimatedGas - 1, 16));
assertFalse(runWithArgumentsAndBlock(eth, args, block));
// Check against another already initialized (2,42) storage cell
TransactionReceipt anotherInitStorageTransactionReceipt = world.getTransactionReceiptByName("tx02");
byte[] status3 = anotherInitStorageTransactionReceipt.getStatus();
long anotherInitStorageGasUsed = new BigInteger(1, anotherInitStorageTransactionReceipt.getGasUsed()).longValue();
assertNotNull(status3);
assertEquals(1, status3.length);
assertEquals(0x01, status3[0]);
// Change this storage cell to zero and compare
args.setData("0x7b8d56e3" + "0000000000000000000000000000000000000000000000000000000000000002" + "0000000000000000000000000000000000000000000000000000000000000000");
args.setGas(TypeConverter.toQuantityJsonHex(BLOCK_GAS_LIMIT));
ProgramResult anotherCallConstantResult = eth.callConstant(args, block);
long anotherClearStorageGasUsed = anotherCallConstantResult.getGasUsed();
long anotherClearStorageEstimatedGas = estimateGas(eth, args);
assertTrue(eth.getEstimationResult().getDeductedRefund() > 0);
assertEquals(initStorageGasUsed, anotherInitStorageGasUsed);
assertEquals(clearStoreageEstimatedGas, anotherClearStorageEstimatedGas);
assertEquals(clearStorageGasUsed, anotherClearStorageGasUsed);
}
Aggregations