Skip to content

Commit b2fff19

Browse files
nagarevfmacleal
authored andcommitted
Adding DSL test
1 parent 8eec74b commit b2fff19

File tree

2 files changed

+167
-3
lines changed

2 files changed

+167
-3
lines changed

rskj-core/src/test/java/co/rsk/rpc/modules/eth/EthModuleDSLTest.java

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import co.rsk.test.dsl.WorldDslProcessor;
2525
import co.rsk.util.HexUtils;
2626
import org.ethereum.core.Account;
27+
import org.ethereum.core.Block;
2728
import org.ethereum.core.Transaction;
2829
import org.ethereum.core.TransactionReceipt;
2930
import org.ethereum.rpc.CallArguments;
@@ -91,7 +92,7 @@ void testCall_getRevertReason() throws FileNotFoundException, DslProcessorExcept
9192
}
9293

9394
@Test
94-
void testCall_StateOverride_stateIsOverride() throws DslProcessorException, FileNotFoundException {
95+
void testCall_StateOverride_stateIsOverridden() throws DslProcessorException, FileNotFoundException {
9596
// When
9697
World world = new World();
9798
// given a deployed contract with stored state = 10
@@ -135,7 +136,7 @@ void testCall_StateOverride_stateIsOverride() throws DslProcessorException, File
135136
* }
136137
*/
137138
@Test
138-
void testCall_StateOverride_codeOverride() throws DslProcessorException, FileNotFoundException {
139+
void testCall_StateOverride_codeIsOverridden() throws DslProcessorException, FileNotFoundException {
139140
// Given
140141
// This is the runtime bytecode of the contract above to override the original contract
141142
String runtimeByteCode = "0x6103e760005260206000f3";
@@ -169,7 +170,7 @@ void testCall_StateOverride_codeOverride() throws DslProcessorException, FileNot
169170
}
170171

171172
@Test
172-
void testCall_StateOverride_balanceOverride()throws DslProcessorException, FileNotFoundException {
173+
void testCall_StateOverride_balanceIsOverridden()throws DslProcessorException, FileNotFoundException {
173174
// Given
174175
long defaultBalance = 30000L;
175176
World world = new World();
@@ -203,6 +204,69 @@ void testCall_StateOverride_balanceOverride()throws DslProcessorException, FileN
203204
assertEquals(defaultBalance, HexUtils.jsonHexToInt(result2));
204205
}
205206

207+
@Test
208+
void testCall_StateOverride_precompiledContractIsMoved() throws DslProcessorException, FileNotFoundException {
209+
210+
// Given
211+
212+
String falseInHex = "0x0000000000000000000000000000000000000000000000000000000000000000";
213+
String trueInHex = "0x0000000000000000000000000000000000000000000000000000000000000001";
214+
215+
// Test Setup
216+
217+
DslParser parser = DslParser.fromResource("dsl/eth_module/test_state_override_move_precompiled.txt");
218+
World world = new World();
219+
WorldDslProcessor processor = new WorldDslProcessor(world);
220+
processor.processCommands(parser);
221+
222+
Account acc = world.getAccountByName("acc1");
223+
RskAddress identityPrecompiledAddress = new RskAddress("0x0000000000000000000000000000000000000004");
224+
RskAddress movePrecompiledTo = new RskAddress("0x0000000000000000000000000000000000000001");
225+
226+
// Test Steps
227+
228+
// 0. Check that DatacopyCaller contract was deployed correctly
229+
Block block01 = world.getBlockByName("b01");
230+
Assertions.assertNotNull(block01);
231+
Assertions.assertEquals(1, block01.getTransactionsList().size());
232+
233+
String contractAddress = world.getTransactionByName("tx01").getContractAddress().toHexString();
234+
235+
// 1. Check that checkOriginalDatacopyWorksAsExpected (0xb7deb48b) is executed correctly
236+
237+
EthModule eth = EthModuleTestUtils.buildBasicEthModule(world);
238+
239+
CallArguments args = new CallArguments();
240+
args.setFrom(acc.getAddress().toHexString());
241+
args.setTo("0x" + contractAddress);
242+
args.setData("0xb7deb48b"); // Call checkOriginalDatacopyWorksAsExpected() function
243+
BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam("latest");
244+
CallArgumentsParam callArgumentsParam = TransactionFactoryHelper.toCallArgumentsParam(args);
245+
246+
String result = eth.call(callArgumentsParam, blockIdentifierParam);
247+
assertEquals(trueInHex, result);
248+
249+
// 2. Check that checkOverriddenDatacopyWorksAsExpected (0x1cf61a8b) returns "false" before overriding
250+
251+
CallArguments args2 = new CallArguments();
252+
args2.setFrom(acc.getAddress().toHexString());
253+
args2.setTo("0x" + contractAddress);
254+
args2.setData("0x1cf61a8b"); // Call checkOverriddenDatacopyWorksAsExpected() function
255+
CallArgumentsParam callArgumentsParam2 = TransactionFactoryHelper.toCallArgumentsParam(args2);
256+
257+
String result2 = eth.call(callArgumentsParam2, blockIdentifierParam);
258+
assertEquals(falseInHex, result2);
259+
260+
// 3. Check that checkOverriddenDatacopyWorksAsExpected (0x1cf61a8b) returns "true" after overriding
261+
262+
AccountOverride accountOverride = new AccountOverride(identityPrecompiledAddress);
263+
accountOverride.setMovePrecompileToAddress(movePrecompiledTo);
264+
265+
String result3 = eth.call(callArgumentsParam2, blockIdentifierParam, List.of(accountOverride));
266+
assertEquals(trueInHex, result3);
267+
268+
}
269+
206270
private String deployContractAndGetAddressFromDsl(String dslContractPath, World world) throws DslProcessorException, FileNotFoundException{
207271
DslParser parser = DslParser.fromResource(dslContractPath);
208272
WorldDslProcessor processor = new WorldDslProcessor(world);
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
comment
2+
3+
Simple Datacopy caller contract
4+
5+
checkOriginalDatacopyWorksAsExpected calls datacopy (The Identity Precompiled Contract) on its original address
6+
- Returns true if data copy was executed correctly
7+
- Returns false otherwise (THIS SHOULD NEVER HAPPEN)
8+
9+
checkOverriddenDatacopyWorksAsExpected calls datacopy on the address 0x01 (where ecrecover is originally located)
10+
if movePrecompiledTo was excecuted previously for the identity contract on 0x01
11+
- Return true if data copy was excecuted correctly
12+
- Return false otherwise (THIS SHOULD NEVER HAPPEN EITHER, as movePrecompiledTo should work correctly)
13+
14+
// SPDX-License-Identifier: UNLICENSED
15+
pragma solidity ^0.8.0;
16+
17+
contract DatacopyCaller {
18+
constructor(){}
19+
20+
// Check datacopy (Identity precompiled contract) in its original address (0x04).
21+
function checkOriginalDatacopyWorksAsExpected() external returns (bool ok) {
22+
bytes memory data = "input";
23+
bytes memory result = new bytes(data.length); // Allocate memory for the result
24+
25+
assembly {
26+
// Get the length of the input data
27+
let len := mload(data)
28+
29+
// Call the precompiled contract at address 0x04
30+
// Arguments:
31+
// 1. gas: gas available for the call
32+
// 2. 0x04: address of the Data Copy precompile
33+
// 3. 0: value (ether) to send (none for Data Copy)
34+
// 4. add(data, 0x20): memory address of the input data (offset by 0x20 for length field)
35+
// 5. len: length of the input data
36+
// 6. add(result, 0x20): memory address to store the output (offset by 0x20 for length field)
37+
// 7. len: expected length of the output data
38+
if iszero(call(gas(), 0x04, 0, add(data, 0x20), len, add(result, 0x20), len)) {
39+
// Revert if the call fails
40+
invalid()
41+
}
42+
}
43+
44+
// Using keccak256 to be able to compare "bytes memory" variables
45+
return keccak256(result) == keccak256(data);
46+
}
47+
48+
// Check datacopy (Identity precompiled contract) in the overridden address (0x01).
49+
// This function returns true only after the Identity contract was copied to 0x01
50+
// Will return false otherwise.
51+
function checkOverriddenDatacopyWorksAsExpected() external returns (bool ok) {
52+
bytes memory data = "input";
53+
bytes memory result = new bytes(data.length); // Allocate memory for the result
54+
55+
assembly {
56+
// Get the length of the input data
57+
let len := mload(data)
58+
59+
// Call the precompiled contract at address 0x04
60+
// Arguments:
61+
// 1. gas: gas available for the call
62+
// 2. 0x01: address of the Data Copy precompile (overridden)
63+
// 3. 0: value (ether) to send (none for Data Copy)
64+
// 4. add(data, 0x20): memory address of the input data (offset by 0x20 for length field)
65+
// 5. len: length of the input data
66+
// 6. add(result, 0x20): memory address to store the output (offset by 0x20 for length field)
67+
// 7. len: expected length of the output data
68+
if iszero(call(gas(), 0x01, 0, add(data, 0x20), len, add(result, 0x20), len)) {
69+
// Revert if the call fails
70+
invalid()
71+
}
72+
}
73+
74+
return keccak256(result) == keccak256(data);
75+
}
76+
77+
}
78+
79+
end
80+
81+
account_new acc1 20000000
82+
83+
transaction_build tx01
84+
sender acc1
85+
receiverAddress 00
86+
value 0
87+
data 6080604052348015600e575f5ffd5b506102808061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610034575f3560e01c80631cf61a8b14610038578063b7deb48b14610056575b5f5ffd5b610040610074565b60405161004d9190610204565b60405180910390f35b61005e61012f565b60405161006b9190610204565b60405180910390f35b5f5f6040518060400160405280600581526020017f696e70757400000000000000000000000000000000000000000000000000000081525090505f815167ffffffffffffffff8111156100ca576100c961021d565b5b6040519080825280601f01601f1916602001820160405280156100fc5781602001600182028036833780820191505090505b5090508151806020830182602086015f60015af161011657fe5b5081805190602001208180519060200120149250505090565b5f5f6040518060400160405280600581526020017f696e70757400000000000000000000000000000000000000000000000000000081525090505f815167ffffffffffffffff8111156101855761018461021d565b5b6040519080825280601f01601f1916602001820160405280156101b75781602001600182028036833780820191505090505b5090508151806020830182602086015f60045af16101d157fe5b5081805190602001208180519060200120149250505090565b5f8115159050919050565b6101fe816101ea565b82525050565b5f6020820190506102175f8301846101f5565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffdfea26469706673582212202ece15a537aa6a01c75693f02004e83bd4f90505ed9146202bc64e3a11fed46164736f6c634300081c0033
88+
gas 750000
89+
build
90+
91+
block_build b01
92+
parent g00
93+
transactions tx01
94+
gasLimit 7500000
95+
build
96+
97+
block_connect b01
98+
99+
# Assert best block
100+
assert_best b01

0 commit comments

Comments
 (0)