diff --git a/rskj-core/src/main/java/co/rsk/rpc/ExecutionBlockRetriever.java b/rskj-core/src/main/java/co/rsk/rpc/ExecutionBlockRetriever.java index e9cfce28517..8cf8cd8a715 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/ExecutionBlockRetriever.java +++ b/rskj-core/src/main/java/co/rsk/rpc/ExecutionBlockRetriever.java @@ -62,8 +62,7 @@ public ExecutionBlockRetriever(Blockchain blockchain, BlockToMineBuilder builder } public Result retrieveExecutionBlock(String bnOrId) { - - if(BlockTag.EARLIEST.tagEquals(bnOrId)) { + if (BlockTag.EARLIEST.tagEquals(bnOrId)) { return Result.ofBlock(blockchain.getBlockByNumber(0)); } diff --git a/rskj-core/src/main/java/co/rsk/rpc/Web3EthModule.java b/rskj-core/src/main/java/co/rsk/rpc/Web3EthModule.java index bc320508e1e..f4e7df6e256 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/Web3EthModule.java +++ b/rskj-core/src/main/java/co/rsk/rpc/Web3EthModule.java @@ -19,26 +19,35 @@ package co.rsk.rpc; import co.rsk.rpc.modules.eth.EthModule; -import org.ethereum.rpc.CallArguments; -import org.ethereum.rpc.FilterRequest; import org.ethereum.rpc.dto.BlockResultDTO; import org.ethereum.rpc.dto.CompilationResultDTO; import org.ethereum.rpc.dto.TransactionReceiptDTO; import org.ethereum.rpc.dto.TransactionResultDTO; +import org.ethereum.rpc.parameters.BlockHashParam; +import org.ethereum.rpc.parameters.FilterRequestParam; +import org.ethereum.rpc.parameters.BlockIdentifierParam; +import org.ethereum.rpc.parameters.BlockRefParam; +import org.ethereum.rpc.parameters.CallArgumentsParam; +import org.ethereum.rpc.parameters.HexAddressParam; +import org.ethereum.rpc.parameters.HexDataParam; +import org.ethereum.rpc.parameters.HexIndexParam; +import org.ethereum.rpc.parameters.HexNumberParam; +import org.ethereum.rpc.parameters.TxHashParam; import java.math.BigInteger; import java.util.Map; +@SuppressWarnings({"java:S100", "java:S112"}) public interface Web3EthModule { default String[] eth_accounts() { return getEthModule().accounts(); } - default String eth_sign(String addr, String data) { - return getEthModule().sign(addr, data); + default String eth_sign(HexAddressParam addr, HexDataParam data) { + return getEthModule().sign(addr.getAddress().toHexString(), data.getAsHexString()); } - default String eth_call(CallArguments args, String bnOrId) { + default String eth_call(CallArgumentsParam args, BlockIdentifierParam bnOrId) { return getEthModule().call(args, bnOrId); } @@ -50,8 +59,8 @@ default String eth_chainId() { return getEthModule().chainId(); } - String eth_estimateGas(CallArguments args, String bnOrId); - String eth_estimateGas(CallArguments args); + String eth_estimateGas(CallArgumentsParam args); + String eth_estimateGas(CallArgumentsParam args, BlockIdentifierParam bnOrId); EthModule getEthModule(); @@ -69,59 +78,53 @@ default String eth_chainId() { String eth_blockNumber(); - String eth_call(CallArguments args, Map blockRef) throws Exception; // NOSONAR + String eth_call(CallArgumentsParam args, Map blockRef) throws Exception; // NOSONAR - String eth_getBalance(String address, String block) throws Exception; + String eth_getBalance(HexAddressParam address, BlockRefParam blockRefParam) throws Exception; - String eth_getBalance(String address) throws Exception; + String eth_getBalance(HexAddressParam address) throws Exception; - String eth_getBalance(String address, Map blockRef) throws Exception; // NOSONAR + String eth_getStorageAt(HexAddressParam address, HexNumberParam storageIdx, BlockRefParam blockRefParam) throws Exception; - String eth_getStorageAt(String address, String storageIdx, Map blockRef) throws Exception; // NOSONAR + String eth_getTransactionCount(HexAddressParam address, BlockRefParam blockRefParam) throws Exception; - String eth_getStorageAt(String address, String storageIdx, String blockId) throws Exception; + String eth_getBlockTransactionCountByHash(BlockHashParam blockHash)throws Exception; - String eth_getTransactionCount(String address, Map blockRef) throws Exception; // NOSONAR + String eth_getBlockTransactionCountByNumber(BlockIdentifierParam bnOrId)throws Exception; - String eth_getTransactionCount(String address, String blockId) throws Exception ; + String eth_getUncleCountByBlockHash(BlockHashParam blockHash)throws Exception; - String eth_getBlockTransactionCountByHash(String blockHash)throws Exception; + String eth_getUncleCountByBlockNumber(BlockIdentifierParam bnOrId)throws Exception; - String eth_getBlockTransactionCountByNumber(String bnOrId)throws Exception; + String eth_getCode(HexAddressParam address, BlockRefParam blockRefParam) throws Exception; - String eth_getUncleCountByBlockHash(String blockHash)throws Exception; - - String eth_getUncleCountByBlockNumber(String bnOrId)throws Exception; - - default String eth_getCode(String address, String blockId) { + default String getCode(HexAddressParam address, String blockId) { return getEthModule().getCode(address, blockId); } - String eth_getCode(String address, Map blockRef) throws Exception; // NOSONAR - - default String eth_sendRawTransaction(String rawData) { + default String eth_sendRawTransaction(HexDataParam rawData) { return getEthModule().sendRawTransaction(rawData); } - default String eth_sendTransaction(CallArguments args) { + default String eth_sendTransaction(CallArgumentsParam args) { return getEthModule().sendTransaction(args); } - BlockResultDTO eth_getBlockByHash(String blockHash, Boolean fullTransactionObjects) throws Exception; + BlockResultDTO eth_getBlockByHash(BlockHashParam blockHash, Boolean fullTransactionObjects) throws Exception; - BlockResultDTO eth_getBlockByNumber(String bnOrId, Boolean fullTransactionObjects) throws Exception; + BlockResultDTO eth_getBlockByNumber(BlockIdentifierParam bnOrId, Boolean fullTransactionObjects) throws Exception; - TransactionResultDTO eth_getTransactionByHash(String transactionHash) throws Exception; + TransactionResultDTO eth_getTransactionByHash(TxHashParam transactionHash) throws Exception; - TransactionResultDTO eth_getTransactionByBlockHashAndIndex(String blockHash, String index) throws Exception; + TransactionResultDTO eth_getTransactionByBlockHashAndIndex(BlockHashParam blockHash, HexIndexParam index) throws Exception; - TransactionResultDTO eth_getTransactionByBlockNumberAndIndex(String bnOrId, String index) throws Exception; + TransactionResultDTO eth_getTransactionByBlockNumberAndIndex(BlockIdentifierParam bnOrId, HexIndexParam index) throws Exception; - TransactionReceiptDTO eth_getTransactionReceipt(String transactionHash) throws Exception; + TransactionReceiptDTO eth_getTransactionReceipt(TxHashParam transactionHash) throws Exception; - BlockResultDTO eth_getUncleByBlockHashAndIndex(String blockHash, String uncleIdx) throws Exception; + BlockResultDTO eth_getUncleByBlockHashAndIndex(BlockHashParam blockHash, HexIndexParam uncleIdx) throws Exception; - BlockResultDTO eth_getUncleByBlockNumberAndIndex(String blockId, String uncleIdx) throws Exception; + BlockResultDTO eth_getUncleByBlockNumberAndIndex(BlockIdentifierParam blockId, HexIndexParam uncleIdx) throws Exception; String[] eth_getCompilers(); @@ -131,19 +134,19 @@ default String eth_sendTransaction(CallArguments args) { Map eth_compileSolidity(String contract); - String eth_newFilter(FilterRequest fr) throws Exception; + String eth_newFilter(FilterRequestParam fr) throws Exception; String eth_newBlockFilter(); String eth_newPendingTransactionFilter(); - boolean eth_uninstallFilter(String id); + boolean eth_uninstallFilter(HexIndexParam id); - Object[] eth_getFilterChanges(String id); + Object[] eth_getFilterChanges(HexIndexParam id); - Object[] eth_getFilterLogs(String id); + Object[] eth_getFilterLogs(HexIndexParam id); - Object[] eth_getLogs(FilterRequest fr) throws Exception; + Object[] eth_getLogs(FilterRequestParam fr) throws Exception; BigInteger eth_netHashrate(); diff --git a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModule.java b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModule.java index 3f26ebb2a62..4c6c02f1c2f 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModule.java +++ b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModule.java @@ -39,6 +39,10 @@ import org.ethereum.rpc.CallArguments; import org.ethereum.rpc.converters.CallArgumentsToByteArray; import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.ethereum.rpc.parameters.BlockIdentifierParam; +import org.ethereum.rpc.parameters.CallArgumentsParam; +import org.ethereum.rpc.parameters.HexAddressParam; +import org.ethereum.rpc.parameters.HexDataParam; import org.ethereum.vm.GasCost; import org.ethereum.vm.PrecompiledContracts; import org.ethereum.vm.program.ProgramResult; @@ -122,10 +126,11 @@ public Map bridgeState() throws IOException, BlockStoreException return state.stateToMap(); } - public String call(CallArguments args, String bnOrId) { + public String call(CallArgumentsParam argsParam, BlockIdentifierParam bnOrId) { String hReturn = null; + CallArguments args = argsParam.toCallArguments(); try { - ExecutionBlockRetriever.Result result = executionBlockRetriever.retrieveExecutionBlock(bnOrId); + ExecutionBlockRetriever.Result result = executionBlockRetriever.retrieveExecutionBlock(bnOrId.getIdentifier()); Block block = result.getBlock(); Trie finalState = result.getFinalState(); ProgramResult res; @@ -152,8 +157,8 @@ public String call(CallArguments args, String bnOrId) { } } - public String estimateGas(CallArguments args, @Nonnull String bnOrId) { - ExecutionBlockRetriever.Result result = executionBlockRetriever.retrieveExecutionBlock(bnOrId); + public String estimateGas(CallArgumentsParam args, @Nonnull BlockIdentifierParam bnOrId) { + ExecutionBlockRetriever.Result result = executionBlockRetriever.retrieveExecutionBlock(bnOrId.getIdentifier()); Block block = result.getBlock(); Trie finalState = result.getFinalState(); RepositorySnapshot snapshot = finalState == null @@ -162,7 +167,7 @@ public String estimateGas(CallArguments args, @Nonnull String bnOrId) { String estimation = null; try { - CallArgumentsToByteArray hexArgs = new CallArgumentsToByteArray(args); + CallArgumentsToByteArray hexArgs = new CallArgumentsToByteArray(args.toCallArguments()); TransactionExecutor executor = reversibleTransactionExecutor.estimateGas( block, @@ -203,12 +208,12 @@ protected String internalEstimateGas(ProgramResult reversibleExecutionResult) { } @Override - public String sendTransaction(CallArguments args) { + public String sendTransaction(CallArgumentsParam args) { return ethModuleTransaction.sendTransaction(args); } @Override - public String sendRawTransaction(String rawData) { + public String sendRawTransaction(HexDataParam rawData) { return ethModuleTransaction.sendRawTransaction(rawData); } @@ -221,14 +226,14 @@ public String chainId() { return HexUtils.toJsonHex(new byte[]{chainId}); } - public String getCode(String address, String blockId) { + public String getCode(HexAddressParam address, String blockId) { if (blockId == null) { throw new NullPointerException(); } String s = null; + RskAddress addr = address.getAddress(); try { - RskAddress addr = new RskAddress(address); AccountInformationProvider accountInformationProvider = getAccountInformationProvider(blockId); @@ -246,7 +251,7 @@ public String getCode(String address, String blockId) { return s; } finally { if (LOGGER.isDebugEnabled()) { - LOGGER.debug("eth_getCode({}, {}): {}", address, blockId, s); + LOGGER.debug("eth_getCode({}, {}): {}", addr.toHexString(), blockId, s); } } } diff --git a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleTransaction.java b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleTransaction.java index f3c1ea1300b..d9357b05c19 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleTransaction.java +++ b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleTransaction.java @@ -18,10 +18,11 @@ package co.rsk.rpc.modules.eth; -import org.ethereum.rpc.CallArguments; +import org.ethereum.rpc.parameters.CallArgumentsParam; +import org.ethereum.rpc.parameters.HexDataParam; public interface EthModuleTransaction { - String sendTransaction(CallArguments args); + String sendTransaction(CallArgumentsParam args); - String sendRawTransaction(String rawData); + String sendRawTransaction(HexDataParam rawData); } diff --git a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleTransactionBase.java b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleTransactionBase.java index 6cc64af4c22..f2b7a125a86 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleTransactionBase.java +++ b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleTransactionBase.java @@ -30,6 +30,8 @@ import org.ethereum.core.TransactionPoolAddResult; import org.ethereum.rpc.CallArguments; import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.ethereum.rpc.parameters.CallArgumentsParam; +import org.ethereum.rpc.parameters.HexDataParam; import org.ethereum.util.TransactionArgumentsUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,7 +39,6 @@ import co.rsk.core.RskAddress; import co.rsk.core.Wallet; import co.rsk.net.TransactionGateway; -import co.rsk.util.HexUtils; public class EthModuleTransactionBase implements EthModuleTransaction { @@ -56,7 +57,12 @@ public EthModuleTransactionBase(Constants constants, Wallet wallet, TransactionP } @Override - public synchronized String sendTransaction(CallArguments args) { + public synchronized String sendTransaction(CallArgumentsParam argsParam) { + CallArguments args = argsParam.toCallArguments(); + + if(args.getFrom() == null) { + throw invalidParamError("from is null"); + } Account senderAccount = this.wallet.getAccount(new RskAddress(args.getFrom())); @@ -97,10 +103,10 @@ public synchronized String sendTransaction(CallArguments args) { } @Override - public String sendRawTransaction(String rawData) { + public String sendRawTransaction(HexDataParam rawData) { String s = null; try { - Transaction tx = new ImmutableTransaction(HexUtils.stringHexToByteArray(rawData)); + Transaction tx = new ImmutableTransaction(rawData.getRawDataBytes()); if (null == tx.getGasLimit() || null == tx.getGasPrice() || null == tx.getValue()) { throw invalidParamError("Missing parameter, gasPrice, gas or value"); diff --git a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleTransactionDisabled.java b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleTransactionDisabled.java index 0f1bee0cad6..6b0313f6033 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleTransactionDisabled.java +++ b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleTransactionDisabled.java @@ -21,7 +21,7 @@ import co.rsk.net.TransactionGateway; import org.ethereum.config.Constants; import org.ethereum.core.TransactionPool; -import org.ethereum.rpc.CallArguments; +import org.ethereum.rpc.parameters.CallArgumentsParam; import static org.ethereum.rpc.exception.RskJsonRpcRequestException.invalidParamError; @@ -36,7 +36,7 @@ public EthModuleTransactionDisabled(Constants constants, TransactionPool transac } @Override - public String sendTransaction(CallArguments args) { // lgtm [java/non-sync-override] + public synchronized String sendTransaction(CallArgumentsParam args) { // lgtm [java/non-sync-override] LOGGER.debug("eth_sendTransaction({}): {}", args, null); throw invalidParamError("Local wallet is disabled in this node"); } diff --git a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleTransactionInstant.java b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleTransactionInstant.java index ee879308874..f5b08ae5dfa 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleTransactionInstant.java +++ b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleTransactionInstant.java @@ -27,8 +27,9 @@ import org.ethereum.core.Blockchain; import org.ethereum.core.TransactionPool; import org.ethereum.db.TransactionInfo; -import org.ethereum.rpc.CallArguments; import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.ethereum.rpc.parameters.CallArgumentsParam; +import org.ethereum.rpc.parameters.HexDataParam; import org.ethereum.vm.program.ProgramResult; import co.rsk.core.Wallet; @@ -64,7 +65,7 @@ public EthModuleTransactionInstant( } @Override - public synchronized String sendTransaction(CallArguments args) { + public synchronized String sendTransaction(CallArgumentsParam args) { try { this.blockExecutor.setRegisterProgramResults(true); @@ -80,7 +81,7 @@ public synchronized String sendTransaction(CallArguments args) { } @Override - public String sendRawTransaction(String rawData) { + public String sendRawTransaction(HexDataParam rawData) { try { this.blockExecutor.setRegisterProgramResults(true); diff --git a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWalletEnabled.java b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWalletEnabled.java index 2341857377c..7ac52b5e3a1 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWalletEnabled.java +++ b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWalletEnabled.java @@ -23,6 +23,7 @@ import java.nio.charset.StandardCharsets; import java.util.Arrays; +import co.rsk.core.RskAddress; import org.bouncycastle.util.BigIntegers; import org.ethereum.core.Account; import org.ethereum.crypto.ECKey; @@ -32,7 +33,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import co.rsk.core.RskAddress; import co.rsk.core.Wallet; import co.rsk.util.HexUtils; @@ -55,7 +55,9 @@ public String sign(String addr, String data) { throw invalidParamError("Account not found"); } - return s = this.sign(data, account.getEcKey()); + s = this.sign(data, account.getEcKey()); + + return s; } finally { LOGGER.debug("eth_sign({}, {}): {}", addr, data, s); } diff --git a/rskj-core/src/main/java/co/rsk/rpc/modules/personal/PersonalModule.java b/rskj-core/src/main/java/co/rsk/rpc/modules/personal/PersonalModule.java index 62b5cbd8f4d..af1102c80f7 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/modules/personal/PersonalModule.java +++ b/rskj-core/src/main/java/co/rsk/rpc/modules/personal/PersonalModule.java @@ -18,24 +18,27 @@ package co.rsk.rpc.modules.personal; -import org.ethereum.rpc.CallArguments; +import org.ethereum.rpc.parameters.CallArgumentsParam; +import org.ethereum.rpc.parameters.HexAddressParam; +import org.ethereum.rpc.parameters.HexDurationParam; +import org.ethereum.rpc.parameters.HexKeyParam; public interface PersonalModule { - String dumpRawKey(String address) throws Exception; + String dumpRawKey(HexAddressParam address) throws Exception; - String importRawKey(String key, String passphrase); + String importRawKey(HexKeyParam key, String passphrase); void init(); String[] listAccounts(); - boolean lockAccount(String address); + boolean lockAccount(HexAddressParam address); String newAccountWithSeed(String seed); String newAccount(String passphrase); - String sendTransaction(CallArguments args, String passphrase) throws Exception; + String sendTransaction(CallArgumentsParam args, String passphrase) throws Exception; - boolean unlockAccount(String address, String passphrase, String duration); + boolean unlockAccount(HexAddressParam address, String passphrase, HexDurationParam duration); } diff --git a/rskj-core/src/main/java/co/rsk/rpc/modules/personal/PersonalModuleWalletDisabled.java b/rskj-core/src/main/java/co/rsk/rpc/modules/personal/PersonalModuleWalletDisabled.java index 0379c0fe5c1..616b912b2d4 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/modules/personal/PersonalModuleWalletDisabled.java +++ b/rskj-core/src/main/java/co/rsk/rpc/modules/personal/PersonalModuleWalletDisabled.java @@ -18,8 +18,11 @@ package co.rsk.rpc.modules.personal; -import org.ethereum.rpc.CallArguments; import org.ethereum.rpc.exception.DisabledWalletException; +import org.ethereum.rpc.parameters.CallArgumentsParam; +import org.ethereum.rpc.parameters.HexAddressParam; +import org.ethereum.rpc.parameters.HexDurationParam; +import org.ethereum.rpc.parameters.HexKeyParam; public class PersonalModuleWalletDisabled implements PersonalModule { @Override @@ -45,27 +48,27 @@ public String[] listAccounts() { } @Override - public String importRawKey(String key, String passphrase) { + public String importRawKey(HexKeyParam key, String passphrase) { throw new DisabledWalletException(); } @Override - public String sendTransaction(CallArguments args, String passphrase) { + public String sendTransaction(CallArgumentsParam args, String passphrase) { throw new DisabledWalletException(); } @Override - public boolean unlockAccount(String address, String passphrase, String duration) { + public boolean unlockAccount(HexAddressParam address, String passphrase, HexDurationParam duration) { throw new DisabledWalletException(); } @Override - public boolean lockAccount(String address) { + public boolean lockAccount(HexAddressParam address) { throw new DisabledWalletException(); } @Override - public String dumpRawKey(String address) { + public String dumpRawKey(HexAddressParam address) { throw new DisabledWalletException(); } } \ No newline at end of file diff --git a/rskj-core/src/main/java/co/rsk/rpc/modules/personal/PersonalModuleWalletEnabled.java b/rskj-core/src/main/java/co/rsk/rpc/modules/personal/PersonalModuleWalletEnabled.java index 141319d7c6c..eb294b1f43e 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/modules/personal/PersonalModuleWalletEnabled.java +++ b/rskj-core/src/main/java/co/rsk/rpc/modules/personal/PersonalModuleWalletEnabled.java @@ -29,12 +29,17 @@ import org.ethereum.facade.Ethereum; import org.ethereum.rpc.CallArguments; import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.ethereum.rpc.parameters.CallArgumentsParam; +import org.ethereum.rpc.parameters.HexAddressParam; +import org.ethereum.rpc.parameters.HexDurationParam; +import org.ethereum.rpc.parameters.HexKeyParam; import org.ethereum.util.ByteUtil; import org.ethereum.util.TransactionArgumentsUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Arrays; +import java.util.Optional; import static org.ethereum.rpc.exception.RskJsonRpcRequestException.invalidParamError; @@ -121,8 +126,13 @@ public String[] listAccounts() { } @Override - public String importRawKey(String key, String passphrase) { + public String importRawKey(HexKeyParam keyParam, String passphrase) { String s = null; + String key = Optional.ofNullable(keyParam).map(HexKeyParam::getHexKey) + .orElseThrow( + () -> RskJsonRpcRequestException.invalidParamError("Key cannot be null.") + ); + try { if (key != null && key.startsWith("0x")) { key = key.substring(2); @@ -136,8 +146,9 @@ public String importRawKey(String key, String passphrase) { } @Override - public String sendTransaction(CallArguments args, String passphrase) throws Exception { + public String sendTransaction(CallArgumentsParam argsParam, String passphrase) throws Exception { String s = null; + CallArguments args = argsParam.toCallArguments(); try { return s = sendTransaction(args, getAccount(args.getFrom(), passphrase)); } finally { @@ -146,15 +157,15 @@ public String sendTransaction(CallArguments args, String passphrase) throws Exce } @Override - public boolean unlockAccount(String address, String passphrase, String duration) { - return unlockAccount(new RskAddress(address), passphrase, duration); + public boolean unlockAccount(HexAddressParam address, String passphrase, HexDurationParam duration) { + return unlockAccount(address.getAddress(), passphrase, duration); } - private boolean unlockAccount(RskAddress addr, String passphrase, String duration) { + private boolean unlockAccount(RskAddress addr, String passphrase, HexDurationParam duration) { long dur = (long) 1000 * 60 * 30; - if (duration != null && duration.length() > 0) { + if (duration != null && duration.getDuration() != null) { try { - dur = convertFromJsonHexToLong(duration); + dur = duration.getDuration(); } catch (Exception e) { throw invalidParamError("Can't parse duration param", e); } @@ -164,15 +175,15 @@ private boolean unlockAccount(RskAddress addr, String passphrase, String duratio } @Override - public boolean lockAccount(String address) { - return this.wallet.lockAccount(new RskAddress(address)); + public boolean lockAccount(HexAddressParam address) { + return this.wallet.lockAccount(address.getAddress()); } @Override - public String dumpRawKey(String address) throws Exception { + public String dumpRawKey(HexAddressParam address) throws Exception { String s = null; try { - Account account = wallet.getAccount(new RskAddress(convertFromJsonHexToHex(address))); + Account account = wallet.getAccount(address.getAddress()); if (account == null) { throw new Exception("Address private key is locked or could not be found in this node"); } @@ -209,19 +220,4 @@ private String sendTransaction(CallArguments args, Account senderAccount) throws } return tx.getHash().toJsonString(); } - - private String convertFromJsonHexToHex(String x) throws Exception { - if (!x.startsWith("0x")) { - throw new Exception("Incorrect hex syntax"); - } - - return x.substring(2); - } - - private long convertFromJsonHexToLong(String x) throws Exception { - if (!x.startsWith("0x")) { - throw new Exception("Incorrect hex syntax"); - } - return Long.parseLong(x.substring(2), 16); - } } diff --git a/rskj-core/src/main/java/co/rsk/util/HexUtils.java b/rskj-core/src/main/java/co/rsk/util/HexUtils.java index 3007001e23d..f04aae64aef 100644 --- a/rskj-core/src/main/java/co/rsk/util/HexUtils.java +++ b/rskj-core/src/main/java/co/rsk/util/HexUtils.java @@ -22,12 +22,12 @@ import org.bouncycastle.util.encoders.Hex; import org.ethereum.util.ByteUtil; -import static org.ethereum.rpc.exception.RskJsonRpcRequestException.invalidParamError; - import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.util.regex.Pattern; +import static org.ethereum.rpc.exception.RskJsonRpcRequestException.invalidParamError; + /** * Hex utils */ @@ -362,4 +362,14 @@ public static int jsonHexToInt(final String param) { return Integer.parseInt(preResult, 16); } + public static int jsonHexToIntOptionalPrefix(final String param) { + if (!hasHexPrefix(param) && !HexUtils.isHex(param)) { + throw invalidParamError(INCORRECT_HEX_SYNTAX); + } + + String preResult = removeHexPrefix(param); + + return Integer.parseInt(preResult, 16); + } + } diff --git a/rskj-core/src/main/java/org/ethereum/rpc/Web3.java b/rskj-core/src/main/java/org/ethereum/rpc/Web3.java index a27803107e9..8b16c98019b 100644 --- a/rskj-core/src/main/java/org/ethereum/rpc/Web3.java +++ b/rskj-core/src/main/java/org/ethereum/rpc/Web3.java @@ -30,6 +30,10 @@ import co.rsk.rpc.Web3TxPoolModule; import co.rsk.scoring.PeerScoringInformation; import co.rsk.scoring.PeerScoringReputationSummary; +import org.ethereum.rpc.parameters.CallArgumentsParam; +import org.ethereum.rpc.parameters.HexAddressParam; +import org.ethereum.rpc.parameters.HexDurationParam; +import org.ethereum.rpc.parameters.HexKeyParam; @java.lang.SuppressWarnings("squid:S100") public interface Web3 extends InternalService, Web3TxPoolModule, Web3EthModule, Web3EvmModule, Web3MnrModule, Web3DebugModule, Web3TraceModule, Web3RskModule { @@ -54,11 +58,11 @@ public interface Web3 extends InternalService, Web3TxPoolModule, Web3EthModule, String personal_newAccountWithSeed(String seed); String personal_newAccount(String passphrase); String[] personal_listAccounts(); - String personal_importRawKey(String key, String passphrase); - String personal_sendTransaction(CallArguments transactionArgs, String passphrase) throws Exception; - boolean personal_unlockAccount(String key, String passphrase, String duration); - boolean personal_lockAccount(String key); - String personal_dumpRawKey(String address) throws Exception; + String personal_importRawKey(HexKeyParam key, String passphrase); + String personal_sendTransaction(CallArgumentsParam transactionArgs, String passphrase) throws Exception; + boolean personal_unlockAccount(HexAddressParam key, String passphrase, HexDurationParam duration); + boolean personal_lockAccount(HexAddressParam key); + String personal_dumpRawKey(HexAddressParam address) throws Exception; void sco_banAddress(String address); void sco_unbanAddress(String address); diff --git a/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java b/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java index e91578400b4..1c224f659d3 100644 --- a/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java +++ b/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java @@ -43,7 +43,6 @@ import co.rsk.scoring.*; import co.rsk.util.HexUtils; import com.google.common.annotations.VisibleForTesting; -import org.apache.commons.lang3.StringUtils; import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.core.*; import org.ethereum.core.genesis.BlockTag; @@ -61,11 +60,14 @@ import org.ethereum.rpc.dto.CompilationResultDTO; import org.ethereum.rpc.dto.TransactionReceiptDTO; import org.ethereum.rpc.dto.TransactionResultDTO; +import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.ethereum.rpc.parameters.*; import org.ethereum.util.BuildInfo; import org.ethereum.vm.DataWord; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nullable; import java.math.BigInteger; import java.net.InetAddress; import java.net.UnknownHostException; @@ -79,6 +81,7 @@ import static java.lang.Math.max; import static org.ethereum.rpc.exception.RskJsonRpcRequestException.*; +@SuppressWarnings("java:S100") public class Web3Impl implements Web3 { private static final Logger logger = LoggerFactory.getLogger("web3"); @@ -398,17 +401,33 @@ public String eth_blockNumber() { } @Override - public String eth_call(CallArguments args, Map inputs) { - return invokeByBlockRef(inputs, blockNumber -> this.eth_call(args, blockNumber)); + public String eth_call(CallArgumentsParam args, Map inputs) { + return invokeByBlockRef(inputs, blockNumber -> this.eth_call(args, new BlockIdentifierParam(blockNumber))); } @Override - public String eth_getCode(String address, Map inputs) { - return invokeByBlockRef(inputs, blockNumber -> this.eth_getCode(address, blockNumber)); + public String eth_getCode(HexAddressParam address, BlockRefParam blockRefParam) { + if (blockRefParam.getIdentifier() != null) { + return this.getCode(address, blockRefParam.getIdentifier()); + } else { + return this.eth_getCode(address, blockRefParam.getInputs()); + } + } + + private String eth_getCode(HexAddressParam address, Map inputs) { + return invokeByBlockRef(inputs, blockNumber -> this.getCode(address, blockNumber)); } @Override - public String eth_getBalance(String address, String block) { + public String eth_getBalance(HexAddressParam address, BlockRefParam blockRefParam) { + if (blockRefParam.getIdentifier() != null) { + return this.eth_getBalance(address, blockRefParam.getIdentifier()); + } else { + return this.eth_getBalance(address, blockRefParam.getInputs()); + } + } + + private String eth_getBalance(HexAddressParam address, String block) { /* HEX String - an integer block number * String "earliest" for the earliest/genesis block * String "latest" - for the latest mined block @@ -417,14 +436,14 @@ public String eth_getBalance(String address, String block) { AccountInformationProvider accountInformationProvider = web3InformationRetriever.getInformationProvider(block); - RskAddress addr = new RskAddress(address); + RskAddress addr = address.getAddress(); Coin balance = accountInformationProvider.getBalance(addr); return toQuantityJsonHex(balance.asBigInteger()); } - @Override - public String eth_getBalance(String address, Map inputs) { + + private String eth_getBalance(HexAddressParam address, Map inputs) { return invokeByBlockRef(inputs, blockNumber -> this.eth_getBalance(address, blockNumber)); } @@ -438,27 +457,34 @@ private boolean isInMainChain(Block block) { } @Override - public String eth_getBalance(String address) { + public String eth_getBalance(HexAddressParam address) { return eth_getBalance(address, "latest"); } @Override - public String eth_getStorageAt(String address, String storageIdx, Map blockRef) { + public String eth_getStorageAt(HexAddressParam address, HexNumberParam storageIdx, BlockRefParam blockRefParam) { + if (blockRefParam.getIdentifier() != null) { + return this.eth_getStorageAt(address, storageIdx, blockRefParam.getIdentifier()); + } else { + return this.eth_getStorageAt(address, storageIdx, blockRefParam.getInputs()); + } + } + + private String eth_getStorageAt(HexAddressParam address, HexNumberParam storageIdx, Map blockRef) { return invokeByBlockRef(blockRef, blockNumber -> this.eth_getStorageAt(address, storageIdx, blockNumber)); } - @Override - public String eth_getStorageAt(String address, String storageIdx, String blockId) { + private String eth_getStorageAt(HexAddressParam address, HexNumberParam storageIdx, String blockId) { String s = null; try { - RskAddress addr = new RskAddress(address); + RskAddress addr = address.getAddress(); AccountInformationProvider accountInformationProvider = web3InformationRetriever.getInformationProvider(blockId); DataWord sv = accountInformationProvider - .getStorageValue(addr, DataWord.valueOf(HexUtils.strHexOrStrNumberToByteArray(storageIdx))); + .getStorageValue(addr, DataWord.valueOf(HexUtils.strHexOrStrNumberToByteArray(storageIdx.getHexNumber()))); if (sv == null) { s = "0x0"; @@ -475,7 +501,15 @@ public String eth_getStorageAt(String address, String storageIdx, String blockId } @Override - public String eth_getTransactionCount(String address, Map inputs) { + public String eth_getTransactionCount(HexAddressParam address, BlockRefParam blockRefParam) { + if (blockRefParam.getIdentifier() != null) { + return this.eth_getTransactionCount(address, blockRefParam.getIdentifier()); + } else { + return this.eth_getTransactionCount(address, blockRefParam.getInputs()); + } + } + + private String eth_getTransactionCount(HexAddressParam address, Map inputs) { return invokeByBlockRef(inputs, blockNumber -> this.eth_getTransactionCount(address, blockNumber)); } @@ -509,11 +543,10 @@ private String toInvokeByBlockHash(String blockHash, boolean requireCanonical, F return toInvokeByBlockNumber.apply(toQuantityJsonHex(block.getNumber())); } - @Override - public String eth_getTransactionCount(String address, String blockId) { + private String eth_getTransactionCount(HexAddressParam address, String blockId) { String s = null; try { - RskAddress addr = new RskAddress(address); + RskAddress addr = address.getAddress(); AccountInformationProvider accountInformationProvider = web3InformationRetriever .getInformationProvider(blockId); BigInteger nonce = accountInformationProvider.getNonce(addr); @@ -537,10 +570,10 @@ public Block getBlockByJSonHash(String blockHash) { } @Override - public String eth_getBlockTransactionCountByHash(String blockHash) { + public String eth_getBlockTransactionCountByHash(BlockHashParam blockHash) { String s = null; try { - Block b = getBlockByJSonHash(blockHash); + Block b = blockchain.getBlockByHash(blockHash.getHash().getBytes()); if (b == null) { return null; @@ -575,11 +608,11 @@ public static Block getBlockByNumberOrStr(String bnOrId, Blockchain blockchain) } @Override - public String eth_getBlockTransactionCountByNumber(String bnOrId) { + public String eth_getBlockTransactionCountByNumber(BlockIdentifierParam bnOrId) { String s = null; try { - List txs = web3InformationRetriever.getTransactions(bnOrId); + List txs = web3InformationRetriever.getTransactions(bnOrId.getIdentifier()); s = toQuantityJsonHex(txs.size()); return s; @@ -591,7 +624,8 @@ public String eth_getBlockTransactionCountByNumber(String bnOrId) { } @Override - public String eth_getUncleCountByBlockHash(String blockHash) { + public String eth_getUncleCountByBlockHash(BlockHashParam blockHashParam) { + String blockHash = blockHashParam.getHash().toString(); Block b = getBlockByJSonHash(blockHash); if (b == null) { throw blockNotFound(String.format("Block with hash %s not found", blockHash)); @@ -602,12 +636,13 @@ public String eth_getUncleCountByBlockHash(String blockHash) { } @Override - public String eth_getUncleCountByBlockNumber(String bnOrId) { - return web3InformationRetriever.getBlock(bnOrId) + public String eth_getUncleCountByBlockNumber(BlockIdentifierParam identifierParam) { + String bnorId = identifierParam.getIdentifier(); + return web3InformationRetriever.getBlock(bnorId) .map(Block::getUncleList) .map(List::size) .map(HexUtils::toQuantityJsonHex) - .orElseThrow(() -> blockNotFound(String.format("Block %s not found", bnOrId))); + .orElseThrow(() -> blockNotFound(String.format("Block %s not found", bnorId))); } public BlockInformationResult getBlockInformationResult(BlockInformation blockInformation) { @@ -644,10 +679,14 @@ public BlockInformationResult[] eth_getBlocksByNumber(String number) { } @Override - public BlockResultDTO eth_getBlockByHash(String blockHash, Boolean fullTransactionObjects) { + public BlockResultDTO eth_getBlockByHash(BlockHashParam blockHash, Boolean fullTransactionObjects) { + if (blockHash == null) { + throw invalidParamError("blockHash is null"); + } + BlockResultDTO s = null; try { - Block b = getBlockByJSonHash(blockHash); + Block b = this.blockchain.getBlockByHash(blockHash.getHash().getBytes()); s = (b == null ? null : getBlockResult(b, fullTransactionObjects)); return s; } finally { @@ -658,8 +697,10 @@ public BlockResultDTO eth_getBlockByHash(String blockHash, Boolean fullTransacti } @Override - public BlockResultDTO eth_getBlockByNumber(String bnOrId, Boolean fullTransactionObjects) { + public BlockResultDTO eth_getBlockByNumber(BlockIdentifierParam identifierParam, Boolean fullTransactionObjects) { BlockResultDTO s = null; + String bnOrId = identifierParam.getIdentifier(); + try { s = web3InformationRetriever.getBlock(bnOrId) @@ -675,10 +716,10 @@ public BlockResultDTO eth_getBlockByNumber(String bnOrId, Boolean fullTransactio } @Override - public TransactionResultDTO eth_getTransactionByHash(String transactionHash) { + public TransactionResultDTO eth_getTransactionByHash(TxHashParam transactionHash) { TransactionResultDTO s = null; try { - Keccak256 txHash = new Keccak256(stringHexToByteArray(transactionHash)); + Keccak256 txHash = transactionHash.getHash(); Block block = null; TransactionInfo txInfo = this.receiptStore.getInMainChain(txHash.getBytes(), blockStore).orElse(null); @@ -713,16 +754,24 @@ public TransactionResultDTO eth_getTransactionByHash(String transactionHash) { } @Override - public TransactionResultDTO eth_getTransactionByBlockHashAndIndex(String blockHash, String index) { + public TransactionResultDTO eth_getTransactionByBlockHashAndIndex(BlockHashParam blockHash, HexIndexParam index) { + if (blockHash == null) { + throw invalidParamError("blockHash is null"); + } + + if (index == null) { + throw invalidParamError("index is null"); + } + TransactionResultDTO s = null; try { - Block b = getBlockByJSonHash(blockHash); + Block b = blockchain.getBlockByHash(blockHash.getHash().getBytes()); if (b == null) { return null; } - int idx = jsonHexToInt(index); + int idx = index.getIndex(); if (idx >= b.getTransactionsList().size()) { return null; @@ -739,15 +788,16 @@ public TransactionResultDTO eth_getTransactionByBlockHashAndIndex(String blockHa } @Override - public TransactionResultDTO eth_getTransactionByBlockNumberAndIndex(String bnOrId, String index) { + public TransactionResultDTO eth_getTransactionByBlockNumberAndIndex(BlockIdentifierParam identifierParam, HexIndexParam index) { TransactionResultDTO s = null; + String bnOrId = identifierParam.getIdentifier(); try { Optional block = web3InformationRetriever.getBlock(bnOrId); if (!block.isPresent()) { return null; } - int idx = jsonHexToInt(index); + int idx = index.getIndex(); List txs = web3InformationRetriever.getTransactions(bnOrId); if (idx >= txs.size()) { return null; @@ -763,10 +813,10 @@ public TransactionResultDTO eth_getTransactionByBlockNumberAndIndex(String bnOrI } @Override - public TransactionReceiptDTO eth_getTransactionReceipt(String transactionHash) { + public TransactionReceiptDTO eth_getTransactionReceipt(TxHashParam transactionHash) { logger.trace("eth_getTransactionReceipt({})", transactionHash); - byte[] hash = stringHexToByteArray(transactionHash); + byte[] hash = stringHexToByteArray(transactionHash.getHash().toHexString()); TransactionInfo txInfo = receiptStore.getInMainChain(hash, blockStore).orElse(null); if (txInfo == null) { @@ -782,17 +832,17 @@ public TransactionReceiptDTO eth_getTransactionReceipt(String transactionHash) { } @Override - public BlockResultDTO eth_getUncleByBlockHashAndIndex(String blockHash, String uncleIdx) { + public BlockResultDTO eth_getUncleByBlockHashAndIndex(BlockHashParam blockHash, HexIndexParam uncleIdx) { BlockResultDTO s = null; try { - Block block = blockchain.getBlockByHash(stringHexToByteArray(blockHash)); + Block block = blockchain.getBlockByHash(blockHash.getHash().getBytes()); if (block == null) { return null; } - s = getUncleResultDTO(uncleIdx, block); + s = getUncleResultDTO(uncleIdx.getIndex(), block); return s; } finally { @@ -802,14 +852,13 @@ public BlockResultDTO eth_getUncleByBlockHashAndIndex(String blockHash, String u } } - private BlockResultDTO getUncleResultDTO(String uncleIdx, Block block) { - int idx = jsonHexToInt(uncleIdx); + private BlockResultDTO getUncleResultDTO(Integer uncleIdx, Block block) { - if (idx >= block.getUncleList().size()) { + if (uncleIdx >= block.getUncleList().size()) { return null; } - BlockHeader uncleHeader = block.getUncleList().get(idx); + BlockHeader uncleHeader = block.getUncleList().get(uncleIdx); Block uncle = blockchain.getBlockByHash(uncleHeader.getHash().getBytes()); if (uncle == null) { @@ -821,16 +870,18 @@ private BlockResultDTO getUncleResultDTO(String uncleIdx, Block block) { } @Override - public BlockResultDTO eth_getUncleByBlockNumberAndIndex(String blockId, String uncleIdx) { + public BlockResultDTO eth_getUncleByBlockNumberAndIndex(BlockIdentifierParam identifierParam, HexIndexParam uncleIdx) { BlockResultDTO s = null; + String blockId = identifierParam.getIdentifier(); + try { Optional block = web3InformationRetriever.getBlock(blockId); if (!block.isPresent()) { return null; } - - s = getUncleResultDTO(uncleIdx, block.get()); + int idx = uncleIdx.getIndex(); + s = getUncleResultDTO(idx, block.get()); return s; } finally { @@ -868,7 +919,11 @@ public Map eth_compileSolidity(String contract) { } @Override - public String eth_newFilter(FilterRequest fr) throws Exception { + public String eth_newFilter(FilterRequestParam filterRequestParam) throws Exception { + return newFilter(filterRequestParam.toFilterRequest()); + } + + private String newFilter(FilterRequest fr) { String str = null; try { Filter filter = LogFilter.fromFilterRequest(fr, blockchain, blocksBloomStore, config.getRpcEthGetLogsMaxBlockToQuery(), config.getRpcEthGetLogsMaxLogsToReturn()); @@ -914,7 +969,7 @@ public String eth_newPendingTransactionFilter() { } @Override - public boolean eth_uninstallFilter(String id) { + public boolean eth_uninstallFilter(HexIndexParam id) { Boolean s = null; try { @@ -922,7 +977,7 @@ public boolean eth_uninstallFilter(String id) { return false; } - return filterManager.removeFilter(stringHexToBigInteger(id).intValue()); + return filterManager.removeFilter(id.getIndex()); } finally { if (logger.isDebugEnabled()) { logger.debug("eth_uninstallFilter({}): {}", id, s); @@ -931,7 +986,7 @@ public boolean eth_uninstallFilter(String id) { } @Override - public Object[] eth_getFilterChanges(String id) { + public Object[] eth_getFilterChanges(HexIndexParam id) { logger.debug("eth_getFilterChanges ..."); // TODO(mc): this is a quick solution that seems to work with OpenZeppelin tests, but needs to be reviewed @@ -944,7 +999,7 @@ public Object[] eth_getFilterChanges(String id) { Object[] s = null; try { - s = getFilterEvents(id, true); + s = this.filterManager.getFilterEvents(id.getIndex(), true); } finally { if (logger.isDebugEnabled()) { logger.debug("eth_getFilterChanges({}): {}", id, Arrays.toString(s)); @@ -955,13 +1010,14 @@ public Object[] eth_getFilterChanges(String id) { } @Override - public Object[] eth_getFilterLogs(String id) { + public Object[] eth_getFilterLogs(HexIndexParam id) { logger.debug("eth_getFilterLogs ..."); Object[] s = null; try { - s = getFilterEvents(id, false); + s = this.filterManager.getFilterEvents(id.getIndex(), false); + } finally { if (logger.isDebugEnabled()) { logger.debug("eth_getFilterLogs({}): {}", id, Arrays.toString(s)); @@ -971,16 +1027,13 @@ public Object[] eth_getFilterLogs(String id) { return s; } - private Object[] getFilterEvents(String id, boolean newevents) { - return this.filterManager.getFilterEvents(stringHexToBigInteger(id).intValue(), newevents); - } - @Override - public Object[] eth_getLogs(FilterRequest fr) throws Exception { + public Object[] eth_getLogs(FilterRequestParam fr) throws Exception { logger.debug("eth_getLogs ..."); - String id = eth_newFilter(fr); - Object[] ret = eth_getFilterLogs(id); - eth_uninstallFilter(id); + String id = newFilter(fr.toFilterRequest()); + HexIndexParam idParam = new HexIndexParam(id); + Object[] ret = eth_getFilterLogs(idParam); + eth_uninstallFilter(idParam); return ret; } @@ -1027,21 +1080,27 @@ public void db_getHex() { @Override public String personal_newAccountWithSeed(String seed) { + if (seed == null) { + throw RskJsonRpcRequestException.invalidParamError("Seed is null"); + } return personalModule.newAccountWithSeed(seed); } @Override public String personal_newAccount(String passphrase) { + if (passphrase == null) { + throw RskJsonRpcRequestException.invalidParamError("Passphrase is null"); + } return personalModule.newAccount(passphrase); } @Override - public String personal_importRawKey(String key, String passphrase) { + public String personal_importRawKey(HexKeyParam key, String passphrase) { return personalModule.importRawKey(key, passphrase); } @Override - public String personal_dumpRawKey(String address) throws Exception { + public String personal_dumpRawKey(HexAddressParam address) throws Exception { return personalModule.dumpRawKey(address); } @@ -1051,29 +1110,29 @@ public String[] personal_listAccounts() { } @Override - public String personal_sendTransaction(CallArguments args, String passphrase) throws Exception { + public String personal_sendTransaction(CallArgumentsParam args, String passphrase) throws Exception { return personalModule.sendTransaction(args, passphrase); } @Override - public boolean personal_unlockAccount(String address, String passphrase, String duration) { + public boolean personal_unlockAccount(HexAddressParam address, String passphrase, HexDurationParam duration) { return personalModule.unlockAccount(address, passphrase, duration); } @Override - public boolean personal_lockAccount(String address) { + public boolean personal_lockAccount(HexAddressParam address) { return personalModule.lockAccount(address); } @Override - public String eth_estimateGas(CallArguments args) { + public String eth_estimateGas(CallArgumentsParam args) { return eth_estimateGas(args, null); } @Override - public String eth_estimateGas(CallArguments args, String bnOrId) { - if (StringUtils.isEmpty(bnOrId)) { - bnOrId = BlockTag.LATEST.getTag(); + public String eth_estimateGas(CallArgumentsParam args, @Nullable BlockIdentifierParam bnOrId) { + if (bnOrId == null) { + bnOrId = new BlockIdentifierParam(BlockTag.LATEST.getTag()); } return getEthModule().estimateGas(args, bnOrId); } diff --git a/rskj-core/src/main/java/org/ethereum/rpc/exception/RskJsonRpcRequestException.java b/rskj-core/src/main/java/org/ethereum/rpc/exception/RskJsonRpcRequestException.java index 44c8c63df82..0a4cc78e30f 100644 --- a/rskj-core/src/main/java/org/ethereum/rpc/exception/RskJsonRpcRequestException.java +++ b/rskj-core/src/main/java/org/ethereum/rpc/exception/RskJsonRpcRequestException.java @@ -61,5 +61,4 @@ public static RskJsonRpcRequestException stateNotFound(String message) { public static RskJsonRpcRequestException filterNotFound(String message) { return new RskJsonRpcRequestException(-32000, message); } - } diff --git a/rskj-core/src/main/java/org/ethereum/rpc/parameters/BlockHashParam.java b/rskj-core/src/main/java/org/ethereum/rpc/parameters/BlockHashParam.java new file mode 100644 index 00000000000..a2cfbf97967 --- /dev/null +++ b/rskj-core/src/main/java/org/ethereum/rpc/parameters/BlockHashParam.java @@ -0,0 +1,54 @@ +/* + * This file is part of RskJ + * Copyright (C) 2023 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.rpc.parameters; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; + +import java.io.IOException; + +@JsonDeserialize(using = BlockHashParam.Deserializer.class) +public class BlockHashParam extends HashParam32 { + + private static final String HASH_TYPE = "block hash"; + + public BlockHashParam(String hash) { + super(HASH_TYPE, hash); + } + + public static class Deserializer extends StdDeserializer { + + private static final long serialVersionUID = 8071595037666226210L; + + public Deserializer() { + this(null); + } + + public Deserializer(Class vc) { + super(vc); + } + + @Override + public BlockHashParam deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { + String hash = jp.getText(); + return new BlockHashParam(hash); + } + } +} diff --git a/rskj-core/src/main/java/org/ethereum/rpc/parameters/BlockIdentifierParam.java b/rskj-core/src/main/java/org/ethereum/rpc/parameters/BlockIdentifierParam.java new file mode 100644 index 00000000000..53d7bb3c1a4 --- /dev/null +++ b/rskj-core/src/main/java/org/ethereum/rpc/parameters/BlockIdentifierParam.java @@ -0,0 +1,68 @@ +/* + * This file is part of RskJ + * Copyright (C) 2018 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.rpc.parameters; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import org.ethereum.core.genesis.BlockTag; +import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.ethereum.util.Utils; + +import java.io.IOException; +import java.io.Serializable; + +@JsonDeserialize(using = BlockIdentifierParam.Deserializer.class) +public class BlockIdentifierParam implements Serializable { + private static final long serialVersionUID = 1L; + + private final String identifier; + + public BlockIdentifierParam(String identifier) { + if (identifier == null || identifier.isEmpty()) { + throw RskJsonRpcRequestException.invalidParamError("Invalid block identifier: empty or null."); + } + + if(BlockTag.fromString(identifier) == null + && !Utils.isDecimalString(identifier) + && !Utils.isHexadecimalString(identifier)) { + throw RskJsonRpcRequestException.invalidParamError("Invalid block identifier '" + identifier + "'"); + } + + this.identifier = identifier; + } + + public String getIdentifier() { + return identifier; + } + + public static class Deserializer extends StdDeserializer { + private static final long serialVersionUID = 1L; + + public Deserializer() { this(null); } + + public Deserializer(Class vc) { super(vc); } + + @Override + public BlockIdentifierParam deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { + String identifier = jp.getText(); + return new BlockIdentifierParam(identifier); + } + } +} diff --git a/rskj-core/src/main/java/org/ethereum/rpc/parameters/BlockRefParam.java b/rskj-core/src/main/java/org/ethereum/rpc/parameters/BlockRefParam.java new file mode 100644 index 00000000000..b47b89af84d --- /dev/null +++ b/rskj-core/src/main/java/org/ethereum/rpc/parameters/BlockRefParam.java @@ -0,0 +1,119 @@ +/* + * This file is part of RskJ + * Copyright (C) 2018 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.rpc.parameters; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.node.JsonNodeType; +import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.ethereum.util.Utils; + +import java.io.IOException; +import java.io.Serializable; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +@JsonDeserialize(using = BlockRefParam.Deserializer.class) +public class BlockRefParam implements Serializable { + private static final long serialVersionUID = 1L; + + private static final String REQUIRED_CANONICAL_KEY = "requireCanonical"; + private static final String BLOCK_HASH_KEY = "blockHash"; + private static final String BLOCK_NUMBER_KEY = "blockNumber"; + private static final List BLOCK_INPUT_KEYS_TO_VALIDATE = Arrays.asList(BLOCK_HASH_KEY, BLOCK_NUMBER_KEY); + private static final List IDENTIFIERS_TO_VALIDATE = Arrays.asList("earliest", "latest", "pending"); + + private String identifier; + private Map inputs; + + public BlockRefParam(String identifier) { + if(!IDENTIFIERS_TO_VALIDATE.contains(identifier) + && !Utils.isDecimalString(identifier) + && !Utils.isHexadecimalString(identifier)) { + throw RskJsonRpcRequestException.invalidParamError("Invalid block identifier '" + identifier + "'"); + } + + this.identifier = identifier; + } + + public BlockRefParam(Map inputs) { + if(inputs.keySet().stream().noneMatch(BLOCK_INPUT_KEYS_TO_VALIDATE::contains)) { + throw RskJsonRpcRequestException.invalidParamError("Invalid block input"); + } + + validateMapItems(inputs); + + this.inputs = inputs; + } + + private void validateMapItems(Map inputs) { + inputs.forEach((key, value) -> { + switch (key) { + case REQUIRED_CANONICAL_KEY: + if(!value.equalsIgnoreCase("true") && !value.equalsIgnoreCase("false")) { + throw RskJsonRpcRequestException.invalidParamError(String + .format("Invalid input: %s must be a String \"true\" or \"false\"", REQUIRED_CANONICAL_KEY)); + } + break; + case BLOCK_HASH_KEY: + new BlockHashParam(value); + break; + case BLOCK_NUMBER_KEY: + new HexNumberParam(value); + break; + } + }); + } + + public String getIdentifier() { + return identifier; + } + + public Map getInputs() { + return inputs; + } + + public static class Deserializer extends StdDeserializer { + private static final long serialVersionUID = 1L; + private final ObjectMapper mapper = new ObjectMapper(); + + public Deserializer() { this(null); } + + public Deserializer(Class vc) { super(vc); } + + @Override + public BlockRefParam deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { + JsonNode node = jp.getCodec().readTree(jp); + JsonNodeType nodeType = node.getNodeType(); + + if(nodeType == JsonNodeType.STRING) { + return new BlockRefParam(node.asText()); + } else if(nodeType == JsonNodeType.OBJECT) { + Map inputs = mapper.convertValue(node, Map.class); + return new BlockRefParam(inputs); + } else { + throw RskJsonRpcRequestException.invalidParamError("Invalid input"); + } + } + } +} diff --git a/rskj-core/src/main/java/org/ethereum/rpc/parameters/CallArgumentsParam.java b/rskj-core/src/main/java/org/ethereum/rpc/parameters/CallArgumentsParam.java new file mode 100644 index 00000000000..c7b40fee4a6 --- /dev/null +++ b/rskj-core/src/main/java/org/ethereum/rpc/parameters/CallArgumentsParam.java @@ -0,0 +1,144 @@ +/* + * This file is part of RskJ + * Copyright (C) 2018 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.rpc.parameters; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import org.ethereum.rpc.CallArguments; + +import java.io.IOException; + +@JsonDeserialize(using = CallArgumentsParam.Deserializer.class) +public class CallArgumentsParam { + + private final HexAddressParam from; + private final HexAddressParam to; + private final HexNumberParam gas; + private final HexNumberParam gasPrice; + private final HexNumberParam gasLimit; + private final HexNumberParam nonce; + private final HexNumberParam chainId; + private final HexNumberParam value; + private final HexDataParam data; + + public CallArgumentsParam(HexAddressParam from, HexAddressParam to, HexNumberParam gas, + HexNumberParam gasPrice, HexNumberParam gasLimit, HexNumberParam nonce, + HexNumberParam chainId, HexNumberParam value, HexDataParam data) { + this.from = from; + this.to = to; + this.gas = gas; + this.gasPrice = gasPrice; + this.gasLimit = gasLimit; + this.nonce = nonce; + this.chainId = chainId; + this.value = value; + this.data = data; + } + + public HexAddressParam getFrom() { + return from; + } + + public HexAddressParam getTo() { + return to; + } + + public HexNumberParam getGas() { + return gas; + } + + public HexNumberParam getGasPrice() { + return gasPrice; + } + + public HexNumberParam getGasLimit() { + return gasLimit; + } + + public HexNumberParam getNonce() { + return nonce; + } + + public HexNumberParam getChainId() { + return chainId; + } + + public HexNumberParam getValue() { + return value; + } + + public HexDataParam getData() { + return data; + } + + public CallArguments toCallArguments() { + + String caFrom = this.from == null ? null : this.from.getAddress().toJsonString(); + String caTo = this.to == null ? null : this.to.getAddress().toJsonString(); + String caGas = this.gas == null ? null : this.gas.getHexNumber(); + String caGasPrice = this.gasPrice == null ? null : this.gasPrice.getHexNumber(); + String caGasLimit = this.gasLimit == null ? null : this.gasLimit.getHexNumber(); + String caNonce = this.nonce == null ? null : this.nonce.getHexNumber(); + String caChainId = this.chainId == null ? null : this.chainId.getHexNumber(); + String caValue = this.value == null ? null : this.value.getHexNumber(); + String caData = this.data == null ? null : this.data.getAsHexString(); + + CallArguments callArguments = new CallArguments(); + callArguments.setFrom(caFrom); + callArguments.setTo(caTo); + callArguments.setGas(caGas); + callArguments.setGasPrice(caGasPrice); + callArguments.setGasLimit(caGasLimit); + callArguments.setNonce(caNonce); + callArguments.setChainId(caChainId); + callArguments.setValue(caValue); + callArguments.setData(caData); + + return callArguments; + } + + public static class Deserializer extends StdDeserializer { + private static final long serialVersionUID = 1L; + + public Deserializer() { this(null); } + + public Deserializer(Class vc) { super(vc); } + + @Override + public CallArgumentsParam deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { + JsonNode node = jp.getCodec().readTree(jp); + + BlockIdentifierParam fromBlock = node.has("fromBlock") ? new BlockIdentifierParam(node.get("fromBlock").asText()) : null; + + HexAddressParam from = node.has("from") ? new HexAddressParam(node.get("from").asText()) : null; + HexAddressParam to = node.has("to") ? new HexAddressParam(node.get("to").asText()) : null; + HexNumberParam gas = node.has("gas") ? new HexNumberParam(node.get("gas").asText()) : null; + HexNumberParam gasPrice = node.has("gasPrice") ? new HexNumberParam(node.get("gasPrice").asText()) : null; + HexNumberParam gasLimit = node.has("gasLimit") ? new HexNumberParam(node.get("gasLimit").asText()) : null; + HexNumberParam nonce = node.has("nonce") ? new HexNumberParam(node.get("nonce").asText()) : null; + HexNumberParam chainId = node.has("chainId") ? new HexNumberParam(node.get("chainId").asText()) : null; + HexNumberParam value = node.has("value") ? new HexNumberParam(node.get("value").asText()) : null; + HexDataParam data = node.has("data") ? new HexDataParam(node.get("data").asText()) : null; + + return new CallArgumentsParam(from, to, gas, gasPrice, gasLimit, nonce, chainId, value, data); + } + } +} diff --git a/rskj-core/src/main/java/org/ethereum/rpc/parameters/FilterRequestParam.java b/rskj-core/src/main/java/org/ethereum/rpc/parameters/FilterRequestParam.java new file mode 100644 index 00000000000..2042cc82d70 --- /dev/null +++ b/rskj-core/src/main/java/org/ethereum/rpc/parameters/FilterRequestParam.java @@ -0,0 +1,192 @@ +/* + * This file is part of RskJ + * Copyright (C) 2023 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.rpc.parameters; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import org.ethereum.rpc.FilterRequest; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +@JsonDeserialize(using = FilterRequestParam.Deserializer.class) +public class FilterRequestParam { + + private final BlockIdentifierParam fromBlock; + private final BlockIdentifierParam toBlock; + private final HexAddressParam[] address; + private final TopicParam[][] topics; + private final BlockHashParam blockHash; + + public FilterRequestParam(BlockIdentifierParam fromBlock, BlockIdentifierParam toBlock, HexAddressParam[] address, TopicParam[][] topics, BlockHashParam blockHash) { + this.fromBlock = fromBlock; + this.toBlock = toBlock; + this.address = address; + this.topics = topics; + this.blockHash = blockHash; + } + + public BlockIdentifierParam getFromBlock() { + return fromBlock; + } + + public BlockIdentifierParam getToBlock() { + return toBlock; + } + + public HexAddressParam[] getAddress() { + return address; + } + + public TopicParam[][] getTopics() { + return topics; + } + + public BlockHashParam getBlockHash() { + return blockHash; + } + + public FilterRequest toFilterRequest() { + String fb = this.fromBlock == null ? null : this.fromBlock.getIdentifier(); + String tb = this.toBlock == null ? null : this.toBlock.getIdentifier(); + Object ad = this.address == null ? null : this.parseAddressArray(); + String bh = this.blockHash == null ? null : this.blockHash.getHash().toJsonString(); + Object[] tp = this.topics == null ? null : this.parseTopicArrayToObjectArray(); + + FilterRequest filterRequest = new FilterRequest(); + filterRequest.setAddress(ad); + filterRequest.setBlockHash(bh); + filterRequest.setFromBlock(fb); + filterRequest.setToBlock(tb); + filterRequest.setTopics(tp); + + return filterRequest; + } + + private Object parseAddressArray() { + if (this.address == null) { + return null; + } + if (this.address.length == 1) { + return this.address[0].getAddress().toJsonString(); + } else { + List arrayList = new ArrayList<>(); + for (int i = 0; i < this.address.length; i++) { + arrayList.add(this.address[i].getAddress().toJsonString()); + } + return arrayList; + } + } + + private Object[] parseTopicArrayToObjectArray() { + if (this.topics == null) { + return new Object[0]; + } + Object[] result = new Object[this.topics.length]; + for (int i = 0; i < this.topics.length; i++) { + TopicParam[] topicArray = this.topics[i]; + if (topicArray.length == 1) { + result[i] = topicArray[0] != null ? topicArray[0].getHash().toJsonString() : null; + } else { + List arrayList = new ArrayList<>(); + for (TopicParam topicParam : topicArray) { + arrayList.add(topicParam != null ? topicParam.getHash().toJsonString() : null); + } + result[i] = arrayList; + } + } + return result; + } + + public static class Deserializer extends StdDeserializer { + private static final long serialVersionUID = -72304400913233552L; + + public Deserializer() { + this(null); + } + + public Deserializer(Class vc) { + super(vc); + } + + @Override + public FilterRequestParam deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { + JsonNode node = jp.getCodec().readTree(jp); + BlockIdentifierParam fromBlock = node.has("fromBlock") ? new BlockIdentifierParam(node.get("fromBlock").asText()) : null; + BlockIdentifierParam toBlock = node.has("toBlock") ? new BlockIdentifierParam(node.get("toBlock").asText()) : null; + HexAddressParam[] address = node.has("address") ? getAddressParam(node.get("address")) : null; + BlockHashParam blockHash = node.has("blockHash") ? new BlockHashParam(node.get("blockHash").asText()) : null; + TopicParam[][] topics = node.has("topics") ? getTopicArray(node.get("topics")) : null; + + return new FilterRequestParam(fromBlock, toBlock, address, topics, blockHash); + } + + private HexAddressParam[] getAddressParam(JsonNode node) { + if (node == null || node.isNull()) { + return null; + } + + if (node.isArray()) { + HexAddressParam[] addresses = new HexAddressParam[node.size()]; + for (int i = 0; i < node.size(); i++) { + JsonNode subNode = node.get(i); + addresses[i] = new HexAddressParam(subNode.asText()); + } + return addresses; + } + return new HexAddressParam[]{new HexAddressParam(node.asText())}; + } + + private TopicParam[][] getTopicArray(JsonNode node) { + if (node == null || node.isNull()) { + return new TopicParam[0][0]; + } + if (node.isArray()) { + TopicParam[][] topics = new TopicParam[node.size()][]; + for (int i = 0; i < node.size(); i++) { + JsonNode subNode = node.get(i); + if (subNode.isArray()) { + TopicParam[] topicParams = getTopics(subNode); + topics[i] = topicParams; + } else { + TopicParam subNodeTopic = subNode.isNull() ? null : new TopicParam(subNode.asText()); + topics[i] = new TopicParam[]{subNodeTopic}; + } + } + return topics; + } + TopicParam topicParam = new TopicParam(node.asText()); + return new TopicParam[][]{new TopicParam[]{topicParam}}; + } + + private TopicParam[] getTopics(JsonNode jsonNode) { + TopicParam[] topicParams = new TopicParam[jsonNode.size()]; + for (int j = 0; j < jsonNode.size(); j++) { + JsonNode subNode = jsonNode.get(j); + topicParams[j] = subNode.isNull() ? null : new TopicParam(subNode.asText()); + } + return topicParams; + } + + } + +} diff --git a/rskj-core/src/main/java/org/ethereum/rpc/parameters/HashParam32.java b/rskj-core/src/main/java/org/ethereum/rpc/parameters/HashParam32.java new file mode 100644 index 00000000000..4ff85034314 --- /dev/null +++ b/rskj-core/src/main/java/org/ethereum/rpc/parameters/HashParam32.java @@ -0,0 +1,53 @@ +/* + * This file is part of RskJ + * Copyright (C) 2023 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.rpc.parameters; + +import co.rsk.crypto.Keccak256; +import co.rsk.util.HexUtils; +import org.ethereum.rpc.exception.RskJsonRpcRequestException; + +import static co.rsk.util.HexUtils.stringHexToByteArray; + +public abstract class HashParam32 { + private static final int HASH_BYTE_LENGTH = 32; + private final Keccak256 hash; + + HashParam32(String hashType, String hash) { + if (hash == null || hash.isEmpty()) { + throw RskJsonRpcRequestException.invalidParamError("Invalid " + hashType + ": empty or null."); + } + + byte[] hashBytes; + + try { + hashBytes = HexUtils.stringHexToByteArray(hash); + } catch (Exception e) { + throw RskJsonRpcRequestException.invalidParamError("Invalid " + hashType + " format: invalid hex value", e); + } + + if (HASH_BYTE_LENGTH != hashBytes.length) { + throw RskJsonRpcRequestException.invalidParamError("Invalid " + hashType + ": incorrect length."); + } + + this.hash = new Keccak256(stringHexToByteArray(hash)); + } + + public Keccak256 getHash() { + return hash; + } +} diff --git a/rskj-core/src/main/java/org/ethereum/rpc/parameters/HexAddressParam.java b/rskj-core/src/main/java/org/ethereum/rpc/parameters/HexAddressParam.java new file mode 100644 index 00000000000..a8c939cc7e5 --- /dev/null +++ b/rskj-core/src/main/java/org/ethereum/rpc/parameters/HexAddressParam.java @@ -0,0 +1,65 @@ +/* + * This file is part of RskJ + * Copyright (C) 2018 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.rpc.parameters; + +import co.rsk.core.RskAddress; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import org.ethereum.rpc.exception.RskJsonRpcRequestException; + +import java.io.IOException; +import java.io.Serializable; + +@JsonDeserialize(using = HexAddressParam.Deserializer.class) +public class HexAddressParam implements Serializable { + private static final long serialVersionUID = 1L; + + private transient final RskAddress address; + + public HexAddressParam(String hexAddress) { + if (hexAddress == null || hexAddress.isEmpty()) { + throw RskJsonRpcRequestException.invalidParamError("Invalid address: empty or null."); + } + + try { + this.address = new RskAddress(hexAddress); + } catch (Exception e) { + throw RskJsonRpcRequestException.invalidParamError("Invalid address format: invalid hex value.", e); + } + } + + public RskAddress getAddress() { + return address; + } + + public static class Deserializer extends StdDeserializer { + private static final long serialVersionUID = 1L; + + public Deserializer() { this(null); } + + public Deserializer(Class vc) { super(vc); } + + @Override + public HexAddressParam deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { + String hexAddress = jp.getText(); + return new HexAddressParam(hexAddress); + } + } +} diff --git a/rskj-core/src/main/java/org/ethereum/rpc/parameters/HexDataParam.java b/rskj-core/src/main/java/org/ethereum/rpc/parameters/HexDataParam.java new file mode 100644 index 00000000000..940a5f2f0d1 --- /dev/null +++ b/rskj-core/src/main/java/org/ethereum/rpc/parameters/HexDataParam.java @@ -0,0 +1,66 @@ +/* + * This file is part of RskJ + * Copyright (C) 2018 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.rpc.parameters; + +import co.rsk.util.HexUtils; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.ethereum.util.ByteUtil; + +import java.io.IOException; +import java.io.Serializable; + +@JsonDeserialize(using = HexDataParam.Deserializer.class) +public class HexDataParam implements Serializable { + private static final long serialVersionUID = 1L; + + private final byte[] rawDataBytes; + + public HexDataParam(String rawData){ + try { + this.rawDataBytes = HexUtils.stringHexToByteArray(rawData); + } catch (Exception e) { + throw RskJsonRpcRequestException.invalidParamError("Invalid data format: invalid hex value.", e); + } + } + + public byte[] getRawDataBytes() { + return rawDataBytes; + } + + public String getAsHexString() { + return "0x" + ByteUtil.toHexString(rawDataBytes); + } + + public static class Deserializer extends StdDeserializer { + private static final long serialVersionUID = 1L; + + public Deserializer() { this(null); } + + public Deserializer(Class vc) { super(vc); } + + @Override + public HexDataParam deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { + String hexRawData = jp.getText(); + return new HexDataParam(hexRawData); + } + } +} diff --git a/rskj-core/src/main/java/org/ethereum/rpc/parameters/HexDurationParam.java b/rskj-core/src/main/java/org/ethereum/rpc/parameters/HexDurationParam.java new file mode 100644 index 00000000000..aae2edb8395 --- /dev/null +++ b/rskj-core/src/main/java/org/ethereum/rpc/parameters/HexDurationParam.java @@ -0,0 +1,63 @@ +/* + * This file is part of RskJ + * Copyright (C) 2018 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.rpc.parameters; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import org.ethereum.rpc.exception.RskJsonRpcRequestException; + +import java.io.IOException; + +@JsonDeserialize(using = HexDurationParam.Deserializer.class) +public class HexDurationParam extends HexStringParam { + private final Long duration; + + public HexDurationParam(String hexDurationStr) { + super(hexDurationStr); + + if (hexDurationStr.isEmpty()) { + this.duration = null; + } else { + try { + this.duration = Long.parseLong(hexDurationStr.substring(2), 16); + } catch (NumberFormatException e) { + throw RskJsonRpcRequestException.invalidParamError("Invalid duration param: value must be a valid hex number.", e); + } + } + } + + public Long getDuration() { + return duration; + } + + public static class Deserializer extends StdDeserializer { + private static final long serialVersionUID = 1L; + + public Deserializer() { this(null); } + + public Deserializer(Class vc) { super(vc); } + + @Override + public HexDurationParam deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { + String hexDurationStr = jp.getText(); + return new HexDurationParam(hexDurationStr); + } + } +} diff --git a/rskj-core/src/main/java/org/ethereum/rpc/parameters/HexIndexParam.java b/rskj-core/src/main/java/org/ethereum/rpc/parameters/HexIndexParam.java new file mode 100644 index 00000000000..51376c1b59e --- /dev/null +++ b/rskj-core/src/main/java/org/ethereum/rpc/parameters/HexIndexParam.java @@ -0,0 +1,67 @@ +/* + * This file is part of RskJ + * Copyright (C) 2023 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.rpc.parameters; + +import co.rsk.util.HexUtils; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import org.ethereum.rpc.exception.RskJsonRpcRequestException; + +import java.io.IOException; + +@JsonDeserialize(using = HexIndexParam.Deserializer.class) +public class HexIndexParam extends HexStringParam { + private final Integer index; + + public HexIndexParam(String indexString) { + super(indexString); + + String preResult = HexUtils.removeHexPrefix(indexString); + try { + this.index = Integer.parseInt(preResult, 16); + } catch (NumberFormatException e) { + throw RskJsonRpcRequestException.invalidParamError("Invalid index param: value must be a valid hex number.", e); + } + } + + public Integer getIndex() { + return index; + } + + public static class Deserializer extends StdDeserializer { + + private static final long serialVersionUID = 1L; + + public Deserializer() { + this(null); + } + + public Deserializer(Class vc) { + super(vc); + } + + @Override + public HexIndexParam deserialize(JsonParser jp, DeserializationContext ctxt) + throws IOException { + String indexString = jp.getText(); + return new HexIndexParam(indexString); + } + } +} diff --git a/rskj-core/src/main/java/org/ethereum/rpc/parameters/HexKeyParam.java b/rskj-core/src/main/java/org/ethereum/rpc/parameters/HexKeyParam.java new file mode 100644 index 00000000000..48d86c83ad4 --- /dev/null +++ b/rskj-core/src/main/java/org/ethereum/rpc/parameters/HexKeyParam.java @@ -0,0 +1,62 @@ +/* + * This file is part of RskJ + * Copyright (C) 2018 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.rpc.parameters; + +import co.rsk.util.HexUtils; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import org.ethereum.rpc.exception.RskJsonRpcRequestException; + +import java.io.IOException; +import java.io.Serializable; + +@JsonDeserialize(using = HexKeyParam.Deserializer.class) +public class HexKeyParam implements Serializable { + private static final long serialVersionUID = 1L; + + private final String hexKey; + + public HexKeyParam(String hexKey) { + boolean hasPrefix = HexUtils.hasHexPrefix(hexKey); + if (!HexUtils.isHex(hexKey.toLowerCase(), hasPrefix ? 2 : 0)) { + throw RskJsonRpcRequestException.invalidParamError("Invalid param " + hexKey + ": value must be a valid hex."); + } + + this.hexKey = hexKey; + } + + public String getHexKey() { + return hexKey; + } + + public static class Deserializer extends StdDeserializer { + private static final long serialVersionUID = 1L; + + public Deserializer() { this(null); } + + public Deserializer(Class vc) { super(vc); } + + @Override + public HexKeyParam deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { + String hexKey = jp.getText(); + return new HexKeyParam(hexKey); + } + } +} diff --git a/rskj-core/src/main/java/org/ethereum/rpc/parameters/HexNumberParam.java b/rskj-core/src/main/java/org/ethereum/rpc/parameters/HexNumberParam.java new file mode 100644 index 00000000000..aca8eeb28ef --- /dev/null +++ b/rskj-core/src/main/java/org/ethereum/rpc/parameters/HexNumberParam.java @@ -0,0 +1,67 @@ +/* + * This file is part of RskJ + * Copyright (C) 2018 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.rpc.parameters; + +import co.rsk.util.HexUtils; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import org.ethereum.rpc.exception.RskJsonRpcRequestException; + +import java.io.IOException; +import java.io.Serializable; +import java.math.BigInteger; + +@JsonDeserialize(using = HexNumberParam.Deserializer.class) +public class HexNumberParam implements Serializable { + private static final long serialVersionUID = 1L; + + private final String hexNumber; + + public HexNumberParam(String hexNumber) { + boolean hasPrefix = HexUtils.hasHexPrefix(hexNumber); + if (!HexUtils.isHex(hexNumber.toLowerCase(), hasPrefix ? 2 : 0)) { + try { + new BigInteger(hexNumber); + } catch(Exception e) { + throw RskJsonRpcRequestException.invalidParamError("Invalid param " + hexNumber + ": value must be a valid hex or string number.", e); + } + } + + this.hexNumber = hexNumber; + } + + public String getHexNumber() { + return this.hexNumber; + } + + public static class Deserializer extends StdDeserializer { + private static final long serialVersionUID = 1L; + + public Deserializer() { this(null); } + + public Deserializer(Class vc) { super(vc); } + + @Override + public HexNumberParam deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { + String hexNumber = jp.getText(); + return new HexNumberParam(hexNumber); + } + } +} diff --git a/rskj-core/src/main/java/org/ethereum/rpc/parameters/HexStringParam.java b/rskj-core/src/main/java/org/ethereum/rpc/parameters/HexStringParam.java new file mode 100644 index 00000000000..c36d838ed86 --- /dev/null +++ b/rskj-core/src/main/java/org/ethereum/rpc/parameters/HexStringParam.java @@ -0,0 +1,33 @@ +/* + * This file is part of RskJ + * Copyright (C) 2018 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.rpc.parameters; + +import co.rsk.util.HexUtils; +import org.ethereum.rpc.exception.RskJsonRpcRequestException; + +public abstract class HexStringParam { + HexStringParam(String hexString) { + if(hexString.isEmpty()) { + return; + } + + if (!HexUtils.hasHexPrefix(hexString) || !HexUtils.isHex(hexString,2)) { + throw RskJsonRpcRequestException.invalidParamError(String.format("Invalid argument \"%s\": param should be a hex value string.", hexString)); + } + } +} diff --git a/rskj-core/src/main/java/org/ethereum/rpc/parameters/TopicParam.java b/rskj-core/src/main/java/org/ethereum/rpc/parameters/TopicParam.java new file mode 100644 index 00000000000..1c643c97a78 --- /dev/null +++ b/rskj-core/src/main/java/org/ethereum/rpc/parameters/TopicParam.java @@ -0,0 +1,26 @@ +/* + * This file is part of RskJ + * Copyright (C) 2023 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.rpc.parameters; + +public class TopicParam extends HashParam32 { + private static final String HASH_TYPE = "topic"; + + public TopicParam(String hash) { + super(HASH_TYPE, hash); + } +} diff --git a/rskj-core/src/main/java/org/ethereum/rpc/parameters/TxHashParam.java b/rskj-core/src/main/java/org/ethereum/rpc/parameters/TxHashParam.java new file mode 100644 index 00000000000..b1c9b3674b7 --- /dev/null +++ b/rskj-core/src/main/java/org/ethereum/rpc/parameters/TxHashParam.java @@ -0,0 +1,53 @@ +/* + * This file is part of RskJ + * Copyright (C) 2023 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.rpc.parameters; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; + +import java.io.IOException; + +@JsonDeserialize(using = TxHashParam.Deserializer.class) +public class TxHashParam extends HashParam32 { + private static final String HASH_TYPE = "transaction hash"; + public TxHashParam(String hash) { + super(HASH_TYPE, hash); + } + + public static class Deserializer extends StdDeserializer { + + private static final long serialVersionUID = 2669501504172497269L; + + public Deserializer() { + this(null); + } + + public Deserializer(Class vc) { + super(vc); + } + + @Override + public TxHashParam deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { + String hash = jp.getText(); + return new TxHashParam(hash); + } + } +} + diff --git a/rskj-core/src/test/java/co/rsk/mine/TransactionModuleTest.java b/rskj-core/src/test/java/co/rsk/mine/TransactionModuleTest.java index c7e68668801..c765662032f 100644 --- a/rskj-core/src/test/java/co/rsk/mine/TransactionModuleTest.java +++ b/rskj-core/src/test/java/co/rsk/mine/TransactionModuleTest.java @@ -67,9 +67,11 @@ import org.ethereum.rpc.Simples.SimpleConfigCapabilities; import org.ethereum.rpc.Web3Impl; import org.ethereum.rpc.Web3Mocks; +import org.ethereum.rpc.parameters.HexDataParam; import org.ethereum.sync.SyncPool; import org.ethereum.util.BuildInfo; import org.ethereum.util.ByteUtil; +import org.ethereum.util.TransactionFactoryHelper; import org.ethereum.vm.GasCost; import org.ethereum.vm.PrecompiledContracts; import org.ethereum.vm.program.invoke.ProgramInvokeFactoryImpl; @@ -306,7 +308,7 @@ public int checkEstimateGas(int method, long expectedValue, long gasLimit, Assertions.assertNotEquals(expectedValue, gasLimit); CallArguments args = getContractCallTransactionParameters(method, gasLimit, srcAddr, contractAddress, repository); - String gas = web3.eth_estimateGas(args, null); + String gas = web3.eth_estimateGas(TransactionFactoryHelper.toCallArgumentsParam(args), null); byte[] gasReturnedBytes = Hex.decode(gas.substring("0x".length())); BigInteger gasReturned = BigIntegers.fromUnsignedByteArray(gasReturnedBytes); int gasReturnedInt = gasReturned.intValueExact(); @@ -332,7 +334,7 @@ private String sendRawTransaction(Web3Impl web3) { String rawData = ByteUtil.toHexString(tx.getEncoded()); - return web3.eth_sendRawTransaction(rawData); + return web3.eth_sendRawTransaction(new HexDataParam(rawData)); } private Transaction getTransactionFromBlockWhichWasSend(BlockChainImpl blockchain, String tx) { @@ -350,13 +352,13 @@ private Transaction getTransactionFromBlockWhichWasSend(BlockChainImpl blockchai private String sendContractCreationTransaction(RskAddress srcaddr, Web3Impl web3, RepositorySnapshot repository) { CallArguments args = getContractCreationTransactionParameters(srcaddr, web3, repository); - return web3.eth_sendTransaction(args); + return web3.eth_sendTransaction(TransactionFactoryHelper.toCallArgumentsParam(args)); } private String sendTransaction(Web3Impl web3, RepositorySnapshot repository) { CallArguments args = getTransactionParameters(web3, repository); - return web3.eth_sendTransaction(args); + return web3.eth_sendTransaction(TransactionFactoryHelper.toCallArgumentsParam(args)); } //////////////////////////////////////////////// diff --git a/rskj-core/src/test/java/co/rsk/rpc/modules/eth/EthModuleDSLTest.java b/rskj-core/src/test/java/co/rsk/rpc/modules/eth/EthModuleDSLTest.java index 79fea1f08bb..cad63aba4f2 100644 --- a/rskj-core/src/test/java/co/rsk/rpc/modules/eth/EthModuleDSLTest.java +++ b/rskj-core/src/test/java/co/rsk/rpc/modules/eth/EthModuleDSLTest.java @@ -26,7 +26,10 @@ import org.ethereum.core.TransactionReceipt; import org.ethereum.rpc.CallArguments; import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.ethereum.rpc.parameters.BlockIdentifierParam; +import org.ethereum.rpc.parameters.CallArgumentsParam; import org.ethereum.util.EthModuleTestUtils; +import org.ethereum.util.TransactionFactoryHelper; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.junit.jupiter.api.Assertions; @@ -62,15 +65,17 @@ void testCall_getRevertReason() throws FileNotFoundException, DslProcessorExcept args.setValue("0"); args.setNonce("1"); args.setGas("10000000"); + CallArgumentsParam callArgumentsParam = TransactionFactoryHelper.toCallArgumentsParam(args); + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam("0x2"); try { - eth.call(args, "0x2"); + eth.call(callArgumentsParam, blockIdentifierParam); fail(); } catch (RskJsonRpcRequestException e) { MatcherAssert.assertThat(e.getMessage(), Matchers.containsString("Negative value.")); } args.setData("0xd96a094a0000000000000000000000000000000000000000000000000000000000000001"); // call to contract with param value = 1 - final String call = eth.call(args, "0x2"); + final String call = eth.call(TransactionFactoryHelper.toCallArgumentsParam(args), new BlockIdentifierParam("0x2")); assertEquals("0x", call); } } diff --git a/rskj-core/src/test/java/co/rsk/rpc/modules/eth/EthModuleGasEstimationDSLTest.java b/rskj-core/src/test/java/co/rsk/rpc/modules/eth/EthModuleGasEstimationDSLTest.java index d5cc63fc134..751ace983bd 100644 --- a/rskj-core/src/test/java/co/rsk/rpc/modules/eth/EthModuleGasEstimationDSLTest.java +++ b/rskj-core/src/test/java/co/rsk/rpc/modules/eth/EthModuleGasEstimationDSLTest.java @@ -31,8 +31,10 @@ import org.ethereum.core.genesis.BlockTag; import org.ethereum.crypto.HashUtil; import org.ethereum.rpc.CallArguments; +import org.ethereum.rpc.parameters.BlockIdentifierParam; import org.ethereum.util.ByteUtil; import org.ethereum.util.EthModuleTestUtils; +import org.ethereum.util.TransactionFactoryHelper; import org.ethereum.vm.GasCost; import org.ethereum.vm.LogInfo; import org.ethereum.vm.program.InternalTransaction; @@ -289,7 +291,7 @@ void estimateGas_gasCap() throws FileNotFoundException, DslProcessorException { callArguments.setGas(HexUtils.toQuantityJsonHex(gasEstimationCap + 1_000_000_000)); // exceeding the gas cap callArguments.setData("0x31fe52e8"); // call outOfGas() - String estimatedGas = eth.estimateGas(callArguments, BlockTag.LATEST.getTag()); + String estimatedGas = eth.estimateGas(TransactionFactoryHelper.toCallArgumentsParam(callArguments), new BlockIdentifierParam(BlockTag.LATEST.getTag())); assertEquals("0x67c280", estimatedGas); assertEquals(gasEstimationCap, Long.decode(estimatedGas).longValue()); @@ -786,7 +788,7 @@ public boolean runWithArgumentsAndBlock(EthModuleTestUtils.EthModuleGasEstimatio } private long estimateGas(EthModuleTestUtils.EthModuleGasEstimation eth, CallArguments args, String bnOrId) { - return Long.parseLong(eth.estimateGas(args, bnOrId).substring("0x".length()), 16); + return Long.parseLong(eth.estimateGas(TransactionFactoryHelper.toCallArgumentsParam(args), new BlockIdentifierParam(bnOrId)).substring("0x".length()), 16); } // todo this is duplicated code, should be extracted into a test util diff --git a/rskj-core/src/test/java/co/rsk/rpc/modules/eth/EthModuleTest.java b/rskj-core/src/test/java/co/rsk/rpc/modules/eth/EthModuleTest.java index 86713193d0d..e2e030935a0 100644 --- a/rskj-core/src/test/java/co/rsk/rpc/modules/eth/EthModuleTest.java +++ b/rskj-core/src/test/java/co/rsk/rpc/modules/eth/EthModuleTest.java @@ -36,6 +36,10 @@ import org.ethereum.datasource.HashMapDB; import org.ethereum.rpc.CallArguments; import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.ethereum.rpc.parameters.BlockIdentifierParam; +import org.ethereum.rpc.parameters.CallArgumentsParam; +import org.ethereum.rpc.parameters.HexAddressParam; +import org.ethereum.rpc.parameters.HexDataParam; import org.ethereum.util.ByteUtil; import org.ethereum.util.TransactionFactoryHelper; import org.ethereum.vm.program.ProgramResult; @@ -43,18 +47,20 @@ import org.hamcrest.Matchers; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; class EthModuleTest { + public static final String TEST_DATA = "0x603d80600c6000396000f3007c01000000000000000000000000000000000000000000000000000000006000350463c6888fa18114602d57005b6007600435028060005260206000f3"; + private final TestSystemProperties config = new TestSystemProperties(); - private SignatureCache signatureCache = new BlockTxSignatureCache(new ReceivedTxSignatureCache()); + private final SignatureCache signatureCache = new BlockTxSignatureCache(new ReceivedTxSignatureCache()); @Test void callSmokeTest() { @@ -91,7 +97,7 @@ void callSmokeTest() { config.getCallGasCap()); String expectedResult = HexUtils.toUnformattedJsonHex(hReturn); - String actualResult = eth.call(args, "latest"); + String actualResult = eth.call(TransactionFactoryHelper.toCallArgumentsParam(args), new BlockIdentifierParam("latest")); assertEquals(expectedResult, actualResult); } @@ -131,7 +137,7 @@ void callWithoutReturn() { config.getCallGasCap()); String expectedResult = HexUtils.toUnformattedJsonHex(hReturn); - String actualResult = eth.call(args, "latest"); + String actualResult = eth.call(TransactionFactoryHelper.toCallArgumentsParam(args), new BlockIdentifierParam("latest")); assertEquals(expectedResult, actualResult); } @@ -176,7 +182,7 @@ void test_revertedTransaction() { config.getCallGasCap()); try { - eth.call(args, "latest"); + eth.call(TransactionFactoryHelper.toCallArgumentsParam(args), new BlockIdentifierParam("latest")); } catch (RskJsonRpcRequestException e) { assertThat(e.getMessage(), Matchers.containsString("deposit too big")); } @@ -207,7 +213,7 @@ void sendTransactionWithGasLimitTest() { EthModuleTransactionBase ethModuleTransaction = new EthModuleTransactionBase(constants, wallet, transactionPool, transactionGateway); // Hash of the actual transaction builded inside the sendTransaction - String txResult = ethModuleTransaction.sendTransaction(args); + String txResult = ethModuleTransaction.sendTransaction(TransactionFactoryHelper.toCallArgumentsParam(args)); assertEquals(txExpectedResult, txResult); } @@ -235,7 +241,8 @@ void sendTransactionThrowsErrorOnChainIdValidationTest() { EthModuleTransactionBase ethModuleTransaction = new EthModuleTransactionBase(constants, wallet, transactionPool, transactionGateway); - Assertions.assertThrows(RskJsonRpcRequestException.class, () -> ethModuleTransaction.sendTransaction(args)); + CallArgumentsParam callArgumentsParam = TransactionFactoryHelper.toCallArgumentsParam(args); + Assertions.assertThrows(RskJsonRpcRequestException.class, () -> ethModuleTransaction.sendTransaction(callArgumentsParam)); } @Test @@ -264,7 +271,8 @@ void sendRawTransactionThrowsErrorOnChainIdValidationTest() { EthModuleTransactionBase ethModuleTransaction = new EthModuleTransactionBase(constants, wallet, transactionPool, transactionGateway); String rawData = ByteUtil.toHexString(tx.getEncoded()); - Assertions.assertThrows(RskJsonRpcRequestException.class, () -> ethModuleTransaction.sendRawTransaction(rawData)); + HexDataParam hexDataParam = new HexDataParam(rawData); + Assertions.assertThrows(RskJsonRpcRequestException.class, () -> ethModuleTransaction.sendRawTransaction(hexDataParam)); } @Test @@ -281,12 +289,12 @@ void sendTransaction_invalidSenderAccount_throwsRskJsonRpcRequestException() { EthModuleTransactionBase ethModuleTransaction = new EthModuleTransactionBase(constants, wallet, transactionPoolMock, transactionGatewayMock); + CallArgumentsParam callArgumentsParam = TransactionFactoryHelper.toCallArgumentsParam(argsMock); // Then try { - ethModuleTransaction.sendTransaction(argsMock); + ethModuleTransaction.sendTransaction(callArgumentsParam); fail("RskJsonRpcRequestException should be thrown"); } catch (RskJsonRpcRequestException ex) { - verify(argsMock, times(2)).getFrom(); assertEquals("Could not find account for address: " + addressFrom.toJsonString(), ex.getMessage()); } } @@ -321,7 +329,8 @@ void getCode() { config.getCallGasCap() ); - String addr = eth.getCode(TestUtils.generateAddress("addr").toHexString(), "pending"); + HexAddressParam addressParam = new HexAddressParam(TestUtils.generateAddress("addr").toHexString()); + String addr = eth.getCode(addressParam, "pending"); MatcherAssert.assertThat(Hex.decode(addr.substring("0x".length())), is(expectedCode)); } @@ -343,4 +352,383 @@ void chainId() { ); assertThat(eth.chainId(), is("0x21")); } + + @Test + void whenExecuteCallWithDataParameter_callExecutorWithData() { + CallArguments args = new CallArguments(); + args.setData(TEST_DATA); + ExecutionBlockRetriever.Result blockResult = mock(ExecutionBlockRetriever.Result.class); + Block block = mock(Block.class); + ExecutionBlockRetriever retriever = mock(ExecutionBlockRetriever.class); + when(retriever.retrieveExecutionBlock("latest")) + .thenReturn(blockResult); + when(blockResult.getBlock()).thenReturn(block); + + byte[] hReturn = HexUtils.stringToByteArray("hello"); + ProgramResult executorResult = mock(ProgramResult.class); + when(executorResult.getHReturn()) + .thenReturn(hReturn); + + ReversibleTransactionExecutor executor = mock(ReversibleTransactionExecutor.class); + when(executor.executeTransaction(eq(blockResult.getBlock()), any(), any(), any(), any(), any(), any(), any())) + .thenReturn(executorResult); + + EthModule eth = new EthModule( + null, + anyByte(), + null, + null, + executor, + retriever, + null, + null, + null, + new BridgeSupportFactory( + null, null, null, signatureCache), + config.getGasEstimationCap(), + config.getCallGasCap()); + + CallArgumentsParam callArgumentsParam = TransactionFactoryHelper.toCallArgumentsParam(args); + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam("latest"); + + eth.call(callArgumentsParam, blockIdentifierParam); + + ArgumentCaptor dataCaptor = ArgumentCaptor.forClass(byte[].class); + verify(executor, times(1)) + .executeTransaction(eq(blockResult.getBlock()), any(), any(), any(), any(), any(), dataCaptor.capture(), any()); + assertArrayEquals(HexUtils.strHexOrStrNumberToByteArray(args.getData()), dataCaptor.getValue()); + } + + @Test + void whenExecuteCallWithInputParameter_callExecutorWithInput() { + CallArguments args = new CallArguments(); + args.setInput(TEST_DATA); + ExecutionBlockRetriever.Result blockResult = mock(ExecutionBlockRetriever.Result.class); + Block block = mock(Block.class); + ExecutionBlockRetriever retriever = mock(ExecutionBlockRetriever.class); + when(retriever.retrieveExecutionBlock("latest")) + .thenReturn(blockResult); + when(blockResult.getBlock()).thenReturn(block); + + byte[] hReturn = HexUtils.stringToByteArray("hello"); + ProgramResult executorResult = mock(ProgramResult.class); + when(executorResult.getHReturn()) + .thenReturn(hReturn); + + ReversibleTransactionExecutor executor = mock(ReversibleTransactionExecutor.class); + when(executor.executeTransaction(eq(blockResult.getBlock()), any(), any(), any(), any(), any(), any(), any())) + .thenReturn(executorResult); + + EthModule eth = new EthModule( + null, + anyByte(), + null, + null, + executor, + retriever, + null, + null, + null, + new BridgeSupportFactory( + null, null, null, signatureCache), + config.getGasEstimationCap(), + config.getCallGasCap()); + + CallArgumentsParam callArgumentsParam = TransactionFactoryHelper.toCallArgumentsParam(args); + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam("latest"); + + eth.call(callArgumentsParam, blockIdentifierParam); + + ArgumentCaptor dataCaptor = ArgumentCaptor.forClass(byte[].class); + verify(executor, times(1)) + .executeTransaction(eq(blockResult.getBlock()), any(), any(), any(), any(), any(), dataCaptor.capture(), any()); + assertArrayEquals(HexUtils.strHexOrStrNumberToByteArray(args.getInput()), dataCaptor.getValue()); + } + + @Test + void whenExecuteCallWithInputAndDataParameters_callExecutorWithInput() { + CallArguments args = new CallArguments(); + args.setData(TEST_DATA); + args.setInput(TEST_DATA); + ExecutionBlockRetriever.Result blockResult = mock(ExecutionBlockRetriever.Result.class); + Block block = mock(Block.class); + ExecutionBlockRetriever retriever = mock(ExecutionBlockRetriever.class); + when(retriever.retrieveExecutionBlock("latest")) + .thenReturn(blockResult); + when(blockResult.getBlock()).thenReturn(block); + + byte[] hReturn = HexUtils.stringToByteArray("hello"); + ProgramResult executorResult = mock(ProgramResult.class); + when(executorResult.getHReturn()) + .thenReturn(hReturn); + + ReversibleTransactionExecutor executor = mock(ReversibleTransactionExecutor.class); + when(executor.executeTransaction(eq(blockResult.getBlock()), any(), any(), any(), any(), any(), any(), any())) + .thenReturn(executorResult); + + EthModule eth = new EthModule( + null, + anyByte(), + null, + null, + executor, + retriever, + null, + null, + null, + new BridgeSupportFactory( + null, null, null, signatureCache), + config.getGasEstimationCap(), + config.getCallGasCap()); + + + CallArgumentsParam callArgumentsParam = TransactionFactoryHelper.toCallArgumentsParam(args); + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam("latest"); + + eth.call(callArgumentsParam, blockIdentifierParam); + + ArgumentCaptor dataCaptor = ArgumentCaptor.forClass(byte[].class); + verify(executor, times(1)) + .executeTransaction(eq(blockResult.getBlock()), any(), any(), any(), any(), any(), dataCaptor.capture(), any()); + assertArrayEquals(HexUtils.strHexOrStrNumberToByteArray(args.getInput()), dataCaptor.getValue()); + } + + @Test + void whenExecuteEstimateGasWithDataParameter_callExecutorWithData() { + CallArguments args = new CallArguments(); + args.setData(TEST_DATA); + Block block = mock(Block.class); + ExecutionBlockRetriever.Result blockResult = mock(ExecutionBlockRetriever.Result.class); + when(blockResult.getBlock()).thenReturn(block); + ExecutionBlockRetriever retriever = mock(ExecutionBlockRetriever.class); + when(retriever.retrieveExecutionBlock("latest")).thenReturn(blockResult); + Blockchain blockchain = mock(Blockchain.class); + + ProgramResult executorResult = mock(ProgramResult.class); + TransactionExecutor transactionExecutor = mock(TransactionExecutor.class); + when(transactionExecutor.getResult()) + .thenReturn(executorResult); + + ReversibleTransactionExecutor reversibleTransactionExecutor = mock(ReversibleTransactionExecutor.class); + when(reversibleTransactionExecutor.estimateGas(eq(block), any(), any(), any(), any(), any(), any(), any(), any())) + .thenReturn(transactionExecutor); + + EthModule eth = new EthModule( + null, + Constants.REGTEST_CHAIN_ID, + blockchain, + null, + reversibleTransactionExecutor, + retriever, + mock(RepositoryLocator.class), + null, + null, + new BridgeSupportFactory( + null, null, null, signatureCache), + config.getGasEstimationCap(), + config.getCallGasCap()); + + CallArgumentsParam callArgumentsParam = TransactionFactoryHelper.toCallArgumentsParam(args); + + eth.estimateGas(callArgumentsParam, new BlockIdentifierParam("latest")); + + ArgumentCaptor dataCaptor = ArgumentCaptor.forClass(byte[].class); + verify(reversibleTransactionExecutor, times(1)) + .estimateGas(eq(block), any(), any(), any(), any(), any(), dataCaptor.capture(), any(), any()); + assertArrayEquals(HexUtils.strHexOrStrNumberToByteArray(args.getData()), dataCaptor.getValue()); + } + + @Test + void whenExecuteEstimateGasWithInputParameter_callExecutorWithInput() { + CallArguments args = new CallArguments(); + args.setInput(TEST_DATA); + Block block = mock(Block.class); + ExecutionBlockRetriever.Result blockResult = mock(ExecutionBlockRetriever.Result.class); + when(blockResult.getBlock()).thenReturn(block); + ExecutionBlockRetriever retriever = mock(ExecutionBlockRetriever.class); + when(retriever.retrieveExecutionBlock("latest")).thenReturn(blockResult); + Blockchain blockchain = mock(Blockchain.class); + + ProgramResult executorResult = mock(ProgramResult.class); + TransactionExecutor transactionExecutor = mock(TransactionExecutor.class); + when(transactionExecutor.getResult()) + .thenReturn(executorResult); + + ReversibleTransactionExecutor reversibleTransactionExecutor = mock(ReversibleTransactionExecutor.class); + when(reversibleTransactionExecutor.estimateGas(eq(block), any(), any(), any(), any(), any(), any(), any(), any())) + .thenReturn(transactionExecutor); + + EthModule eth = new EthModule( + null, + Constants.REGTEST_CHAIN_ID, + blockchain, + null, + reversibleTransactionExecutor, + retriever, + mock(RepositoryLocator.class), + null, + null, + new BridgeSupportFactory( + null, null, null, signatureCache), + config.getGasEstimationCap(), + config.getCallGasCap()); + + CallArgumentsParam callArgumentsParam = TransactionFactoryHelper.toCallArgumentsParam(args); + + eth.estimateGas(callArgumentsParam, new BlockIdentifierParam("latest")); + + ArgumentCaptor dataCaptor = ArgumentCaptor.forClass(byte[].class); + verify(reversibleTransactionExecutor, times(1)) + .estimateGas(eq(block), any(), any(), any(), any(), any(), dataCaptor.capture(), any(), any()); + assertArrayEquals(HexUtils.strHexOrStrNumberToByteArray(args.getInput()), dataCaptor.getValue()); + } + + @Test + void whenExecuteEstimateGasWithInputAndDataParameters_callExecutorWithInput() { + CallArguments args = new CallArguments(); + args.setData(TEST_DATA); + args.setInput(TEST_DATA); + Block block = mock(Block.class); + ExecutionBlockRetriever.Result blockResult = mock(ExecutionBlockRetriever.Result.class); + when(blockResult.getBlock()).thenReturn(block); + ExecutionBlockRetriever retriever = mock(ExecutionBlockRetriever.class); + when(retriever.retrieveExecutionBlock("latest")).thenReturn(blockResult); + Blockchain blockchain = mock(Blockchain.class); + + ProgramResult executorResult = mock(ProgramResult.class); + TransactionExecutor transactionExecutor = mock(TransactionExecutor.class); + when(transactionExecutor.getResult()) + .thenReturn(executorResult); + + ReversibleTransactionExecutor reversibleTransactionExecutor = mock(ReversibleTransactionExecutor.class); + when(reversibleTransactionExecutor.estimateGas(eq(block), any(), any(), any(), any(), any(), any(), any(), any())) + .thenReturn(transactionExecutor); + + EthModule eth = new EthModule( + null, + Constants.REGTEST_CHAIN_ID, + blockchain, + null, + reversibleTransactionExecutor, + retriever, + mock(RepositoryLocator.class), + null, + null, + new BridgeSupportFactory( + null, null, null, signatureCache), + config.getGasEstimationCap(), + config.getCallGasCap()); + + CallArgumentsParam callArgumentsParam = TransactionFactoryHelper.toCallArgumentsParam(args); + + eth.estimateGas(callArgumentsParam, new BlockIdentifierParam("latest")); + + ArgumentCaptor dataCaptor = ArgumentCaptor.forClass(byte[].class); + verify(reversibleTransactionExecutor, times(1)) + .estimateGas(eq(block), any(), any(), any(), any(), any(), dataCaptor.capture(), any(), any()); + assertArrayEquals(HexUtils.strHexOrStrNumberToByteArray(args.getInput()), dataCaptor.getValue()); + } + + @Test + void whenExecuteSendTransactionWithDataParameter_callExecutorWithData() { + Constants constants = Constants.regtest(); + + Wallet wallet = new Wallet(new HashMapDB()); + RskAddress sender = wallet.addAccount(); + RskAddress receiver = wallet.addAccount(); + + // Hash of the expected transaction + CallArguments args = TransactionFactoryHelper.createArguments(sender, receiver); + args.setData(TEST_DATA); + + String expectedDataValue = args.getData().substring(2); + + TransactionPoolAddResult transactionPoolAddResult = mock(TransactionPoolAddResult.class); + when(transactionPoolAddResult.transactionsWereAdded()).thenReturn(true); + + TransactionGateway transactionGateway = mock(TransactionGateway.class); + when(transactionGateway.receiveTransaction(any(Transaction.class))).thenReturn(transactionPoolAddResult); + + TransactionPool transactionPool = mock(TransactionPool.class); + + EthModuleTransactionBase ethModuleTransaction = new EthModuleTransactionBase(constants, wallet, transactionPool, transactionGateway); + + CallArgumentsParam callArgumentsParam = TransactionFactoryHelper.toCallArgumentsParam(args); + + ethModuleTransaction.sendTransaction(callArgumentsParam); + + ArgumentCaptor transactionCaptor = ArgumentCaptor.forClass(Transaction.class); + verify(transactionGateway, times(1)) + .receiveTransaction(transactionCaptor.capture()); + assertArrayEquals(Hex.decode(expectedDataValue), transactionCaptor.getValue().getData()); + } + + @Test + void whenExecuteSendTransactionWithInputParameter_callExecutorWithInput() { + Constants constants = Constants.regtest(); + + Wallet wallet = new Wallet(new HashMapDB()); + RskAddress sender = wallet.addAccount(); + RskAddress receiver = wallet.addAccount(); + + // Hash of the expected transaction + CallArguments args = TransactionFactoryHelper.createArguments(sender, receiver); + args.setInput(TEST_DATA); + + String expectedDataValue = args.getInput().substring(2); + + TransactionPoolAddResult transactionPoolAddResult = mock(TransactionPoolAddResult.class); + when(transactionPoolAddResult.transactionsWereAdded()).thenReturn(true); + + TransactionGateway transactionGateway = mock(TransactionGateway.class); + when(transactionGateway.receiveTransaction(any(Transaction.class))).thenReturn(transactionPoolAddResult); + + TransactionPool transactionPool = mock(TransactionPool.class); + + EthModuleTransactionBase ethModuleTransaction = new EthModuleTransactionBase(constants, wallet, transactionPool, transactionGateway); + + CallArgumentsParam callArgumentsParam = TransactionFactoryHelper.toCallArgumentsParam(args); + + ethModuleTransaction.sendTransaction(callArgumentsParam); + + ArgumentCaptor transactionCaptor = ArgumentCaptor.forClass(Transaction.class); + verify(transactionGateway, times(1)) + .receiveTransaction(transactionCaptor.capture()); + assertArrayEquals(Hex.decode(expectedDataValue), transactionCaptor.getValue().getData()); + } + + @Test + void whenExecuteSendTransactionWithInputAndDataParameters_callExecutorWithInput() { + Constants constants = Constants.regtest(); + + Wallet wallet = new Wallet(new HashMapDB()); + RskAddress sender = wallet.addAccount(); + RskAddress receiver = wallet.addAccount(); + + // Hash of the expected transaction + CallArguments args = TransactionFactoryHelper.createArguments(sender, receiver); + args.setData(TEST_DATA); + args.setInput(TEST_DATA); + + String expectedDataValue = args.getInput().substring(2); + + TransactionPoolAddResult transactionPoolAddResult = mock(TransactionPoolAddResult.class); + when(transactionPoolAddResult.transactionsWereAdded()).thenReturn(true); + + TransactionGateway transactionGateway = mock(TransactionGateway.class); + when(transactionGateway.receiveTransaction(any(Transaction.class))).thenReturn(transactionPoolAddResult); + + TransactionPool transactionPool = mock(TransactionPool.class); + + EthModuleTransactionBase ethModuleTransaction = new EthModuleTransactionBase(constants, wallet, transactionPool, transactionGateway); + + CallArgumentsParam callArgumentsParam = TransactionFactoryHelper.toCallArgumentsParam(args); + + ethModuleTransaction.sendTransaction(callArgumentsParam); + + ArgumentCaptor transactionCaptor = ArgumentCaptor.forClass(Transaction.class); + verify(transactionGateway, times(1)) + .receiveTransaction(transactionCaptor.capture()); + assertArrayEquals(Hex.decode(expectedDataValue), transactionCaptor.getValue().getData()); + } } diff --git a/rskj-core/src/test/java/co/rsk/rpc/modules/personal/PersonalModuleTest.java b/rskj-core/src/test/java/co/rsk/rpc/modules/personal/PersonalModuleTest.java index 365dcdf6dc7..efcb16201a3 100644 --- a/rskj-core/src/test/java/co/rsk/rpc/modules/personal/PersonalModuleTest.java +++ b/rskj-core/src/test/java/co/rsk/rpc/modules/personal/PersonalModuleTest.java @@ -31,14 +31,11 @@ import org.ethereum.facade.Ethereum; import org.ethereum.rpc.CallArguments; import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.ethereum.rpc.parameters.CallArgumentsParam; import org.ethereum.util.TransactionFactoryHelper; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - class PersonalModuleTest { private static final String PASS_FRASE = "passfrase"; @@ -54,6 +51,7 @@ void sendTransactionWithGasLimitTest() throws Exception { // Hash of the expected transaction CallArguments args = TransactionFactoryHelper.createArguments(sender, receiver); + CallArgumentsParam argsParam = TransactionFactoryHelper.toCallArgumentsParam(args); Transaction tx = TransactionFactoryHelper.createTransaction(args, props.getNetworkConstants().getChainId(), wallet.getAccount(sender, PASS_FRASE)); String txExpectedResult = tx.getHash().toJsonString(); @@ -66,7 +64,7 @@ void sendTransactionWithGasLimitTest() throws Exception { PersonalModuleWalletEnabled personalModuleWalletEnabled = new PersonalModuleWalletEnabled(props, ethereum, wallet, null); // Hash of the actual transaction builded inside the sendTransaction - String txResult = personalModuleWalletEnabled.sendTransaction(args, PASS_FRASE); + String txResult = personalModuleWalletEnabled.sendTransaction(argsParam, PASS_FRASE); assertEquals(txExpectedResult, txResult); } @@ -83,6 +81,7 @@ void sendTransactionThrowsErrorOnChainIdValidationTest() { // Hash of the expected transaction CallArguments args = TransactionFactoryHelper.createArguments(sender, receiver); args.setChainId("" + ((int) props.getNetworkConstants().getChainId() - 2)); + CallArgumentsParam argsParam = TransactionFactoryHelper.toCallArgumentsParam(args); TransactionPoolAddResult transactionPoolAddResult = mock(TransactionPoolAddResult.class); when(transactionPoolAddResult.transactionsWereAdded()).thenReturn(true); @@ -91,7 +90,7 @@ void sendTransactionThrowsErrorOnChainIdValidationTest() { PersonalModuleWalletEnabled personalModuleWalletEnabled = new PersonalModuleWalletEnabled(props, ethereum, wallet, null); - Assertions.assertThrows(RskJsonRpcRequestException.class, () -> personalModuleWalletEnabled.sendTransaction(args, PASS_FRASE)); + Assertions.assertThrows(RskJsonRpcRequestException.class, () -> personalModuleWalletEnabled.sendTransaction(argsParam, PASS_FRASE)); } } diff --git a/rskj-core/src/test/java/co/rsk/rpc/modules/personal/PersonalModuleWalletEnabledTest.java b/rskj-core/src/test/java/co/rsk/rpc/modules/personal/PersonalModuleWalletEnabledTest.java index 6a76c6a34d5..33bca0142b4 100644 --- a/rskj-core/src/test/java/co/rsk/rpc/modules/personal/PersonalModuleWalletEnabledTest.java +++ b/rskj-core/src/test/java/co/rsk/rpc/modules/personal/PersonalModuleWalletEnabledTest.java @@ -3,9 +3,10 @@ import co.rsk.config.TestSystemProperties; import co.rsk.core.RskAddress; import co.rsk.core.Wallet; -import org.bouncycastle.util.encoders.DecoderException; import org.bouncycastle.util.encoders.Hex; import org.ethereum.crypto.ECKey; +import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.ethereum.rpc.parameters.HexKeyParam; import org.ethereum.util.ByteUtil; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -25,7 +26,7 @@ class PersonalModuleWalletEnabledTest { @Test void importRawKey_KeyIsNull_ThrowsNullPointerException() { PersonalModuleWalletEnabled personalModuleWalletEnabled = createPersonalModuleWalletEnabled(null); - Assertions.assertThrows(DecoderException.class, () -> personalModuleWalletEnabled.importRawKey(null, "passphrase1")); + Assertions.assertThrows(RskJsonRpcRequestException.class, () -> personalModuleWalletEnabled.importRawKey(null, "passphrase1")); } @Test @@ -43,7 +44,8 @@ void importRawKey_KeyContains0xPrefix_OK() { doReturn(true).when(walletMock).unlockAccount(eq(addressMock), eq(passphrase), any(Long.class)); PersonalModuleWalletEnabled personalModuleWalletEnabled = createPersonalModuleWalletEnabled(walletMock); - String result = personalModuleWalletEnabled.importRawKey(String.format("0x%s", rawKey), passphrase); + HexKeyParam hexKeyParam = new HexKeyParam(String.format("0x%s", rawKey)); + String result = personalModuleWalletEnabled.importRawKey(hexKeyParam, passphrase); verify(walletMock, times(1)).addAccountWithPrivateKey(hexDecodedKey, passphrase); verify(walletMock, times(1)).unlockAccount(addressMock, passphrase, 1800000L); @@ -67,7 +69,8 @@ void importRawKey_KeyDoesNotContains0xPrefix_OK() { doReturn(true).when(walletMock).unlockAccount(eq(addressMock), eq(passphrase), any(Long.class)); PersonalModuleWalletEnabled personalModuleWalletEnabled = createPersonalModuleWalletEnabled(walletMock); - String result = personalModuleWalletEnabled.importRawKey(rawKey, passphrase); + HexKeyParam hexKeyParam = new HexKeyParam(rawKey); + String result = personalModuleWalletEnabled.importRawKey(hexKeyParam, passphrase); verify(walletMock, times(1)).addAccountWithPrivateKey(hexDecodedKey, passphrase); verify(walletMock, times(1)).unlockAccount(addressMock, passphrase, 1800000L); diff --git a/rskj-core/src/test/java/co/rsk/rpc/netty/JsonRPCParamValidationTest.java b/rskj-core/src/test/java/co/rsk/rpc/netty/JsonRPCParamValidationTest.java new file mode 100644 index 00000000000..a7bec0637a0 --- /dev/null +++ b/rskj-core/src/test/java/co/rsk/rpc/netty/JsonRPCParamValidationTest.java @@ -0,0 +1,241 @@ +/* + * This file is part of RskJ + * Copyright (C) 2023 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package co.rsk.rpc.netty; + +import co.rsk.rpc.Web3EthModule; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.googlecode.jsonrpc4j.AnnotationsErrorResolver; +import com.googlecode.jsonrpc4j.DefaultErrorResolver; +import com.googlecode.jsonrpc4j.JsonResponse; +import com.googlecode.jsonrpc4j.MultipleErrorResolver; +import org.ethereum.rpc.dto.BlockResultDTO; +import org.ethereum.rpc.dto.TransactionResultDTO; +import org.ethereum.rpc.exception.RskErrorResolver; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.Collections; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class JsonRPCParamValidationTest { + private final ObjectMapper objectMapper = new ObjectMapper(); + private JsonRpcCustomServer jsonRpcServer; + private Web3EthModule handler; + + @BeforeEach + void setUp() { + handler = mock(Web3EthModule.class); + this.jsonRpcServer = new JsonRpcCustomServer(handler, handler.getClass(), Collections.emptyList()); + jsonRpcServer.setErrorResolver(new MultipleErrorResolver(new RskErrorResolver(), AnnotationsErrorResolver.INSTANCE, DefaultErrorResolver.INSTANCE)); + } + + @Test + void eth_getBlockByHash() throws Exception { + BlockResultDTO blockResultDTO = mock(BlockResultDTO.class); + + String requestBody = "{\n" + + "\t\"jsonrpc\":\"2.0\",\n" + + "\t\"method\":\"eth_getBlockByHash\",\n" + + "\t\"params\":[\n" + + "\t\t\"0xad1328d13f833b8af722117afdc406a762033321df8e48c00cd372d462f48169\", \n" + + "\t\ttrue\n" + + "\t],\n" + + "\t\"id\":1\n" + + "}"; + JsonNode request = objectMapper.readTree(requestBody); + + when(handler.eth_getBlockByHash(any(), any())).thenReturn(blockResultDTO); + + JsonResponse response = jsonRpcServer.handleJsonNodeRequest(request); + assertNotNull(response); + assertEquals(0, response.getCode()); + } + + @Test + void eth_getBlockByHash_invalidHexCharInHash_returnsError() throws Exception { + BlockResultDTO blockResultDTO = mock(BlockResultDTO.class); + + String requestBody = "{\n" + + "\t\"jsonrpc\":\"2.0\",\n" + + "\t\"method\":\"eth_getBlockByHash\",\n" + + "\t\"params\":[\n" + + "\t\t\"0xc2b835zzz172db5bd051bb94fa123721eacac43b5cba2499b22c7583a35689b8\", \n" + + "\t\ttrue\n" + + "\t],\n" + + "\t\"id\":1\n" + + "}"; + JsonNode request = objectMapper.readTree(requestBody); + + when(handler.eth_getBlockByHash(any(), any())).thenReturn(blockResultDTO); + + JsonResponse response = jsonRpcServer.handleJsonNodeRequest(request); + assertEquals(-32602, response.getCode()); + String message = response.getResponse().get("error").get("message").asText(); + assertEquals("Invalid block hash format: invalid hex value", message); + } + + @Test + void eth_getBlockByHash_invalidHashLength_returnsError() throws Exception { + BlockResultDTO blockResultDTO = mock(BlockResultDTO.class); + String requestBody = "{\n" + + "\t\"jsonrpc\":\"2.0\",\n" + + "\t\"method\":\"eth_getBlockByHash\",\n" + + "\t\"params\":[\n" + + "\t\t\"0xec576f474ea123c581c08008bea2\", \n" + + "\t\ttrue\n" + + "\t],\n" + + "\t\"id\":1\n" + + "}"; + JsonNode request = objectMapper.readTree(requestBody); + + when(handler.eth_getBlockByHash(any(), any())).thenReturn(blockResultDTO); + + JsonResponse response = jsonRpcServer.handleJsonNodeRequest(request); + assertEquals(-32602, response.getCode()); + String message = response.getResponse().get("error").get("message").asText(); + assertEquals("Invalid block hash: incorrect length.", message); + + } + + @Test + void eth_getTransactionByBlockHashAndIndex_invalidHash_returnsError() throws Exception { + TransactionResultDTO resultDTO = mock(TransactionResultDTO.class); + String requestBody = "{\n" + + "\t\"jsonrpc\":\"2.0\",\n" + + "\t\"method\":\"eth_getTransactionByBlockHashAndIndex\",\n" + + "\t\"params\":[\n" + + "\t\t\"0x3c82bc62179602b6731037c49cba84e31ffe6e465a21c521a7\", \n" + + "\t\t\"0x0\"\n" + + "\t],\n" + + "\t\"id\":1\n" + + "}"; + JsonNode request = objectMapper.readTree(requestBody); + when(handler.eth_getTransactionByBlockHashAndIndex(any(), any())).thenReturn(resultDTO); + JsonResponse response = jsonRpcServer.handleJsonNodeRequest(request); + assertEquals(-32602, response.getCode()); + String message = response.getResponse().get("error").get("message").asText(); + assertEquals("Invalid block hash: incorrect length.", message); + } + + + @Test + void eth_getTransactionByBlockHashAndIndex_invalidIndex_returnsError() throws Exception { + TransactionResultDTO resultDTO = mock(TransactionResultDTO.class); + String requestBody = "{\n" + + "\t\"jsonrpc\":\"2.0\",\n" + + "\t\"method\":\"eth_getTransactionByBlockHashAndIndex\",\n" + + "\t\"params\":[\n" + + "\t\t\"0x3c82bc62179602b67318c013c10f99011037c49cba84e31ffe6e465a21c521a7\", \n" + + "\t\t\"abc\"\n" + + "\t],\n" + + "\t\"id\":1\n" + + "}"; + JsonNode request = objectMapper.readTree(requestBody); + when(handler.eth_getTransactionByBlockHashAndIndex(any(), any())).thenReturn(resultDTO); + JsonResponse response = jsonRpcServer.handleJsonNodeRequest(request); + assertEquals(-32602, response.getCode()); + String message = response.getResponse().get("error").get("message").asText(); + assertEquals("Invalid argument \"abc\": param should be a hex value string.", message); + } + + @Test + void eth_getBlockTransactionCountByHash_invalidHash_returnsError() throws Exception { + String requestBody = "{\n" + + "\t\"jsonrpc\":\"2.0\",\n" + + "\t\"method\":\"eth_getBlockTransactionCountByHash\",\n" + + "\t\"params\":[\n" + + "\t\t\"0x3c82bc62179602b6731037c49cba84e31ffe6e465a21c521a7\"\n" + + "\t],\n" + + "\t\"id\":1\n" + + "}"; + JsonNode request = objectMapper.readTree(requestBody); + when(handler.eth_getBlockTransactionCountByHash(any())).thenReturn("0x0"); + JsonResponse response = jsonRpcServer.handleJsonNodeRequest(request); + assertEquals(-32602, response.getCode()); + String message = response.getResponse().get("error").get("message").asText(); + assertEquals("Invalid block hash: incorrect length.", message); + } + + @Test + void eth_getTransactionByHash_invalidHash_returnsError() throws Exception { + TransactionResultDTO resultDTO = mock(TransactionResultDTO.class); + String requestBody = "{\n" + + "\t\"jsonrpc\":\"2.0\",\n" + + "\t\"method\":\"eth_getTransactionByHash\",\n" + + "\t\"params\":[\n" + + "\t\t\"0xc2b835zzz172db5bd051bb94fa123721eacac43b5cba2499b22c7583a35689b8\"\n" + + "\t],\n" + + "\t\"id\":1\n" + + "}"; + JsonNode request = objectMapper.readTree(requestBody); + JsonResponse response = jsonRpcServer.handleJsonNodeRequest(request); + assertEquals(-32602, response.getCode()); + String message = response.getResponse().get("error").get("message").asText(); + assertEquals("Invalid transaction hash format: invalid hex value", message); + } + + @Test + void eth_getUncleByBlockHashAndIndex_invalidHash_returnsError() throws Exception { + BlockResultDTO blockResultDTO = mock(BlockResultDTO.class); + String requestBody = "{\n" + + "\t\"jsonrpc\":\"2.0\",\n" + + "\t\"method\":\"eth_getUncleByBlockHashAndIndex\",\n" + + "\t\"params\":[\n" + + "\t\t\"0x3c82bc62179602b6731037c49cba84e31ffe6e465a21c521a7\", \n" + + "\t\t\"0x0\"\n" + + "\t],\n" + + "\t\"id\":1\n" + + "}"; + JsonNode request = objectMapper.readTree(requestBody); + + when(handler.eth_getUncleByBlockHashAndIndex(any(), any())).thenReturn(blockResultDTO); + + JsonResponse response = jsonRpcServer.handleJsonNodeRequest(request); + assertEquals(-32602, response.getCode()); + String message = response.getResponse().get("error").get("message").asText(); + assertEquals("Invalid block hash: incorrect length.", message); + } + + @Test + void eth_getUncleByBlockHashAndIndex_invalidIndex_returnsError() throws Exception { + BlockResultDTO blockResultDTO = mock(BlockResultDTO.class); + String requestBody = "{\n" + + "\t\"jsonrpc\":\"2.0\",\n" + + "\t\"method\":\"eth_getUncleByBlockHashAndIndex\",\n" + + "\t\"params\":[\n" + + "\t\t\"0x3c82bc62179602b67318c013c10f99011037c49cba84e31ffe6e465a21c521a7\", \n" + + "\t\t\"122\"\n" + + "\t],\n" + + "\t\"id\":1\n" + + "}"; + JsonNode request = objectMapper.readTree(requestBody); + + when(handler.eth_getUncleByBlockHashAndIndex(any(), any())).thenReturn(blockResultDTO); + + JsonResponse response = jsonRpcServer.handleJsonNodeRequest(request); + assertEquals(-32602, response.getCode()); + String message = response.getResponse().get("error").get("message").asText(); + assertEquals("Invalid argument \"122\": param should be a hex value string.", message); + } +} \ No newline at end of file diff --git a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplLogsTest.java b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplLogsTest.java index 33cfba15c00..b9cbe67c95a 100644 --- a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplLogsTest.java +++ b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplLogsTest.java @@ -34,6 +34,7 @@ import org.ethereum.rpc.Simples.SimpleConfigCapabilities; import org.ethereum.rpc.dto.TransactionReceiptDTO; import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.ethereum.rpc.parameters.TxHashParam; import org.ethereum.util.ByteUtil; import org.ethereum.util.RskTestFactory; import org.junit.jupiter.api.BeforeEach; @@ -65,8 +66,30 @@ import co.rsk.test.builders.TransactionBuilder; import co.rsk.trie.TrieStore; import co.rsk.util.HexUtils; +import org.ethereum.core.*; +import org.ethereum.datasource.HashMapDB; +import org.ethereum.db.BlockStore; +import org.ethereum.db.ReceiptStore; +import org.ethereum.facade.Ethereum; +import org.ethereum.rpc.Simples.SimpleConfigCapabilities; +import org.ethereum.rpc.dto.TransactionReceiptDTO; +import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.ethereum.rpc.parameters.*; +import org.ethereum.util.ByteUtil; +import org.ethereum.util.RskTestFactory; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; +import java.math.BigInteger; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.mock; + /** * Created by ajlopez on 30/11/2016. */ @@ -106,7 +129,7 @@ class Web3ImplLogsTest { @TempDir public Path tempDir; private Blockchain blockChain; - private MiningMainchainView mainchainView; + private MiningMainchainView mainchainView; private RepositoryLocator repositoryLocator; private TransactionPool transactionPool; private Ethereum eth; @@ -138,8 +161,7 @@ void setUp() { @Test void newFilterInEmptyBlockchain() throws Exception { - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); + FilterRequestParam fr = new FilterRequestParam(new BlockIdentifierParam("earliest"), null, null, null, null); String id = web3.eth_newFilter(fr); assertNotNull(id); @@ -147,10 +169,9 @@ void newFilterInEmptyBlockchain() throws Exception { @Test void newFilterGetLogsInEmptyBlockchain() throws Exception { - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); + FilterRequestParam fr = new FilterRequestParam(new BlockIdentifierParam("earliest"), null, null, null, null); String id = web3.eth_newFilter(fr); - Object[] logs = web3.eth_getFilterLogs(id); + Object[] logs = web3.eth_getFilterLogs(new HexIndexParam(id)); assertNotNull(id); assertNotNull(logs); @@ -160,12 +181,11 @@ void newFilterGetLogsInEmptyBlockchain() throws Exception { @Test void newFilterGetLogsAfterBlock() throws Exception { Account acc1 = new AccountBuilder(blockChain, - blockStore, - repositoryLocator).name("notDefault").balance(Coin.valueOf(10000000)).build(); + blockStore, + repositoryLocator).name("notDefault").balance(Coin.valueOf(10000000)).build(); web3.personal_newAccountWithSeed("notDefault"); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("latest"); + FilterRequestParam fr = new FilterRequestParam(new BlockIdentifierParam("latest"), null, null, null, null); String id = web3.eth_newFilter(fr); Block genesis = blockChain.getBlockByNumber(0); @@ -175,24 +195,24 @@ void newFilterGetLogsAfterBlock() throws Exception { List txs = new ArrayList<>(); txs.add(tx); Block block1 = new BlockBuilder(blockChain, null, - blockStore + blockStore ).trieStore(trieStore).parent(genesis).transactions(txs).build(); assertEquals(ImportResult.IMPORTED_BEST, blockChain.tryToConnect(block1)); - Object[] logs = web3.eth_getFilterLogs(id); + Object[] logs = web3.eth_getFilterLogs(new HexIndexParam(id)); assertNotNull(id); assertNotNull(logs); assertEquals(1, logs.length); - assertEquals("0x" + tx.getContractAddress().toString(),((LogFilterElement)logs[0]).address); + assertEquals("0x" + tx.getContractAddress().toString(), ((LogFilterElement) logs[0]).address); } @Test void newFilterWithAccountAndTopicsCreatedAfterBlockAndGetLogs() throws Exception { Account acc1 = new AccountBuilder(blockChain, - blockStore, - repositoryLocator).name("notDefault").balance(Coin.valueOf(10000000)).build(); + blockStore, + repositoryLocator).name("notDefault").balance(Coin.valueOf(10000000)).build(); web3.personal_newAccountWithSeed("notDefault"); @@ -203,34 +223,34 @@ void newFilterWithAccountAndTopicsCreatedAfterBlockAndGetLogs() throws Exception List txs = new ArrayList<>(); txs.add(tx); Block block1 = new BlockBuilder(blockChain, null, - blockStore + blockStore ).trieStore(trieStore).parent(genesis).transactions(txs).build(); assertEquals(ImportResult.IMPORTED_BEST, blockChain.tryToConnect(block1)); - FilterRequest fr = new FilterRequest(); - fr.setAddress( ByteUtil.toHexString(tx.getContractAddress().getBytes())); - fr.setTopics(new Object[] { "06acbfb32bcf8383f3b0a768b70ac9ec234ea0f2d3b9c77fa6a2de69b919aad1" }); + HexAddressParam[] hexAddressParam = new HexAddressParam[]{new HexAddressParam((tx.getContractAddress().toJsonString()))}; + TopicParam[][] topics = initTopicsArray("06acbfb32bcf8383f3b0a768b70ac9ec234ea0f2d3b9c77fa6a2de69b919aad1"); + FilterRequestParam fr = new FilterRequestParam(null, null, hexAddressParam, topics, null); + String id = web3.eth_newFilter(fr); - Object[] logs = web3.eth_getFilterLogs(id); + Object[] logs = web3.eth_getFilterLogs(new HexIndexParam(id)); assertNotNull(id); assertNotNull(logs); assertEquals(1, logs.length); - assertEquals("0x" + tx.getContractAddress().toString(),((LogFilterElement)logs[0]).address); + assertEquals("0x" + tx.getContractAddress().toString(), ((LogFilterElement) logs[0]).address); } @Test void newFilterGetLogsTwiceAfterBlock() throws Exception { Account acc1 = new AccountBuilder(blockChain, - blockStore, - repositoryLocator).name("notDefault").balance(Coin.valueOf(10000000)).build(); + blockStore, + repositoryLocator).name("notDefault").balance(Coin.valueOf(10000000)).build(); web3.personal_newAccountWithSeed("notDefault"); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); + FilterRequestParam fr = new FilterRequestParam(new BlockIdentifierParam("earliest"), null, null, null, null); String id = web3.eth_newFilter(fr); Block genesis = blockChain.getBlockByNumber(0); @@ -240,26 +260,27 @@ void newFilterGetLogsTwiceAfterBlock() throws Exception { List txs = new ArrayList<>(); txs.add(tx); Block block1 = new BlockBuilder(blockChain, null, - blockStore + blockStore ).trieStore(trieStore).parent(genesis).transactions(txs).build(); assertEquals(ImportResult.IMPORTED_BEST, blockChain.tryToConnect(block1)); - web3.eth_getFilterLogs(id); - Object[] logs = web3.eth_getFilterLogs(id); + HexIndexParam idParam = new HexIndexParam(id); + web3.eth_getFilterLogs(idParam); + Object[] logs = web3.eth_getFilterLogs(idParam); assertNotNull(id); assertNotNull(logs); assertEquals(1, logs.length); - assertEquals("0x" + tx.getContractAddress().toString(),((LogFilterElement)logs[0]).address); + assertEquals("0x" + tx.getContractAddress().toString(), ((LogFilterElement) logs[0]).address); } @Test void newFilterGetChangesInEmptyBlockchain() throws Exception { - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); + FilterRequestParam fr = new FilterRequestParam(new BlockIdentifierParam("earliest"), null, null, null, null); String id = web3.eth_newFilter(fr); - Object[] logs = web3.eth_getFilterChanges(id); + HexIndexParam hexIndexParam = new HexIndexParam(id); + Object[] logs = web3.eth_getFilterChanges(hexIndexParam); assertNotNull(id); assertNotNull(logs); @@ -269,13 +290,12 @@ void newFilterGetChangesInEmptyBlockchain() throws Exception { @Test void newFilterGetChangesAfterBlock() throws Exception { Account acc1 = new AccountBuilder(blockChain, - blockStore, - repositoryLocator).name("notDefault").balance(Coin.valueOf(10000000)).build(); + blockStore, + repositoryLocator).name("notDefault").balance(Coin.valueOf(10000000)).build(); web3.personal_newAccountWithSeed("notDefault"); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); + FilterRequestParam fr = new FilterRequestParam(new BlockIdentifierParam("earliest"), null, null, null, null); String id = web3.eth_newFilter(fr); Block genesis = blockChain.getBlockByNumber(0); @@ -285,23 +305,22 @@ void newFilterGetChangesAfterBlock() throws Exception { List txs = new ArrayList<>(); txs.add(tx); Block block1 = new BlockBuilder(blockChain, null, - blockStore + blockStore ).trieStore(trieStore).parent(genesis).transactions(txs).build(); assertEquals(ImportResult.IMPORTED_BEST, blockChain.tryToConnect(block1)); - Object[] logs = web3.eth_getFilterChanges(id); + Object[] logs = web3.eth_getFilterChanges(new HexIndexParam(id)); assertNotNull(id); assertNotNull(logs); assertEquals(1, logs.length); - assertEquals("0x" + tx.getContractAddress().toString(),((LogFilterElement)logs[0]).address); + assertEquals("0x" + tx.getContractAddress().toString(), ((LogFilterElement) logs[0]).address); } @Test void getLogsFromEmptyBlockchain() throws Exception { - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); + FilterRequestParam fr = new FilterRequestParam(new BlockIdentifierParam("earliest"), null, null, null, null); Object[] logs = web3.eth_getLogs(fr); assertNotNull(logs); @@ -312,8 +331,7 @@ void getLogsFromEmptyBlockchain() throws Exception { void getLogsFromBlockchainWithThreeEmptyBlocks() throws Exception { addTwoEmptyBlocks(); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); + FilterRequestParam fr = new FilterRequestParam(new BlockIdentifierParam("earliest"), null, null, null, null); Object[] logs = web3.eth_getLogs(fr); assertNotNull(logs); @@ -324,8 +342,7 @@ void getLogsFromBlockchainWithThreeEmptyBlocks() throws Exception { void getLogsTwiceFromBlockchainWithThreeEmptyBlocks() throws Exception { addTwoEmptyBlocks(); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); + FilterRequestParam fr = new FilterRequestParam(new BlockIdentifierParam("earliest"), null, null, null, null); web3.eth_getLogs(fr); Object[] logs = web3.eth_getLogs(fr); @@ -337,8 +354,7 @@ void getLogsTwiceFromBlockchainWithThreeEmptyBlocks() throws Exception { void getLogsFromBlockchainWithContractCreation() throws Exception { addContractCreationWithoutEvents(); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); + FilterRequestParam fr = new FilterRequestParam(new BlockIdentifierParam("earliest"), null, null, null, null); Object[] logs = web3.eth_getLogs(fr); assertNotNull(logs); @@ -349,8 +365,8 @@ void getLogsFromBlockchainWithContractCreation() throws Exception { void getLogsTwiceFromBlockchainWithContractCreation() throws Exception { addContractCreationWithoutEvents(); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); + FilterRequestParam fr = new FilterRequestParam(new BlockIdentifierParam("earliest"), null, null, null, null); + web3.eth_getLogs(fr); Object[] logs = web3.eth_getLogs(fr); @@ -362,69 +378,67 @@ void getLogsTwiceFromBlockchainWithContractCreation() throws Exception { void getLogsFromBlockchainWithEventInContractCreation() throws Exception { addEventInContractCreation(); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); - fr.setToBlock("latest"); + FilterRequestParam fr = new FilterRequestParam(new BlockIdentifierParam("earliest"), new BlockIdentifierParam("latest"), null, null, null); Object[] logs = web3.eth_getLogs(fr); assertNotNull(logs); assertEquals(1, logs.length); - String txhash = ((LogFilterElement)logs[0]).transactionHash; - TransactionReceiptDTO txdto = web3.eth_getTransactionReceipt(txhash); + String txhash = ((LogFilterElement) logs[0]).transactionHash; + TransactionReceiptDTO txdto = web3.eth_getTransactionReceipt(new TxHashParam(txhash)); - assertEquals(txdto.getContractAddress(),((LogFilterElement)logs[0]).address); + assertEquals(txdto.getContractAddress(), ((LogFilterElement) logs[0]).address); } @Test void getLogsTwiceFromBlockchainWithEventInContractCreation() throws Exception { addEventInContractCreation(); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); + FilterRequestParam fr = new FilterRequestParam(new BlockIdentifierParam("earliest"), null, null, null, null); + web3.eth_getLogs(fr); Object[] logs = web3.eth_getLogs(fr); assertNotNull(logs); assertEquals(1, logs.length); - String txhash = ((LogFilterElement)logs[0]).transactionHash; - TransactionReceiptDTO txdto = web3.eth_getTransactionReceipt(txhash); + String txhash = ((LogFilterElement) logs[0]).transactionHash; + TransactionReceiptDTO txdto = web3.eth_getTransactionReceipt(new TxHashParam(txhash)); - assertEquals(txdto.getContractAddress(),((LogFilterElement)logs[0]).address); + assertEquals(txdto.getContractAddress(), ((LogFilterElement) logs[0]).address); } @Test void getLogsFromBlockchainWithInvokeContract() throws Exception { addContractInvoke(); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); + FilterRequestParam fr = new FilterRequestParam(new BlockIdentifierParam("earliest"), null, null, null, null); + Object[] logs = web3.eth_getLogs(fr); assertNotNull(logs); assertEquals(2, logs.length); - String txhash = ((LogFilterElement)logs[0]).transactionHash; - TransactionReceiptDTO txdto = web3.eth_getTransactionReceipt(txhash); + String txhash = ((LogFilterElement) logs[0]).transactionHash; + TransactionReceiptDTO txdto = web3.eth_getTransactionReceipt(new TxHashParam(txhash)); - assertEquals(txdto.getContractAddress(),((LogFilterElement)logs[0]).address); - assertEquals(txdto.getContractAddress(),((LogFilterElement)logs[1]).address); + assertEquals(txdto.getContractAddress(), ((LogFilterElement) logs[0]).address); + assertEquals(txdto.getContractAddress(), ((LogFilterElement) logs[1]).address); } @Test void getLogsKeepsCorrectOrderForReverseSearch() throws Exception { List transactions = addContractInvokeManyTxPerBlock(); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); + FilterRequestParam fr = new FilterRequestParam(new BlockIdentifierParam("earliest"), null, null, null, null); + Object[] logs = web3.eth_getLogs(fr); assertNotNull(logs); assertEquals(3, logs.length); String txHash1 = "0x" + transactions.get(0).getHash().toHexString(); - TransactionReceiptDTO txReceipt1 = web3.eth_getTransactionReceipt(txHash1); + TransactionReceiptDTO txReceipt1 = web3.eth_getTransactionReceipt(new TxHashParam(txHash1)); String contractAddress = txReceipt1.getContractAddress(); LogFilterElement logs1 = (LogFilterElement) logs[0]; assertEquals(contractAddress, logs1.address); @@ -435,7 +449,7 @@ void getLogsKeepsCorrectOrderForReverseSearch() throws Exception { assertArrayEquals(receipt1Logs.topics, logs1.topics); String txHash2 = "0x" + transactions.get(1).getHash().toHexString(); - TransactionReceiptDTO txReceipt2 = web3.eth_getTransactionReceipt(txHash2); + TransactionReceiptDTO txReceipt2 = web3.eth_getTransactionReceipt(new TxHashParam(txHash2)); LogFilterElement logs2 = (LogFilterElement) logs[1]; assertEquals(contractAddress, logs2.address); assertEquals(txHash2, logs2.transactionHash); @@ -445,7 +459,7 @@ void getLogsKeepsCorrectOrderForReverseSearch() throws Exception { assertArrayEquals(receipt2Logs.topics, logs2.topics); String txHash3 = "0x" + transactions.get(2).getHash().toHexString(); - TransactionReceiptDTO txReceipt3 = web3.eth_getTransactionReceipt(txHash3); + TransactionReceiptDTO txReceipt3 = web3.eth_getTransactionReceipt(new TxHashParam(txHash3)); LogFilterElement logs3 = (LogFilterElement) logs[2]; assertEquals(contractAddress, logs3.address); assertEquals(txHash3, logs3.transactionHash); @@ -466,27 +480,26 @@ void getLogsKeepsCorrectOrderForReverseSearch() throws Exception { void getLogsTwiceFromBlockchainWithInvokeContract() throws Exception { addContractInvoke(); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); + FilterRequestParam fr = new FilterRequestParam(new BlockIdentifierParam("earliest"), null, null, null, null); web3.eth_getLogs(fr); Object[] logs = web3.eth_getLogs(fr); assertNotNull(logs); assertEquals(2, logs.length); - String txhash = ((LogFilterElement)logs[0]).transactionHash; - TransactionReceiptDTO txdto = web3.eth_getTransactionReceipt(txhash); + String txhash = ((LogFilterElement) logs[0]).transactionHash; + TransactionReceiptDTO txdto = web3.eth_getTransactionReceipt(new TxHashParam(txhash)); - assertEquals(txdto.getContractAddress(),((LogFilterElement)logs[0]).address); - assertEquals(txdto.getContractAddress(),((LogFilterElement)logs[1]).address); + assertEquals(txdto.getContractAddress(), ((LogFilterElement) logs[0]).address); + assertEquals(txdto.getContractAddress(), ((LogFilterElement) logs[1]).address); } @Test void getLogsFromBlockchainWithCallContract() throws Exception { addContractCall(); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); + FilterRequestParam fr = new FilterRequestParam(new BlockIdentifierParam("earliest"), null, null, null, null); + Object[] logs = web3.eth_getLogs(fr); assertNotNull(logs); @@ -497,8 +510,8 @@ void getLogsFromBlockchainWithCallContract() throws Exception { void getLogsTwiceFromBlockchainWithCallContract() throws Exception { addContractCall(); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); + FilterRequestParam fr = new FilterRequestParam(new BlockIdentifierParam("earliest"), null, null, null, null); + web3.eth_getLogs(fr); Object[] logs = web3.eth_getLogs(fr); @@ -510,50 +523,51 @@ void getLogsTwiceFromBlockchainWithCallContract() throws Exception { void getLogsFromBlockchainWithCallContractAndFilterByContractAddress() throws Exception { addContractCall(); Block block1 = blockChain.getBlockByNumber(1l); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); - fr.setAddress( ByteUtil.toHexString(block1.getTransactionsList().get(0).getContractAddress().getBytes())); + HexAddressParam[] addressParam = new HexAddressParam[]{new HexAddressParam(block1.getTransactionsList().get(0).getContractAddress().toJsonString())}; + FilterRequestParam fr = new FilterRequestParam(new BlockIdentifierParam("earliest"), null, addressParam, null, null); Object[] logs = web3.eth_getLogs(fr); assertNotNull(logs); assertEquals(3, logs.length); - String address = "0x" + fr.getAddress(); + String address = fr.getAddress()[0].getAddress().toJsonString(); - assertEquals(address,((LogFilterElement)logs[0]).address); - assertEquals(address,((LogFilterElement)logs[1]).address); - assertEquals(address,((LogFilterElement)logs[2]).address); + assertEquals(address, ((LogFilterElement) logs[0]).address); + assertEquals(address, ((LogFilterElement) logs[1]).address); + assertEquals(address, ((LogFilterElement) logs[2]).address); } @Test void getLogsTwoceFromBlockchainWithCallContractAndFilterByContractAddress() throws Exception { addContractCall(); Block block1 = blockChain.getBlockByNumber(1l); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); - fr.setAddress( ByteUtil.toHexString(block1.getTransactionsList().get(0).getContractAddress().getBytes())); + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam("earliest"); + HexAddressParam[] hexAddressParam = new HexAddressParam[]{ + new HexAddressParam(block1.getTransactionsList().get(0).getContractAddress().toJsonString()) + }; + FilterRequestParam fr = new FilterRequestParam(blockIdentifierParam, null, hexAddressParam, null, null); web3.eth_getLogs(fr); Object[] logs = web3.eth_getLogs(fr); assertNotNull(logs); assertEquals(3, logs.length); - String address = "0x" + fr.getAddress(); + String address = fr.getAddress()[0].getAddress().toJsonString(); - assertEquals(address,((LogFilterElement)logs[0]).address); - assertEquals(address,((LogFilterElement)logs[1]).address); - assertEquals(address,((LogFilterElement)logs[2]).address); + assertEquals(address, ((LogFilterElement) logs[0]).address); + assertEquals(address, ((LogFilterElement) logs[1]).address); + assertEquals(address, ((LogFilterElement) logs[2]).address); } @Test void getLogsFromBlockchainWithCallContractAndFilterByUnknownContractAddress() throws Exception { addContractCall(); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); - List addresses = new ArrayList<>(); - addresses.add(ByteUtil.toHexString(new byte[20])); - fr.setAddress(addresses); + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam("earliest"); + HexAddressParam[] hexAddressParam = new HexAddressParam[]{ + new HexAddressParam(ByteUtil.toHexString(new byte[20])) + }; + FilterRequestParam fr = new FilterRequestParam(blockIdentifierParam, null, hexAddressParam, null, null); Object[] logs = web3.eth_getLogs(fr); assertNotNull(logs); @@ -564,11 +578,11 @@ void getLogsFromBlockchainWithCallContractAndFilterByUnknownContractAddress() th void getLogsTwiceFromBlockchainWithCallContractAndFilterByUnknownContractAddress() throws Exception { addContractCall(); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); - List addresses = new ArrayList<>(); - addresses.add(ByteUtil.toHexString(new byte[20])); - fr.setAddress(addresses); + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam("earliest"); + HexAddressParam[] hexAddressParam = new HexAddressParam[]{ + new HexAddressParam(ByteUtil.toHexString(new byte[20])) + }; + FilterRequestParam fr = new FilterRequestParam(blockIdentifierParam, null, hexAddressParam, null, null); web3.eth_getLogs(fr); Object[] logs = web3.eth_getLogs(fr); @@ -580,10 +594,9 @@ void getLogsTwiceFromBlockchainWithCallContractAndFilterByUnknownContractAddress void getLogsFromBlockchainWithCallContractAndFilterByUnknownTopic() throws Exception { addContractCall(); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); - fr.setTopics(new Object[1]); - fr.getTopics()[0] = "0102030405060102030405060102030405060102030405060102030405060102"; + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam("earliest"); + TopicParam[][] topics = initTopicsArray("0102030405060102030405060102030405060102030405060102030405060102"); + FilterRequestParam fr = new FilterRequestParam(blockIdentifierParam, null, null, topics, null); Object[] logs = web3.eth_getLogs(fr); assertNotNull(logs); @@ -594,10 +607,9 @@ void getLogsFromBlockchainWithCallContractAndFilterByUnknownTopic() throws Excep void getLogsTwiceFromBlockchainWithCallContractAndFilterByUnknownTopic() throws Exception { addContractCall(); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); - fr.setTopics(new Object[1]); - fr.getTopics()[0] = "0102030405060102030405060102030405060102030405060102030405060102"; + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam("earliest"); + TopicParam[][] topics = initTopicsArray("0102030405060102030405060102030405060102030405060102030405060102"); + FilterRequestParam fr = new FilterRequestParam(blockIdentifierParam, null, null, topics, null); web3.eth_getLogs(fr); Object[] logs = web3.eth_getLogs(fr); @@ -610,16 +622,15 @@ void getLogsFromBlockchainWithCallContractAndFilterByKnownTopic() throws Excepti addContractCall(); Block block1 = blockChain.getBlockByNumber(1l); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); - fr.setTopics(new Object[1]); - fr.getTopics()[0] = GET_VALUED_EVENT_SIGNATURE; + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam("earliest"); + TopicParam[][] topics = initTopicsArray(GET_VALUED_EVENT_SIGNATURE); + FilterRequestParam fr = new FilterRequestParam(blockIdentifierParam, null, null, topics, null); Object[] logs = web3.eth_getLogs(fr); assertNotNull(logs); String address = "0x" + ByteUtil.toHexString(block1.getTransactionsList().get(0).getContractAddress().getBytes()); assertEquals(1, logs.length); - assertEquals(address,((LogFilterElement)logs[0]).address); + assertEquals(address, ((LogFilterElement) logs[0]).address); } @Test @@ -627,67 +638,56 @@ void getLogsTwiceFromBlockchainWithCallContractAndFilterByKnownTopic() throws Ex addContractCall(); Block block1 = blockChain.getBlockByNumber(1l); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); - fr.setTopics(new Object[1]); - fr.getTopics()[0] = GET_VALUED_EVENT_SIGNATURE; + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam("earliest"); + TopicParam[][] topics = initTopicsArray(GET_VALUED_EVENT_SIGNATURE); + FilterRequestParam fr = new FilterRequestParam(blockIdentifierParam, null, null, topics, null); web3.eth_getLogs(fr); Object[] logs = web3.eth_getLogs(fr); assertNotNull(logs); String address = "0x" + ByteUtil.toHexString(block1.getTransactionsList().get(0).getContractAddress().getBytes()); assertEquals(1, logs.length); - assertEquals(address,((LogFilterElement)logs[0]).address); + assertEquals(address, ((LogFilterElement) logs[0]).address); } @Test void getLogsFromBlockchainWithCallContractAndFilterByKnownTopicInList() throws Exception { addContractCall(); Block block1 = blockChain.getBlockByNumber(1l); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); - fr.setTopics(new Object[1]); - List topics = new ArrayList<>(); - topics.add(GET_VALUED_EVENT_SIGNATURE); - fr.getTopics()[0] = topics; + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam("earliest"); + TopicParam[][] topics = initTopicsArray(GET_VALUED_EVENT_SIGNATURE); + FilterRequestParam fr = new FilterRequestParam(blockIdentifierParam, null, null, topics, null); Object[] logs = web3.eth_getLogs(fr); assertNotNull(logs); String address = "0x" + ByteUtil.toHexString(block1.getTransactionsList().get(0).getContractAddress().getBytes()); assertEquals(1, logs.length); - assertEquals(address,((LogFilterElement)logs[0]).address); + assertEquals(address, ((LogFilterElement) logs[0]).address); } @Test void getLogsTwiceFromBlockchainWithCallContractAndFilterByKnownTopicInList() throws Exception { addContractCall(); Block block1 = blockChain.getBlockByNumber(1l); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); - fr.setTopics(new Object[1]); - List topics = new ArrayList<>(); - topics.add(GET_VALUED_EVENT_SIGNATURE); - fr.getTopics()[0] = topics; + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam("earliest"); + TopicParam[][] topics = initTopicsArray(GET_VALUED_EVENT_SIGNATURE); + FilterRequestParam fr = new FilterRequestParam(blockIdentifierParam, null, null, topics, null); web3.eth_getLogs(fr); Object[] logs = web3.eth_getLogs(fr); assertNotNull(logs); String address = "0x" + ByteUtil.toHexString(block1.getTransactionsList().get(0).getContractAddress().getBytes()); assertEquals(1, logs.length); - assertEquals(address,((LogFilterElement)logs[0]).address); + assertEquals(address, ((LogFilterElement) logs[0]).address); } @Test void getLogsFromBlockchainWithCallContractAndFilterByKnownsTopicInList() throws Exception { addContractCall(); Block block1 = blockChain.getBlockByNumber(1l); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); - fr.setTopics(new Object[1]); - List topics = new ArrayList<>(); - topics.add(GET_VALUED_EVENT_SIGNATURE); - topics.add(INC_EVENT_SIGNATURE); - fr.getTopics()[0] = topics; + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam("earliest"); + TopicParam[][] topics = new TopicParam[][]{{new TopicParam(GET_VALUED_EVENT_SIGNATURE),new TopicParam(INC_EVENT_SIGNATURE)}}; + FilterRequestParam fr = new FilterRequestParam(blockIdentifierParam, null, null, topics, null); Object[] logs = web3.eth_getLogs(fr); assertNotNull(logs); @@ -703,13 +703,9 @@ void getLogsFromBlockchainWithCallContractAndFilterByKnownsTopicInList() throws void getLogsTwiceFromBlockchainWithCallContractAndFilterByKnownsTopicInList() throws Exception { addContractCall(); Block block1 = blockChain.getBlockByNumber(1l); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); - fr.setTopics(new Object[1]); - List topics = new ArrayList<>(); - topics.add(GET_VALUED_EVENT_SIGNATURE); - topics.add(INC_EVENT_SIGNATURE); - fr.getTopics()[0] = topics; + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam("earliest"); + TopicParam[][] topics = new TopicParam[][]{{new TopicParam(GET_VALUED_EVENT_SIGNATURE),new TopicParam(INC_EVENT_SIGNATURE)}}; + FilterRequestParam fr = new FilterRequestParam(blockIdentifierParam, null, null, topics, null); web3.eth_getLogs(fr); Object[] logs = web3.eth_getLogs(fr); @@ -726,45 +722,41 @@ void getLogsTwiceFromBlockchainWithCallContractAndFilterByKnownsTopicInList() th void getLogsFromBlockchainWithCallContractAndFilterByKnownTopicInListWithNull() throws Exception { addContractCall(); Block block1 = blockChain.getBlockByNumber(1l); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); - fr.setTopics(new Object[2]); - fr.getTopics()[0] = GET_VALUED_EVENT_SIGNATURE; - fr.getTopics()[1] = null; + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam("earliest"); + TopicParam[][] topics = new TopicParam[][]{{new TopicParam(GET_VALUED_EVENT_SIGNATURE)},{null}}; + FilterRequestParam fr = new FilterRequestParam(blockIdentifierParam, null, null, topics, null); Object[] logs = web3.eth_getLogs(fr); assertNotNull(logs); String address = "0x" + ByteUtil.toHexString(block1.getTransactionsList().get(0).getContractAddress().getBytes()); assertEquals(1, logs.length); - assertEquals(address,((LogFilterElement)logs[0]).address); + assertEquals(address, ((LogFilterElement) logs[0]).address); } @Test void getLogsTwiceFromBlockchainWithCallContractAndFilterByKnownTopicInListWithNull() throws Exception { addContractCall(); Block block1 = blockChain.getBlockByNumber(1l); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); - fr.setTopics(new Object[2]); - fr.getTopics()[0] = GET_VALUED_EVENT_SIGNATURE; - fr.getTopics()[1] = null; + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam("earliest"); + TopicParam[][] topics = new TopicParam[][]{{new TopicParam(GET_VALUED_EVENT_SIGNATURE)},{null}}; + + FilterRequestParam fr = new FilterRequestParam(blockIdentifierParam, null, null, topics, null); web3.eth_getLogs(fr); Object[] logs = web3.eth_getLogs(fr); assertNotNull(logs); String address = "0x" + ByteUtil.toHexString(block1.getTransactionsList().get(0).getContractAddress().getBytes()); assertEquals(1, logs.length); - assertEquals(address,((LogFilterElement)logs[0]).address); + assertEquals(address, ((LogFilterElement) logs[0]).address); } @Test void getLogsFromBlockchainWithCallContractAndFilterWithNullTopic() throws Exception { addContractCall(); Block block1 = blockChain.getBlockByNumber(1l); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); - fr.setTopics(new Object[1]); - fr.getTopics()[0] = null; + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam("earliest"); + TopicParam[][] topics = new TopicParam[][]{{null}}; + FilterRequestParam fr = new FilterRequestParam(blockIdentifierParam, null, null, topics, null); Object[] logs = web3.eth_getLogs(fr); assertNotNull(logs); @@ -780,10 +772,9 @@ void getLogsFromBlockchainWithCallContractAndFilterWithNullTopic() throws Except void getLogsTwiceFromBlockchainWithCallContractAndFilterWithNullTopic() throws Exception { addContractCall(); Block block1 = blockChain.getBlockByNumber(1l); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); - fr.setTopics(new Object[1]); - fr.getTopics()[0] = null; + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam("earliest"); + TopicParam[][] topics = new TopicParam[][]{{null}}; + FilterRequestParam fr = new FilterRequestParam(blockIdentifierParam, null, null, topics, null); web3.eth_getLogs(fr); Object[] logs = web3.eth_getLogs(fr); @@ -800,11 +791,9 @@ void getLogsTwiceFromBlockchainWithCallContractAndFilterWithNullTopic() throws E void getLogsFromBlockchainWithCallContractAndFilterWithTwoTopics() throws Exception { addContractCall(); Block block1 = blockChain.getBlockByNumber(1l); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); - fr.setTopics(new Object[2]); - fr.getTopics()[0] = INC_EVENT_SIGNATURE; - fr.getTopics()[1] = ONE_TOPIC; + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam("earliest"); + TopicParam[][] topics = new TopicParam[][]{{new TopicParam(INC_EVENT_SIGNATURE)},{new TopicParam(ONE_TOPIC)}}; + FilterRequestParam fr = new FilterRequestParam(blockIdentifierParam, null, null, topics, null); Object[] logs = web3.eth_getLogs(fr); assertNotNull(logs); @@ -820,11 +809,9 @@ void getLogsFromBlockchainWithCallContractAndFilterWithTwoTopics() throws Except void getLogsTwiceFromBlockchainWithCallContractAndFilterWithTwoTopics() throws Exception { addContractCall(); Block block1 = blockChain.getBlockByNumber(1l); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); - fr.setTopics(new Object[2]); - fr.getTopics()[0] = INC_EVENT_SIGNATURE; - fr.getTopics()[1] = ONE_TOPIC; + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam("earliest"); + TopicParam[][] topics = new TopicParam[][]{{new TopicParam(INC_EVENT_SIGNATURE)},{new TopicParam(ONE_TOPIC)}}; + FilterRequestParam fr = new FilterRequestParam(blockIdentifierParam, null, null, topics, null); web3.eth_getLogs(fr); Object[] logs = web3.eth_getLogs(fr); @@ -841,11 +828,9 @@ void getLogsTwiceFromBlockchainWithCallContractAndFilterWithTwoTopics() throws E void getLogsFromBlockchainWithCallContractAndFilterBySecondTopic() throws Exception { addContractCall(); Block block1 = blockChain.getBlockByNumber(1l); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); - fr.setTopics(new Object[2]); - fr.getTopics()[0] = null; - fr.getTopics()[1] = ONE_TOPIC; + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam("earliest"); + TopicParam[][] topics = new TopicParam[][]{{null},{new TopicParam(ONE_TOPIC)}}; + FilterRequestParam fr = new FilterRequestParam(blockIdentifierParam, null, null, topics, null); Object[] logs = web3.eth_getLogs(fr); assertNotNull(logs); @@ -861,11 +846,9 @@ void getLogsFromBlockchainWithCallContractAndFilterBySecondTopic() throws Except void getLogsTwiceFromBlockchainWithCallContractAndFilterBySecondTopic() throws Exception { addContractCall(); Block block1 = blockChain.getBlockByNumber(1l); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); - fr.setTopics(new Object[2]); - fr.getTopics()[0] = null; - fr.getTopics()[1] = ONE_TOPIC; + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam("earliest"); + TopicParam[][] topics = new TopicParam[][]{{null},{new TopicParam(ONE_TOPIC)}}; + FilterRequestParam fr = new FilterRequestParam(blockIdentifierParam, null, null, topics, null); web3.eth_getLogs(fr); Object[] logs = web3.eth_getLogs(fr); @@ -881,18 +864,17 @@ void getLogsTwiceFromBlockchainWithCallContractAndFilterBySecondTopic() throws E @Test void getLogsFromBlockchainWithEventInContractCreationReturnsAsExpectedWithBlockHashFilter() throws Exception { addEventInContractCreation(); - FilterRequest fr = new FilterRequest(); final String blockHash = TRACKED_TEST_BLOCK_HASH; - fr.setBlockHash(blockHash); + FilterRequestParam fr = new FilterRequestParam(null, null, null, null, new BlockHashParam(blockHash)); Object[] logs = web3.eth_getLogs(fr); assertNotNull(logs); assertEquals(1, logs.length); assertEquals(blockHash, ((LogFilterElement) logs[0]).blockHash); - String txhash = ((LogFilterElement)logs[0]).transactionHash; - TransactionReceiptDTO txdto = web3.eth_getTransactionReceipt(txhash); - assertEquals(txdto.getContractAddress(),((LogFilterElement)logs[0]).address); + String txhash = ((LogFilterElement) logs[0]).transactionHash; + TransactionReceiptDTO txdto = web3.eth_getTransactionReceipt(new TxHashParam(txhash)); + assertEquals(txdto.getContractAddress(), ((LogFilterElement) logs[0]).address); } @Test @@ -900,8 +882,8 @@ void getLogsWithBlockHashFilterForNonexistentBlockThrowsException() throws Excep final String blockHash = UNTRACKED_TEST_BLOCK_HASH; byte[] blockHashBytes = new Keccak256(HexUtils.stringHexToByteArray(blockHash)).getBytes(); assertFalse(blockChain.hasBlockInSomeBlockchain(blockHashBytes)); - FilterRequest fr = new FilterRequest(); - fr.setBlockHash(blockHash); + FilterRequestParam fr = new FilterRequestParam(null, null, null, null, new BlockHashParam(blockHash)); + Object[] logs = web3.eth_getLogs(fr); @@ -912,19 +894,14 @@ void getLogsWithBlockHashFilterForNonexistentBlockThrowsException() throws Excep @Test void getLogsThrowsExceptionWhenBlockHashIsUsedCombinedWithFromBlock() { addEventInContractCreation(); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); - fr.setBlockHash(TRACKED_TEST_BLOCK_HASH); - + FilterRequestParam fr = new FilterRequestParam(new BlockIdentifierParam("earliest"), null, null, null, new BlockHashParam(TRACKED_TEST_BLOCK_HASH)); Assertions.assertThrows(RskJsonRpcRequestException.class, () -> web3.eth_getLogs(fr)); } @Test void getLogsThrowsExceptionWhenBlockHashIsUsedCombinedWithToBlock() { addEventInContractCreation(); - FilterRequest fr = new FilterRequest(); - fr.setToBlock("latest"); - fr.setBlockHash(TRACKED_TEST_BLOCK_HASH); + FilterRequestParam fr = new FilterRequestParam(new BlockIdentifierParam("latest"), null, null, null, new BlockHashParam(TRACKED_TEST_BLOCK_HASH)); Assertions.assertThrows(RskJsonRpcRequestException.class, () -> web3.eth_getLogs(fr)); } @@ -932,12 +909,11 @@ void getLogsThrowsExceptionWhenBlockHashIsUsedCombinedWithToBlock() { @Test void createMainContractWithoutEvents() throws Exception { Account acc1 = new AccountBuilder(blockChain, - blockStore, - repositoryLocator).name("notDefault").balance(Coin.valueOf(10000000)).build(); + blockStore, + repositoryLocator).name("notDefault").balance(Coin.valueOf(10000000)).build(); web3.personal_newAccountWithSeed("notDefault"); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); + FilterRequestParam fr = new FilterRequestParam(new BlockIdentifierParam("earliest"), null, null, null, null); String id = web3.eth_newFilter(fr); Block genesis = blockChain.getBlockByNumber(0); @@ -947,11 +923,11 @@ void createMainContractWithoutEvents() throws Exception { List txs = new ArrayList<>(); txs.add(tx); Block block1 = new BlockBuilder(blockChain, null, - blockStore + blockStore ).trieStore(trieStore).parent(genesis).transactions(txs).build(); assertEquals(ImportResult.IMPORTED_BEST, blockChain.tryToConnect(block1)); - Object[] logs = web3.eth_getFilterChanges(id); + Object[] logs = web3.eth_getFilterChanges(new HexIndexParam(id)); assertNotNull(id); assertNotNull(logs); @@ -961,12 +937,11 @@ void createMainContractWithoutEvents() throws Exception { @Test void createCallerContractWithEvents() throws Exception { Account acc1 = new AccountBuilder(blockChain, - blockStore, - repositoryLocator).name("notDefault").balance(Coin.valueOf(10000000)).build(); + blockStore, + repositoryLocator).name("notDefault").balance(Coin.valueOf(10000000)).build(); web3.personal_newAccountWithSeed("notDefault"); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); + FilterRequestParam fr = new FilterRequestParam(new BlockIdentifierParam("earliest"), null, null, null, null); String id = web3.eth_newFilter(fr); Block genesis = blockChain.getBlockByNumber(0); @@ -976,7 +951,7 @@ void createCallerContractWithEvents() throws Exception { List txs = new ArrayList<>(); txs.add(tx); Block block1 = new BlockBuilder(blockChain, null, - blockStore + blockStore ).trieStore(trieStore).parent(genesis).transactions(txs).build(); assertEquals(ImportResult.IMPORTED_BEST, blockChain.tryToConnect(block1)); @@ -989,29 +964,28 @@ void createCallerContractWithEvents() throws Exception { List txs2 = new ArrayList<>(); txs2.add(tx2); Block block2 = new BlockBuilder(blockChain, null, - blockStore + blockStore ).trieStore(trieStore).parent(block1).transactions(txs2).build(); assertEquals(ImportResult.IMPORTED_BEST, blockChain.tryToConnect(block2)); - Object[] logs = web3.eth_getFilterChanges(id); + Object[] logs = web3.eth_getFilterChanges(new HexIndexParam(id)); assertNotNull(id); assertNotNull(logs); assertEquals(2, logs.length); - assertEquals("0x" + mainAddress, ((LogFilterElement)logs[0]).address); - assertEquals("0x" + callerAddress, ((LogFilterElement)logs[1]).address); + assertEquals("0x" + mainAddress, ((LogFilterElement) logs[0]).address); + assertEquals("0x" + callerAddress, ((LogFilterElement) logs[1]).address); } @Test void createCallerContractWithEventsOnInvoke() throws Exception { Account acc1 = new AccountBuilder(blockChain, - blockStore, - repositoryLocator).name("notDefault").balance(Coin.valueOf(10000000)).build(); + blockStore, + repositoryLocator).name("notDefault").balance(Coin.valueOf(10000000)).build(); web3.personal_newAccountWithSeed("notDefault"); - FilterRequest fr = new FilterRequest(); - fr.setFromBlock("earliest"); + FilterRequestParam fr = new FilterRequestParam(new BlockIdentifierParam("earliest"), null, null, null, null); String id = web3.eth_newFilter(fr); Block genesis = blockChain.getBlockByNumber(0); @@ -1021,7 +995,7 @@ void createCallerContractWithEventsOnInvoke() throws Exception { List txs = new ArrayList<>(); txs.add(tx); Block block1 = new BlockBuilder(blockChain, null, - blockStore + blockStore ).trieStore(trieStore).parent(genesis).transactions(txs).build(); assertEquals(ImportResult.IMPORTED_BEST, blockChain.tryToConnect(block1)); @@ -1034,7 +1008,7 @@ void createCallerContractWithEventsOnInvoke() throws Exception { List txs2 = new ArrayList<>(); txs2.add(tx2); Block block2 = new BlockBuilder(blockChain, null, - blockStore + blockStore ).trieStore(trieStore).parent(block1).transactions(txs2).build(); assertEquals(ImportResult.IMPORTED_BEST, blockChain.tryToConnect(block2)); @@ -1044,26 +1018,26 @@ void createCallerContractWithEventsOnInvoke() throws Exception { List txs3 = new ArrayList<>(); txs3.add(tx3); Block block3 = new BlockBuilder(blockChain, null, - blockStore + blockStore ).trieStore(trieStore).parent(block2).transactions(txs3).build(); assertEquals(ImportResult.IMPORTED_BEST, blockChain.tryToConnect(block3)); - Object[] logs = web3.eth_getFilterChanges(id); + Object[] logs = web3.eth_getFilterChanges(new HexIndexParam(id)); assertNotNull(id); assertNotNull(logs); assertEquals(3, logs.length); - assertEquals("0x" + mainAddress, ((LogFilterElement)logs[0]).address); - assertEquals("0x" + callerAddress, ((LogFilterElement)logs[1]).address); - assertEquals("0x" + mainAddress, ((LogFilterElement)logs[2]).address); + assertEquals("0x" + mainAddress, ((LogFilterElement) logs[0]).address); + assertEquals("0x" + callerAddress, ((LogFilterElement) logs[1]).address); + assertEquals("0x" + mainAddress, ((LogFilterElement) logs[2]).address); } @Test void createCallerContractWithEventsOnInvokeUsingGetFilterLogs() throws Exception { Account acc1 = new AccountBuilder(blockChain, - blockStore, - repositoryLocator).name("notDefault").balance(Coin.valueOf(10000000)).build(); + blockStore, + repositoryLocator).name("notDefault").balance(Coin.valueOf(10000000)).build(); web3.personal_newAccountWithSeed("notDefault"); Block genesis = blockChain.getBlockByNumber(0); @@ -1073,7 +1047,7 @@ void createCallerContractWithEventsOnInvokeUsingGetFilterLogs() throws Exception List txs = new ArrayList<>(); txs.add(tx); Block block1 = new BlockBuilder(blockChain, null, - blockStore + blockStore ).trieStore(trieStore).parent(genesis).transactions(txs).build(); assertEquals(ImportResult.IMPORTED_BEST, blockChain.tryToConnect(block1)); @@ -1085,7 +1059,7 @@ void createCallerContractWithEventsOnInvokeUsingGetFilterLogs() throws Exception List txs2 = new ArrayList<>(); txs2.add(tx2); Block block2 = new BlockBuilder(blockChain, null, - blockStore + blockStore ).trieStore(trieStore).parent(block1).transactions(txs2).build(); assertEquals(ImportResult.IMPORTED_BEST, blockChain.tryToConnect(block2)); @@ -1095,21 +1069,21 @@ void createCallerContractWithEventsOnInvokeUsingGetFilterLogs() throws Exception List txs3 = new ArrayList<>(); txs3.add(tx3); Block block3 = new BlockBuilder(blockChain, null, - blockStore + blockStore ).trieStore(trieStore).parent(block2).transactions(txs3).build(); assertEquals(ImportResult.IMPORTED_BEST, blockChain.tryToConnect(block3)); - FilterRequest fr = new FilterRequest(); - fr.setAddress( "0x" + mainAddress); + HexAddressParam[] address = new HexAddressParam[]{new HexAddressParam("0x" + mainAddress)}; + FilterRequestParam fr = new FilterRequestParam(null, null, address, null, null); String id = web3.eth_newFilter(fr); - Object[] logs = web3.eth_getFilterLogs(id); + Object[] logs = web3.eth_getFilterLogs(new HexIndexParam(id)); assertNotNull(id); assertNotNull(logs); assertEquals(1, logs.length); - assertEquals("0x" + mainAddress, ((LogFilterElement)logs[0]).address); + assertEquals("0x" + mainAddress, ((LogFilterElement) logs[0]).address); } private Web3Impl createWeb3() { @@ -1159,11 +1133,11 @@ null, new EthModuleWalletEnabled(wallet), null, private void addTwoEmptyBlocks() { Block genesis = blockChain.getBlockByNumber(0); Block block1 = new BlockBuilder(blockChain, null, - blockStore + blockStore ).trieStore(trieStore).parent(genesis).build(); assertEquals(ImportResult.IMPORTED_BEST, blockChain.tryToConnect(block1)); Block block2 = new BlockBuilder(blockChain, null, - blockStore + blockStore ).trieStore(trieStore).parent(block1).build(); assertEquals(ImportResult.IMPORTED_BEST, blockChain.tryToConnect(block2)); assertEquals(3, blockChain.getSize()); @@ -1173,8 +1147,8 @@ private void addTwoEmptyBlocks() { private void addContractCreationWithoutEvents() { Account acc1 = new AccountBuilder(blockChain, - blockStore, - repositoryLocator).name("notDefault").balance(Coin.valueOf(10000000)).build(); + blockStore, + repositoryLocator).name("notDefault").balance(Coin.valueOf(10000000)).build(); Block genesis = blockChain.getBlockByNumber(0); @@ -1201,7 +1175,7 @@ function greet(string param) onlyOwner constant returns (string) { List txs = new ArrayList<>(); txs.add(tx); Block block1 = new BlockBuilder(blockChain, null, - blockStore + blockStore ).trieStore(trieStore).parent(genesis).transactions(txs).build(); assertEquals(ImportResult.IMPORTED_BEST, blockChain.tryToConnect(block1)); @@ -1219,7 +1193,7 @@ public static void addEmptyBlockToBlockchain( BlockStore blockStore, RepositoryLocator repositoryLocator, TrieStore trieStore) { - Account acc1 = new AccountBuilder(blockChain,blockStore,repositoryLocator) + Account acc1 = new AccountBuilder(blockChain, blockStore, repositoryLocator) .name("notDefault").balance(Coin.valueOf(10000000)).build(); Block genesis = blockChain.getBlockByNumber(0); @@ -1235,8 +1209,8 @@ public static void addEmptyBlockToBlockchain( private void addContractInvoke() { Account acc1 = new AccountBuilder(blockChain, - blockStore, - repositoryLocator).name("notDefault").balance(Coin.valueOf(10000000)).build(); + blockStore, + repositoryLocator).name("notDefault").balance(Coin.valueOf(10000000)).build(); Block genesis = blockChain.getBlockByNumber(0); Transaction tx; @@ -1341,14 +1315,14 @@ private void addContractCall() { } private static Transaction getContractTransaction(Account acc1) { - return getContractTransaction(acc1,false); + return getContractTransaction(acc1, false); } //0.4.11+commit.68ef5810.Emscripten.clang WITH optimizations static final String compiled_0_4_11 = "6060604052341561000c57fe5b5b60466000819055507f06acbfb32bcf8383f3b0a768b70ac9ec234ea0f2d3b9c77fa6a2de69b919aad16000546040518082815260200191505060405180910390a15b5b61014e8061005f6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680632096525514610046578063371303c01461006c575bfe5b341561004e57fe5b61005661007e565b6040518082815260200191505060405180910390f35b341561007457fe5b61007c6100c2565b005b60007f1ee041944547858a75ebef916083b6d4f5ae04bea9cd809334469dd07dbf441b6000546040518082815260200191505060405180910390a160005490505b90565b60006000815460010191905081905550600160026000548115156100e257fe5b061415157f6e61ef44ac2747ff8b84d353a908eb8bd5c3fb118334d57698c5cfc7041196ad6000546040518082815260200191505060405180910390a25b5600a165627a7a7230582092c7b2c0483b85227396e18149993b33243059af0f3bd0364f1dc36b8bbbcdae0029"; static final String compiled_unknown = "60606040526046600081905560609081527f06acbfb32bcf8383f3b0a768b70ac9ec234ea0f2d3b9c77fa6a2de69b919aad190602090a160aa8060426000396000f3606060405260e060020a60003504632096525581146024578063371303c0146060575b005b60a36000805460609081527f1ee041944547858a75ebef916083b6d4f5ae04bea9cd809334469dd07dbf441b90602090a1600060005054905090565b6022600080546001908101918290556060828152600290920614907f6e61ef44ac2747ff8b84d353a908eb8bd5c3fb118334d57698c5cfc7041196ad90602090a2565b5060206060f3"; - private static Transaction getContractTransaction(Account acc1,boolean withEvent) { + private static Transaction getContractTransaction(Account acc1, boolean withEvent) { /* contract compiled in data attribute of tx contract counter { event Incremented(bool indexed odd, uint x); @@ -1402,7 +1376,8 @@ private static Transaction getContractTransactionWithCall(Account acc1, byte[] r .build(); } - String compiledLogExample ="606060405234610000575b60bd806100186000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063195977a614603c575b6000565b34600057605460048080359060200190919050506056565b005b7ffd99bb34477b313b3e3b452b34d012d8315db36a1d63949d9d8f9d2573b05aff816040518082815260200191505060405180910390a15b505600a165627a7a72305820fb2550735b0655fb2fe03738be375a4c29ef1b6ff51004f869be19de0301f30b0029"; + String compiledLogExample = "606060405234610000575b60bd806100186000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063195977a614603c575b6000565b34600057605460048080359060200190919050506056565b005b7ffd99bb34477b313b3e3b452b34d012d8315db36a1d63949d9d8f9d2573b05aff816040518082815260200191505060405180910390a15b505600a165627a7a72305820fb2550735b0655fb2fe03738be375a4c29ef1b6ff51004f869be19de0301f30b0029"; + private Transaction getMainContractTransaction(Account acc1) { /* contract compiled in data attribute of tx contract main { @@ -1448,7 +1423,7 @@ function doSomething(address mainAddr) { .sender(acc1) .gasLimit(BigInteger.valueOf(1000000)) .gasPrice(BigInteger.ONE) - .data( compiledCaller + address) + .data(compiledCaller + address) .nonce(1) .build(); } @@ -1459,7 +1434,7 @@ private static Transaction getCallerContractTransactionWithInvoke(Account acc1, while (address.length() < 64) address = "0" + address; - CallTransaction.Function func = CallTransaction.Function.fromSignature("doSomething", new String[] { "address" }, new String[0]); + CallTransaction.Function func = CallTransaction.Function.fromSignature("doSomething", new String[]{"address"}, new String[0]); return new TransactionBuilder() .sender(acc1) @@ -1470,4 +1445,8 @@ private static Transaction getCallerContractTransactionWithInvoke(Account acc1, .nonce(2) .build(); } + + private TopicParam[][] initTopicsArray(String topic) { + return new TopicParam[][]{{new TopicParam(topic)}}; + } } diff --git a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java index f0e17ed66c6..f8ac098dfff 100644 --- a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java +++ b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java @@ -26,8 +26,6 @@ import co.rsk.core.bc.TransactionPoolImpl; import co.rsk.crypto.Keccak256; import co.rsk.db.RepositoryLocator; -import co.rsk.logfilter.BlocksBloomStore; -import co.rsk.metrics.HashRateCalculator; import co.rsk.mine.MinerClient; import co.rsk.mine.MinerServer; import co.rsk.net.BlockProcessor; @@ -44,17 +42,13 @@ import co.rsk.rpc.modules.eth.EthModule; import co.rsk.rpc.modules.eth.EthModuleTransactionBase; import co.rsk.rpc.modules.eth.EthModuleWalletEnabled; -import co.rsk.rpc.modules.evm.EvmModule; -import co.rsk.rpc.modules.mnr.MnrModule; import co.rsk.rpc.modules.personal.PersonalModule; import co.rsk.rpc.modules.personal.PersonalModuleWalletDisabled; import co.rsk.rpc.modules.personal.PersonalModuleWalletEnabled; import co.rsk.rpc.modules.rsk.RskModule; import co.rsk.rpc.modules.rsk.RskModuleImpl; -import co.rsk.rpc.modules.trace.TraceModule; import co.rsk.rpc.modules.txpool.TxPoolModule; import co.rsk.rpc.modules.txpool.TxPoolModuleImpl; -import co.rsk.scoring.PeerScoringManager; import co.rsk.test.World; import co.rsk.test.builders.AccountBuilder; import co.rsk.test.builders.BlockBuilder; @@ -84,8 +78,10 @@ import org.ethereum.rpc.dto.TransactionReceiptDTO; import org.ethereum.rpc.dto.TransactionResultDTO; import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.ethereum.rpc.parameters.*; import org.ethereum.util.BuildInfo; import org.ethereum.util.ByteUtil; +import org.ethereum.util.TransactionFactoryHelper; import org.ethereum.vm.PrecompiledContracts; import org.ethereum.vm.program.ProgramResult; import org.ethereum.vm.program.invoke.ProgramInvokeFactoryImpl; @@ -222,7 +218,7 @@ void getBalanceWithAccount() { Web3Impl web3 = createWeb3(world); - assertEquals(BALANCE_10K_HEX, web3.eth_getBalance(ByteUtil.toHexString(acc1.getAddress().getBytes()))); + assertEquals(BALANCE_10K_HEX, web3.eth_getBalance(new HexAddressParam(ByteUtil.toHexString(acc1.getAddress().getBytes())))); } @Test @@ -232,7 +228,9 @@ void getBalanceWithAccountAndLatestBlock() { Web3Impl web3 = createWeb3(world); - assertEquals(BALANCE_10K_HEX, web3.eth_getBalance(ByteUtil.toHexString(acc1.getAddress().getBytes()), "latest")); + assertEquals(BALANCE_10K_HEX, web3.eth_getBalance( + new HexAddressParam(ByteUtil.toHexString(acc1.getAddress().getBytes())), + new BlockRefParam("latest"))); } @Test @@ -244,7 +242,7 @@ void getBalanceWithAccountAndGenesisBlock() { String accountAddress = ByteUtil.toHexString(acc1.getAddress().getBytes()); - assertEquals(BALANCE_10K_HEX, web3.eth_getBalance(accountAddress, "0x0")); + assertEquals(BALANCE_10K_HEX, web3.eth_getBalance(new HexAddressParam(accountAddress), new BlockRefParam("0x0"))); } @Test @@ -257,42 +255,42 @@ void getBalanceWithAccountAndBlock() { String accountAddress = ByteUtil.toHexString(acc1.getAddress().getBytes()); - assertEquals(BALANCE_10K_HEX, web3.eth_getBalance(accountAddress, "0x1")); + assertEquals(BALANCE_10K_HEX, web3.eth_getBalance(new HexAddressParam(accountAddress), new BlockRefParam("0x1"))); } @Test //[ "0x
", { "blockNumber": "0x0" } -> return balance at given address in genesis block void getBalanceWithAccountAndBlockNumber() { final ChainParams chain = chainWithAccount10kBalance(false); - assertByBlockNumber(BALANCE_10K_HEX, blockRef -> chain.web3.eth_getBalance(chain.accountAddress, blockRef)); + assertByBlockNumber(BALANCE_10K_HEX, blockRef -> chain.web3.eth_getBalance(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @Test //[ "0x
", { "invalidInput": "0x0" } -> throw RskJsonRpcRequestException void getBalanceWithAccountAndInvalidInputThrowsException() { final ChainParams chain = chainWithAccount10kBalance(false); - assertInvalidInput(blockRef -> chain.web3.eth_getBalance(chain.accountAddress, blockRef)); + assertInvalidInput(blockRef -> chain.web3.eth_getBalance(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @Test //[ "0x
", { "blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3" } -> return balance at given address in genesis block void getBalanceWithAccountAndBlockHash() { final ChainParams chain = chainWithAccount10kBalance(false); - assertByBlockHash(BALANCE_10K_HEX, chain.block, blockRef -> chain.web3.eth_getBalance(chain.accountAddress, blockRef)); + assertByBlockHash(BALANCE_10K_HEX, chain.block, blockRef -> chain.web3.eth_getBalance(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @Test //[ "0x
", { "blockHash": "0x" } -> raise block-not-found error void getBalanceWithAccountAndNonExistentBlockHash() { final ChainParams chain = chainWithAccount10kBalance(false); - assertNonExistentBlockHash(blockRef -> chain.web3.eth_getBalance(chain.accountAddress, blockRef)); + assertNonExistentBlockHash(blockRef -> chain.web3.eth_getBalance(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @Test //[ "0x
", { "blockHash": "0x", "requireCanonical": true } -> raise block-not-found error void getBalanceWithAccountAndNonExistentBlockHashWhenCanonicalIsRequired() { final ChainParams chain = chainWithAccount10kBalance(false); - assertNonBlockHashWhenCanonical(blockRef -> chain.web3.eth_getBalance(chain.accountAddress, blockRef)); + assertNonBlockHashWhenCanonical(blockRef -> chain.web3.eth_getBalance(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @@ -300,14 +298,14 @@ void getBalanceWithAccountAndNonExistentBlockHashWhenCanonicalIsRequired() { //[ "0x
", { "blockHash": "0x", "requireCanonical": false } -> raise block-not-found error void getBalanceWithAccountAndNonExistentBlockHashWhenCanonicalIsNotRequired() { final ChainParams chain = chainWithAccount10kBalance(false); - assertNonBlockHashWhenIsNotCanonical(blockRef -> chain.web3.eth_getBalance(chain.accountAddress, blockRef)); + assertNonBlockHashWhenIsNotCanonical(blockRef -> chain.web3.eth_getBalance(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @Test // [ "0x
", { "blockHash": "0x", "requireCanonical": true } -> raise block-not-canonical error void getBalanceWithAccountAndNonCanonicalBlockHashWhenCanonicalIsRequired() { final ChainParams chain = chainWithAccount10kBalance(true); - assertNonCanonicalBlockHashWhenCanonical(chain.block, blockRef -> chain.web3.eth_getBalance(chain.accountAddress, blockRef)); + assertNonCanonicalBlockHashWhenCanonical(chain.block, blockRef -> chain.web3.eth_getBalance(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @@ -315,28 +313,28 @@ void getBalanceWithAccountAndNonCanonicalBlockHashWhenCanonicalIsRequired() { //[ "0x
", { "blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3", "requireCanonical": true } -> return balance at given address in genesis block void getBalanceWithAccountAndCanonicalBlockHashWhenCanonicalIsRequired() { final ChainParams chain = chainWithAccount10kBalance(false); - assertCanonicalBlockHashWhenCanonical(BALANCE_10K_HEX, chain.block, blockRef -> chain.web3.eth_getBalance(chain.accountAddress, blockRef)); + assertCanonicalBlockHashWhenCanonical(BALANCE_10K_HEX, chain.block, blockRef -> chain.web3.eth_getBalance(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @Test //[ "0x
", { "blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3", "requireCanonical": false } -> return balance at given address in genesis block void getBalanceWithAccountAndCanonicalBlockHashWhenCanonicalIsNotRequired() { final ChainParams chain = chainWithAccount10kBalance(false); - assertCanonicalBlockHashWhenNotCanonical(BALANCE_10K_HEX, chain.block, blockRef -> chain.web3.eth_getBalance(chain.accountAddress, blockRef)); + assertCanonicalBlockHashWhenNotCanonical(BALANCE_10K_HEX, chain.block, blockRef -> chain.web3.eth_getBalance(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @Test // [ "0x
", { "blockHash": "0x", "requireCanonical": false } -> return balance at given address in specified block void getBalanceWithAccountAndNonCanonicalBlockHashWhenCanonicalIsNotRequired() { final ChainParams chain = chainWithAccount10kBalance(true); - assertNonCanonicalBlockHashWhenNotCanonical(BALANCE_10K_HEX, chain.block, blockRef -> chain.web3.eth_getBalance(chain.accountAddress, blockRef)); + assertNonCanonicalBlockHashWhenNotCanonical(BALANCE_10K_HEX, chain.block, blockRef -> chain.web3.eth_getBalance(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @Test // [ "0x
", { "blockHash": "0x" } -> return balance at given address in specified bloc void getBalanceWithAccountAndNonCanonicalBlockHash() { final ChainParams chain = chainWithAccount10kBalance(true); - assertNonCanonicalBlockHash(BALANCE_10K_HEX, chain.block, blockRef -> chain.web3.eth_getBalance(chain.accountAddress, blockRef)); + assertNonCanonicalBlockHash(BALANCE_10K_HEX, chain.block, blockRef -> chain.web3.eth_getBalance(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @Test @@ -360,30 +358,39 @@ void getBalanceWithAccountAndBlockWithTransaction() { String accountAddress = ByteUtil.toHexString(acc2.getAddress().getBytes()); String balanceString = BALANCE_10K_HEX; - assertEquals("0x0", web3.eth_getBalance(accountAddress, "0x0")); - assertEquals(balanceString, web3.eth_getBalance(accountAddress, "0x1")); - assertEquals(balanceString, web3.eth_getBalance(accountAddress, "pending")); + assertEquals("0x0", web3.eth_getBalance(new HexAddressParam(accountAddress), new BlockRefParam("0x0"))); + assertEquals(balanceString, web3.eth_getBalance(new HexAddressParam(accountAddress), new BlockRefParam("0x1"))); + assertEquals(balanceString, web3.eth_getBalance(new HexAddressParam(accountAddress), new BlockRefParam("pending"))); } @Test //[ "0x
", { "blockNumber": "0x0" } -> return storage at given address in genesis block void getStorageAtAccountAndBlockNumber() { final ChainParams chain = chainWithAccount10kBalance(false); - assertByBlockNumber("0x0", blockRef -> chain.web3.eth_getStorageAt(chain.accountAddress, "0x0", blockRef)); + assertByBlockNumber("0x0", blockRef -> chain.web3.eth_getStorageAt( + new HexAddressParam(chain.accountAddress), + new HexNumberParam("0x0"), + new BlockRefParam(blockRef))); } @Test //[ "0x
", { "blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3" } -> return storage at given address in genesis block void getStorageAtAccountAndBlockHash() { final ChainParams chain = chainWithAccount10kBalance(false); - assertByBlockHash("0x0", chain.block, blockRef -> chain.web3.eth_getStorageAt(chain.accountAddress, "0x0", blockRef)); + assertByBlockHash("0x0", chain.block, blockRef -> chain.web3.eth_getStorageAt( + new HexAddressParam(chain.accountAddress), + new HexNumberParam("0x0"), + new BlockRefParam(blockRef))); } @Test //[ "0x
", { "blockHash": "0x" } -> raise block-not-found error void getStorageAtAccountAndNonExistentBlockHash() { final ChainParams chain = chainWithAccount10kBalance(false); - assertNonExistentBlockHash(blockRef -> chain.web3.eth_getStorageAt(chain.accountAddress, "0x0", blockRef)); + assertNonExistentBlockHash(blockRef -> chain.web3.eth_getStorageAt( + new HexAddressParam(chain.accountAddress), + new HexNumberParam("0x0"), + new BlockRefParam(blockRef))); } @@ -391,49 +398,70 @@ void getStorageAtAccountAndNonExistentBlockHash() { //[ "0x
", { "blockHash": "0x", "requireCanonical": true } -> raise block-not-found error void getStorageAtAccountAndNonExistentBlockHashWhenCanonicalIsRequired() { final ChainParams chain = chainWithAccount10kBalance(false); - assertNonBlockHashWhenCanonical(blockRef -> chain.web3.eth_getStorageAt(chain.accountAddress, "0x0", blockRef)); + assertNonBlockHashWhenCanonical(blockRef -> chain.web3.eth_getStorageAt( + new HexAddressParam(chain.accountAddress), + new HexNumberParam("0x0"), + new BlockRefParam(blockRef))); } @Test //[ "0x
", { "blockHash": "0x", "requireCanonical": false } -> raise block-not-found error void getStorageAtAccountAndNonExistentBlockHashWhenCanonicalIsNotRequired() { final ChainParams chain = chainWithAccount10kBalance(false); - assertNonBlockHashWhenIsNotCanonical(blockRef -> chain.web3.eth_getStorageAt(chain.accountAddress, "0x0", blockRef)); + assertNonBlockHashWhenIsNotCanonical(blockRef -> chain.web3.eth_getStorageAt( + new HexAddressParam(chain.accountAddress), + new HexNumberParam("0x0"), + new BlockRefParam(blockRef))); } @Test // [ "0x
", { "blockHash": "0x", "requireCanonical": true } -> raise block-not-canonical error void getStorageAtAccountAndNonCanonicalBlockHashWhenCanonicalIsRequired() { final ChainParams chain = chainWithAccount10kBalance(true); - assertNonCanonicalBlockHashWhenCanonical(chain.block, blockRef -> chain.web3.eth_getStorageAt(chain.accountAddress, "0x0", blockRef)); + assertNonCanonicalBlockHashWhenCanonical(chain.block, blockRef -> chain.web3.eth_getStorageAt( + new HexAddressParam(chain.accountAddress), + new HexNumberParam("0x0"), + new BlockRefParam(blockRef))); } @Test //[ "0x
", { "blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3", "requireCanonical": true } -> return storage at given address in genesis block void getStorageAtAccountAndCanonicalBlockHashWhenCanonicalIsRequired() { final ChainParams chain = chainWithAccount10kBalance(false); - assertCanonicalBlockHashWhenCanonical("0x0", chain.block, blockRef -> chain.web3.eth_getStorageAt(chain.accountAddress, "0x0", blockRef)); + assertCanonicalBlockHashWhenCanonical("0x0", chain.block, blockRef -> chain.web3.eth_getStorageAt( + new HexAddressParam(chain.accountAddress), + new HexNumberParam("0x0"), + new BlockRefParam(blockRef))); } @Test //[ "0x
", { "blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3", "requireCanonical": false } -> return storage at given address in genesis block void getStorageAtAccountAndCanonicalBlockHashWhenCanonicalIsNotRequired() { final ChainParams chain = chainWithAccount10kBalance(false); - assertCanonicalBlockHashWhenNotCanonical("0x0", chain.block, blockRef -> chain.web3.eth_getStorageAt(chain.accountAddress, "0x0", blockRef)); + assertCanonicalBlockHashWhenNotCanonical("0x0", chain.block, blockRef -> chain.web3.eth_getStorageAt( + new HexAddressParam(chain.accountAddress), + new HexNumberParam("0x0"), + new BlockRefParam(blockRef))); } @Test // [ "0x
", { "blockHash": "0x", "requireCanonical": false } -> return storage at given address in specified block void getStorageAtAccountAndNonCanonicalBlockHashWhenCanonicalIsNotRequired() { final ChainParams chain = chainWithAccount10kBalance(true); - assertNonCanonicalBlockHashWhenNotCanonical("0x0", chain.block, blockRef -> chain.web3.eth_getStorageAt(chain.accountAddress, "0x0", blockRef)); + assertNonCanonicalBlockHashWhenNotCanonical("0x0", chain.block, blockRef -> chain.web3.eth_getStorageAt( + new HexAddressParam(chain.accountAddress), + new HexNumberParam("0x0"), + new BlockRefParam(blockRef))); } @Test // [ "0x
", { "blockHash": "0x" } -> return storage at given address in specified bloc void getStorageAtAccountAndNonCanonicalBlockHash() { final ChainParams chain = chainWithAccount10kBalance(true); - assertNonCanonicalBlockHash("0x0", chain.block, blockRef -> chain.web3.eth_getStorageAt(chain.accountAddress, "0x0", blockRef)); + assertNonCanonicalBlockHash("0x0", chain.block, blockRef -> chain.web3.eth_getStorageAt( + new HexAddressParam(chain.accountAddress), + new HexNumberParam("0x0"), + new BlockRefParam(blockRef))); } @@ -441,140 +469,140 @@ void getStorageAtAccountAndNonCanonicalBlockHash() { //[ "0x
", { "blockNumber": "0x0" } -> return code at given address in genesis block void getCodeAtAccountAndBlockNumber() { final ChainParams chain = createChainWithAContractCode(false); - assertByBlockNumber("0x010203", blockRef -> chain.web3.eth_getCode(chain.accountAddress, blockRef)); + assertByBlockNumber("0x010203", blockRef -> chain.web3.eth_getCode(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @Test //[ "0x
", { "blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3" } -> return code at given address in genesis block void getCodeAtAccountAndBlockHash() { final ChainParams chain = createChainWithAContractCode(false); - assertByBlockHash("0x010203", chain.block, blockRef -> chain.web3.eth_getCode(chain.accountAddress, blockRef)); + assertByBlockHash("0x010203", chain.block, blockRef -> chain.web3.eth_getCode(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @Test //[ "0x
", { "blockHash": "0x" } -> raise block-not-found error void getCodeAtAccountAndNonExistentBlockHash() { final ChainParams chain = createChainWithAContractCode(false); - assertNonExistentBlockHash(blockRef -> chain.web3.eth_getCode(chain.accountAddress, blockRef)); + assertNonExistentBlockHash(blockRef -> chain.web3.eth_getCode(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @Test //[ "0x
", { "blockHash": "0x", "requireCanonical": true } -> raise block-not-found error void getCodeAtAccountAndNonExistentBlockHashWhenCanonicalIsRequired() { final ChainParams chain = createChainWithAContractCode(false); - assertNonBlockHashWhenCanonical(blockRef -> chain.web3.eth_getCode(chain.accountAddress, blockRef)); + assertNonBlockHashWhenCanonical(blockRef -> chain.web3.eth_getCode(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @Test //[ "0x
", { "blockHash": "0x", "requireCanonical": false } -> raise block-not-found error void getCodeAtAccountAndNonExistentBlockHashWhenCanonicalIsNotRequired() { final ChainParams chain = createChainWithAContractCode(false); - assertNonBlockHashWhenIsNotCanonical(blockRef -> chain.web3.eth_getCode(chain.accountAddress, blockRef)); + assertNonBlockHashWhenIsNotCanonical(blockRef -> chain.web3.eth_getCode(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @Test // [ "0x
", { "blockHash": "0x", "requireCanonical": true } -> raise block-not-canonical error void getCodeAtAccountAndNonCanonicalBlockHashWhenCanonicalIsRequired() { final ChainParams chain = createChainWithAContractCode(true); - assertNonCanonicalBlockHashWhenCanonical(chain.block, blockRef -> chain.web3.eth_getCode(chain.accountAddress, blockRef)); + assertNonCanonicalBlockHashWhenCanonical(chain.block, blockRef -> chain.web3.eth_getCode(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @Test //[ "0x
", { "blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3", "requireCanonical": true } -> return code at given address in genesis block void getCodeAtAccountAndCanonicalBlockHashWhenCanonicalIsRequired() { final ChainParams chain = createChainWithAContractCode(false); - assertCanonicalBlockHashWhenCanonical("0x010203", chain.block, blockRef -> chain.web3.eth_getCode(chain.accountAddress, blockRef)); + assertCanonicalBlockHashWhenCanonical("0x010203", chain.block, blockRef -> chain.web3.eth_getCode(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @Test //[ "0x
", { "blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3", "requireCanonical": false } -> return code at given address in genesis block void getCodeAtAccountAndCanonicalBlockHashWhenCanonicalIsNotRequired() { final ChainParams chain = createChainWithAContractCode(false); - assertCanonicalBlockHashWhenNotCanonical("0x010203", chain.block, blockRef -> chain.web3.eth_getCode(chain.accountAddress, blockRef)); + assertCanonicalBlockHashWhenNotCanonical("0x010203", chain.block, blockRef -> chain.web3.eth_getCode(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @Test // [ "0x
", { "blockHash": "0x", "requireCanonical": false } -> return code at given address in specified block void getCodeAtAccountAndNonCanonicalBlockHashWhenCanonicalIsNotRequired() { final ChainParams chain = createChainWithAContractCode(true); - assertNonCanonicalBlockHashWhenNotCanonical("0x010203", chain.block, blockRef -> chain.web3.eth_getCode(chain.accountAddress, blockRef)); + assertNonCanonicalBlockHashWhenNotCanonical("0x010203", chain.block, blockRef -> chain.web3.eth_getCode(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @Test // [ "0x
", { "blockHash": "0x" } -> return code at given address in specified bloc void getCodeAtAccountAndNonCanonicalBlockHash() { final ChainParams chain = createChainWithAContractCode(true); - assertNonCanonicalBlockHash("0x010203", chain.block, blockRef -> chain.web3.eth_getCode(chain.accountAddress, blockRef)); + assertNonCanonicalBlockHash("0x010203", chain.block, blockRef -> chain.web3.eth_getCode(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @Test //[ {argsForCall}, { "blockNumber": "0x0" } -> return contract call respond at given args for call in genesis block void callByBlockNumber() { final ChainParams chain = createChainWithACall(false); - assertByBlockNumber(CALL_RESPOND, blockRef -> chain.web3.eth_call(chain.argsForCall, blockRef)); + assertByBlockNumber(CALL_RESPOND, blockRef -> chain.web3.eth_call(TransactionFactoryHelper.toCallArgumentsParam(chain.argsForCall), blockRef)); } @Test //[ {argsForCall}, { "blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3" } -> return contract call respond at given address in genesis block void callByBlockHash() { final ChainParams chain = createChainWithACall(false); - assertByBlockHash(CALL_RESPOND, chain.block, blockRef -> chain.web3.eth_call(chain.argsForCall, blockRef)); + assertByBlockHash(CALL_RESPOND, chain.block, blockRef -> chain.web3.eth_call(TransactionFactoryHelper.toCallArgumentsParam(chain.argsForCall), blockRef)); } @Test //[ {argsForCall}, { "blockHash": "0x" } -> raise block-not-found error void callByNonExistentBlockHash() { final ChainParams chain = createChainWithACall(false); - assertNonExistentBlockHash(blockRef -> chain.web3.eth_call(chain.argsForCall, blockRef)); + assertNonExistentBlockHash(blockRef -> chain.web3.eth_call(TransactionFactoryHelper.toCallArgumentsParam(chain.argsForCall), blockRef)); } @Test //[ {argsForCall}, { "blockHash": "0x", "requireCanonical": true } -> raise block-not-found error void callByNonExistentBlockHashWhenCanonicalIsRequired() { final ChainParams chain = createChainWithACall(false); - assertNonBlockHashWhenCanonical(blockRef -> chain.web3.eth_call(chain.argsForCall, blockRef)); + assertNonBlockHashWhenCanonical(blockRef -> chain.web3.eth_call(TransactionFactoryHelper.toCallArgumentsParam(chain.argsForCall), blockRef)); } @Test //[ {argsForCall}, { "blockHash": "0x", "requireCanonical": false } -> raise block-not-found error void callByNonExistentBlockHashWhenCanonicalIsNotRequired() { final ChainParams chain = createChainWithACall(false); - assertNonBlockHashWhenIsNotCanonical(blockRef -> chain.web3.eth_call(chain.argsForCall, blockRef)); + assertNonBlockHashWhenIsNotCanonical(blockRef -> chain.web3.eth_call(TransactionFactoryHelper.toCallArgumentsParam(chain.argsForCall), blockRef)); } @Test // [ {argsForCall} { "blockHash": "0x", "requireCanonical": true } -> raise block-not-canonical error void callByNonCanonicalBlockHashWhenCanonicalIsRequired() { final ChainParams chain = createChainWithACall(true); - assertNonCanonicalBlockHashWhenCanonical(chain.block, blockRef -> chain.web3.eth_call(chain.argsForCall, blockRef)); + assertNonCanonicalBlockHashWhenCanonical(chain.block, blockRef -> chain.web3.eth_call(TransactionFactoryHelper.toCallArgumentsParam(chain.argsForCall), blockRef)); } @Test //[ {argsForCall}, { "blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3", "requireCanonical": true } -> return contract call respond at given address in genesis block void callByCanonicalBlockHashWhenCanonicalIsRequired() { final ChainParams chain = createChainWithACall(false); - assertCanonicalBlockHashWhenCanonical(CALL_RESPOND, chain.block, blockRef -> chain.web3.eth_call(chain.argsForCall, blockRef)); + assertCanonicalBlockHashWhenCanonical(CALL_RESPOND, chain.block, blockRef -> chain.web3.eth_call(TransactionFactoryHelper.toCallArgumentsParam(chain.argsForCall), blockRef)); } @Test //[ {argsForCall}, { "blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3", "requireCanonical": false } -> return contract call respond at given address in genesis block void callByCanonicalBlockHashWhenCanonicalIsNotRequired() { final ChainParams chain = createChainWithACall(false); - assertCanonicalBlockHashWhenNotCanonical(CALL_RESPOND, chain.block, blockRef -> chain.web3.eth_call(chain.argsForCall, blockRef)); + assertCanonicalBlockHashWhenNotCanonical(CALL_RESPOND, chain.block, blockRef -> chain.web3.eth_call(TransactionFactoryHelper.toCallArgumentsParam(chain.argsForCall), blockRef)); } @Test // [ {argsForCall}, { "blockHash": "0x", "requireCanonical": false } -> return contract call respond at given address in specified block void callByNonCanonicalBlockHashWhenCanonicalIsNotRequired() { final ChainParams chain = createChainWithACall(true); - assertNonCanonicalBlockHashWhenNotCanonical(CALL_RESPOND, chain.block, blockRef -> chain.web3.eth_call(chain.argsForCall, blockRef)); + assertNonCanonicalBlockHashWhenNotCanonical(CALL_RESPOND, chain.block, blockRef -> chain.web3.eth_call(TransactionFactoryHelper.toCallArgumentsParam(chain.argsForCall), blockRef)); } @Test // [ {argsForCall}, { "blockHash": "0x" } -> return contract call respond at given address in specified bloc void callByNonCanonicalBlockHash() { final ChainParams chain = createChainWithACall(true); - assertNonCanonicalBlockHash(CALL_RESPOND, chain.block, blockRef -> chain.web3.eth_call(chain.argsForCall, blockRef)); + assertNonCanonicalBlockHash(CALL_RESPOND, chain.block, blockRef -> chain.web3.eth_call(TransactionFactoryHelper.toCallArgumentsParam(chain.argsForCall), blockRef)); } @Test @@ -724,7 +752,7 @@ void getUnknownTransactionReceipt() { String hashString = tx.getHash().toHexString(); - Assertions.assertNull(web3.eth_getTransactionReceipt(hashString)); + Assertions.assertNull(web3.eth_getTransactionReceipt(new TxHashParam(hashString))); Assertions.assertNull(web3.rsk_getRawTransactionReceiptByHash(hashString)); } @@ -743,7 +771,7 @@ void getTransactionReceipt() { String hashString = tx.getHash().toHexString(); - TransactionReceiptDTO tr = web3.eth_getTransactionReceipt(hashString); + TransactionReceiptDTO tr = web3.eth_getTransactionReceipt(new TxHashParam(hashString)); assertNotNull(tr); assertEquals("0x" + hashString, tr.getTransactionHash()); @@ -794,7 +822,7 @@ void getTransactionReceiptNotInMainBlockchain() { String hashString = tx.getHash().toHexString(); - TransactionReceiptDTO tr = web3.eth_getTransactionReceipt(hashString); + TransactionReceiptDTO tr = web3.eth_getTransactionReceipt(new TxHashParam(hashString)); Assertions.assertNull(tr); } @@ -814,8 +842,8 @@ void getTransactionByHash() { Block block1 = createCanonicalBlock(world, txs); String hashString = tx.getHash().toHexString(); - - TransactionResultDTO tr = web3.eth_getTransactionByHash(hashString); + TxHashParam txHashParam = new TxHashParam(hashString); + TransactionResultDTO tr = web3.eth_getTransactionByHash(txHashParam); assertNotNull(tr); assertEquals("0x" + hashString, tr.getHash()); @@ -852,8 +880,8 @@ void getPendingTransactionByHash() { transactionPool.addTransaction(tx); String hashString = tx.getHash().toHexString(); - - TransactionResultDTO tr = web3.eth_getTransactionByHash(hashString); + TxHashParam txHashParam = new TxHashParam(hashString); + TransactionResultDTO tr = web3.eth_getTransactionByHash(txHashParam); assertNotNull(tr); @@ -889,8 +917,8 @@ void getTransactionByHashNotInMainBlockchain() { assertEquals(ImportResult.IMPORTED_BEST, world.getBlockChain().tryToConnect(block2b)); String hashString = tx.getHash().toHexString(); - - TransactionResultDTO tr = web3.eth_getTransactionByHash(hashString); + TxHashParam txHashParam = new TxHashParam(hashString); + TransactionResultDTO tr = web3.eth_getTransactionByHash(txHashParam); Assertions.assertNull(tr); } @@ -910,8 +938,9 @@ void getTransactionByBlockHashAndIndex() { String hashString = tx.getHash().toHexString(); String blockHashString = block1.getHash().toHexString(); - - TransactionResultDTO tr = web3.eth_getTransactionByBlockHashAndIndex(blockHashString, "0x0"); + BlockHashParam blockHashParam = new BlockHashParam(blockHashString); + HexIndexParam hexIndexParam = new HexIndexParam("0x0"); + TransactionResultDTO tr = web3.eth_getTransactionByBlockHashAndIndex(blockHashParam, hexIndexParam); assertNotNull(tr); assertEquals("0x" + hashString, tr.getHash()); @@ -931,8 +960,9 @@ void getUnknownTransactionByBlockHashAndIndex() { assertEquals(ImportResult.IMPORTED_BEST, world.getBlockChain().tryToConnect(block1)); String blockHashString = block1.getHash().toString(); - - TransactionResultDTO tr = web3.eth_getTransactionByBlockHashAndIndex(blockHashString, "0x0"); + BlockHashParam blockHashParam = new BlockHashParam(blockHashString); + HexIndexParam hexIndexParam = new HexIndexParam("0x0"); + TransactionResultDTO tr = web3.eth_getTransactionByBlockHashAndIndex(blockHashParam, hexIndexParam); Assertions.assertNull(tr); } @@ -953,7 +983,7 @@ void getTransactionByBlockNumberAndIndex() { String hashString = tx.getHash().toHexString(); String blockHashString = block1.getHash().toHexString(); - TransactionResultDTO tr = web3.eth_getTransactionByBlockNumberAndIndex("0x01", "0x0"); + TransactionResultDTO tr = web3.eth_getTransactionByBlockNumberAndIndex(new BlockIdentifierParam("0x01"), new HexIndexParam("0x0")); assertNotNull(tr); assertEquals("0x" + hashString, tr.getHash()); @@ -972,7 +1002,7 @@ void getUnknownTransactionByBlockNumberAndIndex() { world.getBlockStore()).trieStore(world.getTrieStore()).parent(genesis).build(); assertEquals(ImportResult.IMPORTED_BEST, world.getBlockChain().tryToConnect(block1)); - TransactionResultDTO tr = web3.eth_getTransactionByBlockNumberAndIndex("0x1", "0x0"); + TransactionResultDTO tr = web3.eth_getTransactionByBlockNumberAndIndex(new BlockIdentifierParam("0x1"), new HexIndexParam("0x0")); Assertions.assertNull(tr); } @@ -992,12 +1022,12 @@ void getTransactionCount() { String accountAddress = ByteUtil.toHexString(acc1.getAddress().getBytes()); - String count = web3.eth_getTransactionCount(accountAddress, "0x1"); + String count = web3.eth_getTransactionCount(new HexAddressParam(accountAddress), new BlockRefParam("0x1")); assertNotNull(count); assertEquals("0x1", count); - count = web3.eth_getTransactionCount(accountAddress, "0x0"); + count = web3.eth_getTransactionCount(new HexAddressParam(accountAddress), new BlockRefParam("0x0")); assertNotNull(count); assertEquals("0x0", count); @@ -1007,42 +1037,42 @@ void getTransactionCount() { //[ "0x
", { "blockNumber": "0x0" } -> return tx count at given address in genesis block void getTransactionCountByBlockNumber() { final ChainParams chain = createChainWithATransaction(false); - assertByBlockNumber("0x1", blockRef -> chain.web3.eth_getTransactionCount(chain.accountAddress, blockRef)); + assertByBlockNumber("0x1", blockRef -> chain.web3.eth_getTransactionCount(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @Test //[ "0x
", { "invalidInput": "0x0" } -> throw RskJsonRpcRequestException void getTransactionCountAndInvalidInputThrowsException() { final ChainParams chain = createChainWithATransaction(false); - assertInvalidInput(blockRef -> chain.web3.eth_getTransactionCount(chain.accountAddress, blockRef)); + assertInvalidInput(blockRef -> chain.web3.eth_getTransactionCount(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @Test //[ "0x
", { "blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3" } -> return tx count at given address in genesis block void getTransactionCountByBlockHash() { final ChainParams chain = createChainWithATransaction(false); - assertByBlockHash("0x1", chain.block, blockRef -> chain.web3.eth_getTransactionCount(chain.accountAddress, blockRef)); + assertByBlockHash("0x1", chain.block, blockRef -> chain.web3.eth_getTransactionCount(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @Test //[ "0x
", { "blockHash": "0x" } -> raise block-not-found error void getTransactionCountByNonExistentBlockHash() { final ChainParams chain = chainWithAccount10kBalance(false); - assertNonExistentBlockHash(blockRef -> chain.web3.eth_getTransactionCount(chain.accountAddress, blockRef)); + assertNonExistentBlockHash(blockRef -> chain.web3.eth_getTransactionCount(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @Test // [ "0x
", { "blockHash": "0x", "requireCanonical": true } -> raise block-not-canonical error void getTransactionCountByNonCanonicalBlockHashWhenCanonicalIsRequired() { final ChainParams chain = createChainWithATransaction(true); - assertNonCanonicalBlockHashWhenCanonical(chain.block, blockRef -> chain.web3.eth_getTransactionCount(chain.accountAddress, blockRef)); + assertNonCanonicalBlockHashWhenCanonical(chain.block, blockRef -> chain.web3.eth_getTransactionCount(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @Test // [ "0x
", { "blockHash": "0x" } -> return tx count at given address in specified bloc void getTransactionCountByNonCanonicalBlockHash() { final ChainParams chain = createChainWithATransaction(true); - assertNonCanonicalBlockHash("0x1", chain.block, blockRef -> chain.web3.eth_getTransactionCount(chain.accountAddress, blockRef)); + assertNonCanonicalBlockHash("0x1", chain.block, blockRef -> chain.web3.eth_getTransactionCount(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } @Test @@ -1064,7 +1094,7 @@ void getBlockByNumber() { assertEquals(ImportResult.IMPORTED_NOT_BEST, world.getBlockChain().tryToConnect(block1b)); assertEquals(ImportResult.IMPORTED_BEST, world.getBlockChain().tryToConnect(block2b)); - BlockResultDTO bresult = web3.eth_getBlockByNumber("0x1", false); + BlockResultDTO bresult = web3.eth_getBlockByNumber(new BlockIdentifierParam("0x1"), false); assertNotNull(bresult); @@ -1072,7 +1102,7 @@ void getBlockByNumber() { assertEquals(blockHash, bresult.getHash()); String bnOrId = "0x2"; - bresult = web3.eth_getBlockByNumber("0x2", true); + bresult = web3.eth_getBlockByNumber(new BlockIdentifierParam("0x2"), true); assertNotNull(bresult); @@ -1128,7 +1158,7 @@ void getBlockByNumberRetrieveLatestBlock() { block1.setBitcoinMergedMiningHeader(new byte[]{0x01}); assertEquals(ImportResult.IMPORTED_BEST, world.getBlockChain().tryToConnect(block1)); - BlockResultDTO blockResult = web3.eth_getBlockByNumber("latest", false); + BlockResultDTO blockResult = web3.eth_getBlockByNumber(new BlockIdentifierParam("latest"), false); assertNotNull(blockResult); String blockHash = HexUtils.toJsonHex(block1.getHash().toString()); @@ -1148,7 +1178,7 @@ void getBlockByNumberRetrieveEarliestBlock() { assertEquals(ImportResult.IMPORTED_BEST, world.getBlockChain().tryToConnect(block1)); String bnOrId = "earliest"; - BlockResultDTO blockResult = web3.eth_getBlockByNumber(bnOrId, false); + BlockResultDTO blockResult = web3.eth_getBlockByNumber(new BlockIdentifierParam(bnOrId), false); assertNotNull(blockResult); @@ -1167,7 +1197,7 @@ void getBlockByNumberBlockDoesNotExists() { Web3Impl web3 = createWeb3(world); String bnOrId = "0x1234"; - BlockResultDTO blockResult = web3.eth_getBlockByNumber(bnOrId, false); + BlockResultDTO blockResult = web3.eth_getBlockByNumber(new BlockIdentifierParam(bnOrId), false); Assertions.assertNull(blockResult); @@ -1197,7 +1227,7 @@ void getBlockByNumberWhenNumberIsInvalidThrowsException() { String bnOrId = "991234"; - Assertions.assertThrows(org.ethereum.rpc.exception.RskJsonRpcRequestException.class, () -> web3.eth_getBlockByNumber(bnOrId, false)); + Assertions.assertThrows(org.ethereum.rpc.exception.RskJsonRpcRequestException.class, () -> web3.eth_getBlockByNumber(new BlockIdentifierParam(bnOrId), false)); } @Test @@ -1234,8 +1264,11 @@ void getBlockByHash() { String block1HashString = "0x" + block1.getHash(); String block1bHashString = "0x" + block1b.getHash(); String block2bHashString = "0x" + block2b.getHash(); + BlockHashParam blockHashParam1 = new BlockHashParam(block1HashString); + BlockHashParam blockHashParam1b = new BlockHashParam(block1bHashString); + BlockHashParam blockHashParam2 = new BlockHashParam(block2bHashString); - BlockResultDTO bresult = web3.eth_getBlockByHash(block1HashString, false); + BlockResultDTO bresult = web3.eth_getBlockByHash(blockHashParam1, false); assertNotNull(bresult); assertEquals(block1HashString, bresult.getHash()); @@ -1244,7 +1277,7 @@ void getBlockByHash() { assertEquals(0, bresult.getUncles().size()); assertEquals("0xa", bresult.getDifficulty()); assertEquals("0xb", bresult.getTotalDifficulty()); - bresult = web3.eth_getBlockByHash(block1bHashString, true); + bresult = web3.eth_getBlockByHash(blockHashParam1b, true); assertNotNull(bresult); assertEquals(block1bHashString, bresult.getHash()); @@ -1253,7 +1286,7 @@ void getBlockByHash() { Keccak256 blockHash = new Keccak256(HashUtil.keccak256(Hex.decode(hexString))); assertEquals(blockHash.toJsonString(), block1bHashString); - bresult = web3.eth_getBlockByHash(block2bHashString, true); + bresult = web3.eth_getBlockByHash(blockHashParam2, true); assertNotNull(bresult); assertEquals(block2bHashString, bresult.getHash()); @@ -1282,8 +1315,8 @@ void getBlockByHashWithFullTransactionsAsResult() { assertEquals(ImportResult.IMPORTED_BEST, world.getBlockChain().tryToConnect(block1)); String block1HashString = block1.getHashJsonString(); - - BlockResultDTO bresult = web3.eth_getBlockByHash(block1HashString, true); + BlockHashParam blockHashParam = new BlockHashParam(block1HashString); + BlockResultDTO bresult = web3.eth_getBlockByHash(blockHashParam, true); assertNotNull(bresult); assertEquals(block1HashString, bresult.getHash()); @@ -1312,8 +1345,9 @@ void getBlockByHashWithTransactionsHashAsResult() { assertEquals(ImportResult.IMPORTED_BEST, world.getBlockChain().tryToConnect(block1)); String block1HashString = block1.getHashJsonString(); + BlockHashParam blockHashParam = new BlockHashParam(block1HashString); - BlockResultDTO bresult = web3.eth_getBlockByHash(block1HashString, false); + BlockResultDTO bresult = web3.eth_getBlockByHash(blockHashParam, false); assertNotNull(bresult); assertEquals(block1HashString, bresult.getHash()); @@ -1329,7 +1363,9 @@ void getBlockByHashBlockDoesNotExists() { Web3Impl web3 = createWeb3(world); String blockHash = "0x1234000000000000000000000000000000000000000000000000000000000000"; - BlockResultDTO blockResult = web3.eth_getBlockByHash(blockHash, false); + BlockHashParam blockHashParam = new BlockHashParam(blockHash); + + BlockResultDTO blockResult = web3.eth_getBlockByHash(blockHashParam, false); Assertions.assertNull(blockResult); @@ -1384,8 +1420,8 @@ void getBlockByHashBlockWithUncles() { String block1bHashString = "0x" + block1b.getHash(); String block1cHashString = "0x" + block1c.getHash(); String block2HashString = "0x" + block2.getHash(); - - BlockResultDTO result = web3.eth_getBlockByHash(block2HashString, false); + BlockHashParam block2HashStringParam = new BlockHashParam(block2HashString); + BlockResultDTO result = web3.eth_getBlockByHash(block2HashStringParam, false); assertEquals(block2HashString, result.getHash()); assertEquals(block1HashString, result.getParentHash()); @@ -1442,7 +1478,7 @@ void getBlockByNumberBlockWithUncles() { String block1cHashString = "0x" + block1c.getHash(); String block2HashString = "0x" + block2.getHash(); - BlockResultDTO result = web3.eth_getBlockByNumber("0x02", false); + BlockResultDTO result = web3.eth_getBlockByNumber(new BlockIdentifierParam("0x02"), false); assertEquals(block2HashString, result.getHash()); assertEquals(block1HashString, result.getParentHash()); @@ -1507,8 +1543,10 @@ void getUncleByBlockHashAndIndexBlockWithUncles() { String blockEhash = "0x" + blockE.getHash(); String blockBhash = "0x" + blockB.getHash(); String blockChash = "0x" + blockC.getHash(); + BlockHashParam blockFhashParam = new BlockHashParam(blockFhash); + HexIndexParam hexIndexParam = new HexIndexParam("0x00"); - BlockResultDTO result = web3.eth_getUncleByBlockHashAndIndex(blockFhash, "0x00"); + BlockResultDTO result = web3.eth_getUncleByBlockHashAndIndex(blockFhashParam, hexIndexParam); assertEquals(blockEhash, result.getHash()); assertEquals(2, result.getUncles().size()); @@ -1572,8 +1610,10 @@ void getUncleByBlockHashAndIndexBlockWithUnclesCorrespondingToAnUnknownBlock() { String blockFhash = "0x" + blockF.getHash(); String blockEhash = "0x" + blockE.getHash(); + BlockHashParam blockFhashParam = new BlockHashParam(blockFhash); + HexIndexParam hexIndexParam = new HexIndexParam("0x00"); - BlockResultDTO result = web3.eth_getUncleByBlockHashAndIndex(blockFhash, "0x00"); + BlockResultDTO result = web3.eth_getUncleByBlockHashAndIndex(blockFhashParam, hexIndexParam); assertEquals(blockEhash, result.getHash()); assertEquals(0, result.getUncles().size()); @@ -1637,7 +1677,7 @@ void getUncleByBlockNumberAndIndexBlockWithUncles() { String blockBhash = "0x" + blockB.getHash(); String blockChash = "0x" + blockC.getHash(); - BlockResultDTO result = web3.eth_getUncleByBlockNumberAndIndex("0x03", "0x00"); + BlockResultDTO result = web3.eth_getUncleByBlockNumberAndIndex(new BlockIdentifierParam("0x03"), new HexIndexParam("0x00")); assertEquals(blockEhash, result.getHash()); assertEquals(2, result.getUncles().size()); @@ -1701,7 +1741,7 @@ void getUncleByBlockNumberAndIndexBlockWithUnclesCorrespondingToAnUnknownBlock() String blockEhash = "0x" + blockE.getHash(); - BlockResultDTO result = web3.eth_getUncleByBlockNumberAndIndex("0x" + blockF.getNumber(), "0x00"); + BlockResultDTO result = web3.eth_getUncleByBlockNumberAndIndex(new BlockIdentifierParam("0x" + blockF.getNumber()), new HexIndexParam("0x00")); assertEquals(blockEhash, result.getHash()); assertEquals(0, result.getUncles().size()); @@ -1728,7 +1768,7 @@ void getCode() { String accountAddress = ByteUtil.toHexString(acc1.getAddress().getBytes()); - String scode = web3.eth_getCode(accountAddress, "0x1"); + String scode = web3.eth_getCode(new HexAddressParam(accountAddress), new BlockRefParam("0x1")); assertNotNull(scode); assertEquals("0x" + ByteUtil.toHexString(code), scode); @@ -1773,7 +1813,7 @@ function greet(string memory param) public pure returns (string memory) { argsForCall.setTo(HexUtils.toJsonHex(tx.getContractAddress().getBytes())); argsForCall.setData("0xead710c40000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000"); - String result = web3.eth_call(argsForCall, "latest"); + String result = web3.eth_call(TransactionFactoryHelper.toCallArgumentsParam(argsForCall), new BlockIdentifierParam("latest")); assertEquals("0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000", result); } @@ -1820,7 +1860,7 @@ function greet(string memory param) public pure returns (string memory) { argsForCall.setTo(HexUtils.toJsonHex(tx.getContractAddress().getBytes())); argsForCall.setData("0xead710c40000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000"); - String result = web3.eth_call(argsForCall, "latest"); + String result = web3.eth_call(TransactionFactoryHelper.toCallArgumentsParam(argsForCall), new BlockIdentifierParam("latest")); assertEquals("0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000", result); } @@ -1853,7 +1893,7 @@ void callNoneContractReturn() { argsForCall.setTo(HexUtils.toUnformattedJsonHex(tx.getContractAddress().getBytes())); argsForCall.setData(HexUtils.toUnformattedJsonHex(func.encode())); - String result = web3.eth_call(argsForCall, "latest"); + String result = web3.eth_call(TransactionFactoryHelper.toCallArgumentsParam(argsForCall), new BlockIdentifierParam("latest")); assertEquals("0x", result); } @@ -1870,7 +1910,7 @@ void getCodeBlockDoesNotExist() { String accountAddress = ByteUtil.toHexString(acc1.getAddress().getBytes()); - String resultCode = web3.eth_getCode(accountAddress, "0x100"); + String resultCode = web3.eth_getCode(new HexAddressParam(accountAddress), new BlockRefParam("0x100")); assertNull(resultCode); } @@ -1957,7 +1997,7 @@ void eth_sign() { byte[] hash = Keccak256Helper.keccak256("this is the data to hash".getBytes()); - String signature = web3.eth_sign(addr1, "0x" + ByteUtil.toHexString(hash)); + String signature = web3.eth_sign(new HexAddressParam(addr1), new HexDataParam("0x" + ByteUtil.toHexString(hash))); MatcherAssert.assertThat( signature, @@ -1983,7 +2023,7 @@ void eth_sign_testSignatureGenerationToBeAlways32BytesLength() { byte[] hash = Keccak256Helper.keccak256("this is the data to hash".getBytes()); - String signature = web3.eth_sign(addr1, "0x" + ByteUtil.toHexString(hash)); + String signature = web3.eth_sign(new HexAddressParam(addr1), new HexDataParam("0x" + ByteUtil.toHexString(hash))); MatcherAssert.assertThat( signature, @@ -2043,7 +2083,9 @@ void importAccountUsingRawKey() { assertNull(account); - String address = web3.personal_importRawKey(ByteUtil.toHexString(privKeyBytes), "passphrase1"); + HexKeyParam hexKeyParam = new HexKeyParam(ByteUtil.toHexString(privKeyBytes)); + + String address = web3.personal_importRawKey(hexKeyParam, "passphrase1"); assertNotNull(address); @@ -2070,7 +2112,9 @@ void importAccountUsingRawKeyContaining0xPrefix() { assertNull(account); - String address = web3.personal_importRawKey(String.format("0x%s", ByteUtil.toHexString(privKeyBytes)), "passphrase1"); + HexKeyParam hexKeyParam = new HexKeyParam(String.format("0x%s", ByteUtil.toHexString(privKeyBytes))); + + String address = web3.personal_importRawKey(hexKeyParam, "passphrase1"); assertNotNull(address); @@ -2087,10 +2131,14 @@ void dumpRawKey() throws Exception { ECKey eckey = new ECKey(); - String address = web3.personal_importRawKey(ByteUtil.toHexString(eckey.getPrivKeyBytes()), "passphrase1"); - assertTrue(web3.personal_unlockAccount(address, "passphrase1", "")); + HexKeyParam hexKeyParam = new HexKeyParam(ByteUtil.toHexString(eckey.getPrivKeyBytes())); + + String address = web3.personal_importRawKey(hexKeyParam, "passphrase1"); + HexAddressParam hexAddressParam = new HexAddressParam(address); + + assertTrue(web3.personal_unlockAccount(hexAddressParam, "passphrase1", new HexDurationParam(""))); - String rawKey = web3.personal_dumpRawKey(address).substring(2); + String rawKey = web3.personal_dumpRawKey(hexAddressParam).substring(2); assertArrayEquals(eckey.getPrivKeyBytes(), Hex.decode(rawKey)); } @@ -2101,10 +2149,14 @@ void dumpRawKeyContaining0xPrefix() throws Exception { ECKey eckey = new ECKey(); - String address = web3.personal_importRawKey(String.format("0x%s", ByteUtil.toHexString(eckey.getPrivKeyBytes())), "passphrase1"); - assertTrue(web3.personal_unlockAccount(address, "passphrase1", "")); + HexKeyParam hexKeyParam = new HexKeyParam(String.format("0x%s", ByteUtil.toHexString(eckey.getPrivKeyBytes()))); - String rawKey = web3.personal_dumpRawKey(address).substring(2); + String address = web3.personal_importRawKey(hexKeyParam, "passphrase1"); + HexAddressParam hexAddressParam = new HexAddressParam(address); + + assertTrue(web3.personal_unlockAccount(hexAddressParam, "passphrase1", new HexDurationParam(""))); + + String rawKey = web3.personal_dumpRawKey(hexAddressParam).substring(2); assertArrayEquals(eckey.getPrivKeyBytes(), Hex.decode(rawKey)); } @@ -2136,6 +2188,8 @@ void sendPersonalTransaction() throws Exception { args.setNonce(nonce.toString()); args.setChainId(HexUtils.toJsonHex(new byte[]{chainId})); + CallArgumentsParam argsParam = TransactionFactoryHelper.toCallArgumentsParam(args); + // ***** Verifies tx hash Transaction expectedTx = Transaction .builder() @@ -2155,7 +2209,7 @@ void sendPersonalTransaction() throws Exception { when(ethereumMock.submitTransaction(expectedTx)).thenReturn(pendingTransactionResult); // ***** Executes the transaction ******************* - String txHash = web3.personal_sendTransaction(args, "passphrase1"); + String txHash = web3.personal_sendTransaction(argsParam, "passphrase1"); // ***** Checking expected result ******************* @@ -2186,6 +2240,8 @@ void sendPersonalTransactionFailsIfTransactionIsNotQueued() { args.setValue(value.toString()); args.setNonce(nonce.toString()); + CallArgumentsParam argsParam = TransactionFactoryHelper.toCallArgumentsParam(args); + Transaction expectedTx = Transaction .builder() .destination(toAddress.substring(2)) @@ -2204,7 +2260,7 @@ void sendPersonalTransactionFailsIfTransactionIsNotQueued() { // ***** Executes the transaction ******************* RskJsonRpcRequestException thrownEx = Assertions.assertThrows(RskJsonRpcRequestException.class, () -> { - web3.personal_sendTransaction(args, "passphrase1"); + web3.personal_sendTransaction(argsParam, "passphrase1"); }); assertEquals(-32010, thrownEx.getCode(), "Unexpected exception code"); @@ -2218,9 +2274,11 @@ void unlockAccount() { String addr = web3.personal_newAccount("passphrase1"); - web3.personal_lockAccount(addr); + HexAddressParam hexAddressParam = new HexAddressParam(addr); + + web3.personal_lockAccount(hexAddressParam); - assertTrue(web3.personal_unlockAccount(addr, "passphrase1", "")); + assertTrue(web3.personal_unlockAccount(hexAddressParam, "passphrase1", new HexDurationParam(""))); Account account = wallet.getAccount(new RskAddress(addr)); @@ -2233,10 +2291,12 @@ void unlockAccountInvalidDuration() { String addr = web3.personal_newAccount("passphrase1"); - web3.personal_lockAccount(addr); + HexAddressParam hexAddressParam = new HexAddressParam(addr); + + web3.personal_lockAccount(hexAddressParam); RskJsonRpcRequestException e = TestUtils.assertThrows(RskJsonRpcRequestException.class, - () -> web3.personal_unlockAccount(addr, "passphrase1", "K")); + () -> web3.personal_unlockAccount(hexAddressParam, "passphrase1", new HexDurationParam("K"))); assertEquals(-32602, (int) e.getCode()); } @@ -2250,7 +2310,9 @@ void lockAccount() { assertNotNull(account); - assertTrue(web3.personal_lockAccount(addr)); + HexAddressParam hexAddressParam = new HexAddressParam(addr); + + assertTrue(web3.personal_lockAccount(hexAddressParam)); Account account1 = wallet.getAccount(new RskAddress(addr)); @@ -2293,18 +2355,18 @@ void createNewAccountWithoutDuplicates() { } @Test - void estimateGasWithNoBlock(){ - CallArguments args = Mockito.mock(CallArguments.class); + void estimateGasWithNoBlock() { + CallArgumentsParam args = Mockito.mock(CallArgumentsParam.class); Web3TestBuilder builder = new Web3TestBuilder(); Web3Impl web3 = builder.build(); EthModule ethModule = builder.getEthModule(); String estimatedCost = "0x5c"; - ArgumentCaptor blockCaptor = ArgumentCaptor.forClass(String.class); + ArgumentCaptor blockCaptor = ArgumentCaptor.forClass(BlockIdentifierParam.class); when(ethModule.estimateGas(eq(args),blockCaptor.capture())).thenReturn(estimatedCost); String result = web3.eth_estimateGas(args); - String capturedBlock = blockCaptor.getValue(); - assertEquals(BlockTag.LATEST.getTag(),capturedBlock); + BlockIdentifierParam capturedBlock = blockCaptor.getValue(); + assertEquals(BlockTag.LATEST.getTag(), capturedBlock.getIdentifier()); assertEquals(estimatedCost,result); } @@ -2342,8 +2404,9 @@ private void checkSendTransaction(Byte chainId) { if (chainId != null) { args.setChainId(HexUtils.toJsonHex(new byte[]{chainId})); } + CallArgumentsParam argsParam = TransactionFactoryHelper.toCallArgumentsParam(args); - String txHash = web3.eth_sendTransaction(args); + String txHash = web3.eth_sendTransaction(argsParam); // ***** Verifies tx hash String to = toAddress.substring(2); @@ -2353,7 +2416,7 @@ private void checkSendTransaction(Byte chainId) { .gasPrice(gasPrice) .gasLimit(gasLimit) .destination(Hex.decode(to)) - .data(args.getData() == null ? null : Hex.decode(args.getData())) + .data(args.getData() == null ? null : Hex.decode(args.getData().substring(2))) .chainId(config.getNetworkConstants().getChainId()) .value(value) .build(); @@ -2381,7 +2444,7 @@ void getNoCode() throws Exception { String accountAddress = Hex.toHexString(acc1.getAddress().getBytes()); - String scode = web3.eth_getCode(accountAddress, "0x1"); + String scode = web3.eth_getCode(new HexAddressParam(accountAddress), new BlockRefParam("0x1")); assertNotNull(scode); Assertions.assertEquals("0x", scode); @@ -2412,7 +2475,7 @@ void callWithoutReturn() { argsForCall.setTo(HexUtils.toJsonHex(tx.getContractAddress().getBytes())); argsForCall.setData(HexUtils.toJsonHex(noreturn.functions.get("noreturn").encodeSignature())); - String result = web3.eth_call(argsForCall, "latest"); + String result = web3.eth_call(TransactionFactoryHelper.toCallArgumentsParam(argsForCall), new BlockIdentifierParam("latest")); Assertions.assertEquals("0x", result); } @@ -2428,9 +2491,11 @@ void whenEthGetFilterChanges_throwFilterNotFoundException() { Web3RskImpl web3 = (Web3RskImpl) createWeb3(); + HexIndexParam hexIndexParam = new HexIndexParam("0x01"); + RskJsonRpcRequestException exception = Assertions.assertThrowsExactly( expectedException.getClass(), - () -> web3.eth_getFilterChanges("0x01"), + () -> web3.eth_getFilterChanges(hexIndexParam), "filter not found" ); @@ -2448,9 +2513,11 @@ void whenEthGetFilterLogs_throwFilterNotFoundException() { Web3RskImpl web3 = (Web3RskImpl) createWeb3(); + HexIndexParam hexIndexParam = new HexIndexParam("0x01"); + RskJsonRpcRequestException exception = Assertions.assertThrowsExactly( expectedException.getClass(), - () -> web3.eth_getFilterLogs("0x01"), + () -> web3.eth_getFilterLogs(hexIndexParam), "filter not found" ); @@ -2730,7 +2797,6 @@ private Web3Impl createWeb3CallNoReturn( signatureCache); } - private TransactionExecutorFactory buildTransactionExecutorFactory( BlockStore blockStore, BlockTxSignatureCache blockTxSignatureCache) { return new TransactionExecutorFactory( @@ -3045,9 +3111,9 @@ void transactionReceiptAndResultHasTypeField() { Block block1 = createCanonicalBlock(world, txs); String hashString = tx.getHash().toHexString(); - - TransactionReceiptDTO txReceipt = web3.eth_getTransactionReceipt(hashString); - TransactionResultDTO txResult = web3.eth_getTransactionByHash(hashString); + TxHashParam txHashParam = new TxHashParam(hashString); + TransactionReceiptDTO txReceipt = web3.eth_getTransactionReceipt(new TxHashParam(hashString)); + TransactionResultDTO txResult = web3.eth_getTransactionByHash(txHashParam); assertEquals("0x0", txReceipt.getType()); assertEquals("0x0", txResult.getType()); diff --git a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplUnitTest.java b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplUnitTest.java index 752d0d05d5f..6dfe17b61fd 100644 --- a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplUnitTest.java +++ b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplUnitTest.java @@ -25,7 +25,13 @@ import org.ethereum.net.server.ChannelManager; import org.ethereum.net.server.PeerServer; import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.ethereum.rpc.parameters.BlockHashParam; +import org.ethereum.rpc.parameters.BlockIdentifierParam; +import org.ethereum.rpc.parameters.BlockRefParam; +import org.ethereum.rpc.parameters.HexAddressParam; +import org.ethereum.rpc.parameters.HexNumberParam; import org.ethereum.util.BuildInfo; +import org.ethereum.util.TransactionFactoryHelper; import org.ethereum.vm.DataWord; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -101,12 +107,12 @@ void eth_getBalance_stateCannotBeRetrieved() { when(retriever.getInformationProvider(id)) .thenThrow(RskJsonRpcRequestException.blockNotFound("Block not found")); TestUtils.assertThrows(RskJsonRpcRequestException.class, - () -> target.eth_getBalance(addr, id)); + () -> target.eth_getBalance(new HexAddressParam(addr), new BlockRefParam(id))); } @Test void eth_getBalance() { - String id = "id"; + String id = "0x00"; String addr = "0x0011223344556677880011223344556677889900"; RskAddress expectedAddress = new RskAddress(addr); @@ -115,7 +121,7 @@ void eth_getBalance() { when(aip.getBalance(expectedAddress)) .thenReturn(new Coin(BigInteger.ONE)); - String result = target.eth_getBalance(addr, id); + String result = target.eth_getBalance(new HexAddressParam(addr),new BlockRefParam(id)); assertEquals("0x1", result); } @@ -125,43 +131,51 @@ void eth_getBalanceByBlockRef() { String addr = "0x0011223344556677880011223344556677889900"; Map blockRef = new HashMap() { { - put("blockHash", "0x0011223344556677880011223344556677889900"); + put("blockHash", "0xc2b835124172db5bd051bb94fa123721eacac43b5cba2499b22c7583a35689b8"); } }; final Web3Impl spyTarget = spy(target); doReturn("0x1").when(spyTarget).invokeByBlockRef(eq(blockRef),any()); - String result = spyTarget.eth_getBalance(addr, blockRef); + String result = spyTarget.eth_getBalance(new HexAddressParam(addr), new BlockRefParam(blockRef)); assertEquals("0x1", result); verify(spyTarget).invokeByBlockRef(eq(blockRef),any()); } @Test void eth_getStorageAt_stateCannotBeRetrieved() { - String id = "id"; + String id = "0x00"; String addr = "0x0011223344556677880011223344556677889900"; String storageIdx = "0x01"; + HexAddressParam hexAddressParam = new HexAddressParam(addr); + HexNumberParam hexNumberParam = new HexNumberParam(storageIdx); + BlockRefParam blockRefParam = new BlockRefParam(id); + when(retriever.getInformationProvider(id)) .thenThrow(RskJsonRpcRequestException.blockNotFound("Block not found")); TestUtils.assertThrows(RskJsonRpcRequestException.class, - () -> target.eth_getStorageAt(addr, storageIdx, id)); + () -> target.eth_getStorageAt(hexAddressParam, hexNumberParam, blockRefParam)); } @Test void eth_getStorageAt() { - String id = "id"; + String id = "0x00"; String addr = "0x0011223344556677880011223344556677889900"; RskAddress expectedAddress = new RskAddress(addr); String storageIdx = "0x01"; DataWord expectedIdx = DataWord.valueOf(HexUtils.stringHexToByteArray(storageIdx)); + HexAddressParam hexAddressParam = new HexAddressParam(addr); + HexNumberParam hexNumberParam = new HexNumberParam(storageIdx); + BlockRefParam blockRefParam = new BlockRefParam(id); + AccountInformationProvider aip = mock(AccountInformationProvider.class); when(retriever.getInformationProvider(id)).thenReturn(aip); when(aip.getStorageValue(expectedAddress, expectedIdx)) .thenReturn(DataWord.ONE); - String result = target.eth_getStorageAt(addr, storageIdx, id); + String result = target.eth_getStorageAt(hexAddressParam, hexNumberParam, blockRefParam); assertEquals("0x0000000000000000000000000000000000000000000000000000000000000001", result); } @@ -173,13 +187,18 @@ void eth_getStorageAtByBlockRef() { final String storageIdx = "0x01"; Map blockRef = new HashMap() { { - put("blockHash", "0x0011223344556677880011223344556677889900"); + put("blockHash", "0xc2b835124172db5bd051bb94fa123721eacac43b5cba2499b22c7583a35689b8"); } }; final Web3Impl spyTarget = spy(target); final String expectedData = "0x0000000000000000000000000000000000000000000000000000000000000001"; + + HexAddressParam hexAddressParam = new HexAddressParam(addr); + HexNumberParam hexNumberParam = new HexNumberParam(storageIdx); + BlockRefParam blockRefParam = new BlockRefParam(blockRef); + doReturn(expectedData).when(spyTarget).invokeByBlockRef(eq(blockRef),any()); - String result = spyTarget.eth_getStorageAt(addr, storageIdx, blockRef); + String result = spyTarget.eth_getStorageAt(hexAddressParam, hexNumberParam, blockRefParam); assertEquals(expectedData, result); verify(spyTarget).invokeByBlockRef(eq(blockRef),any()); } @@ -187,42 +206,46 @@ void eth_getStorageAtByBlockRef() { @Test void eth_getStorageAtEmptyCell() { - String id = "id"; + String id = "0x00"; String addr = "0x0011223344556677880011223344556677889900"; RskAddress expectedAddress = new RskAddress(addr); String storageIdx = "0x01"; DataWord expectedIdx = DataWord.valueOf(HexUtils.stringHexToByteArray(storageIdx)); + HexAddressParam hexAddressParam = new HexAddressParam(addr); + HexNumberParam hexNumberParam = new HexNumberParam(storageIdx); + BlockRefParam blockRefParam = new BlockRefParam(id); + AccountInformationProvider aip = mock(AccountInformationProvider.class); when(retriever.getInformationProvider(id)).thenReturn(aip); when(aip.getStorageValue(expectedAddress, expectedIdx)) .thenReturn(null); - String result = target.eth_getStorageAt(addr, storageIdx, id); + String result = target.eth_getStorageAt(hexAddressParam, hexNumberParam, blockRefParam); assertEquals("0x0", result); } @Test void eth_getBlockTransactionCountByNumber_blockNotFound() { - String id = "id"; + String id = "0x00"; when(retriever.getTransactions(id)).thenThrow(RskJsonRpcRequestException.blockNotFound("Block not found")); TestUtils.assertThrows(RskJsonRpcRequestException.class, - () -> target.eth_getBlockTransactionCountByNumber(id)); + () -> target.eth_getBlockTransactionCountByNumber(new BlockIdentifierParam(id))); } @Test void eth_getBlockTransactionCountByNumber() { - String id = "id"; + String id = "0x00"; List txs = new LinkedList<>(); txs.add(mock(Transaction.class)); txs.add(mock(Transaction.class)); when(retriever.getTransactions(id)).thenReturn(txs); - String result = target.eth_getBlockTransactionCountByNumber(id); + String result = target.eth_getBlockTransactionCountByNumber(new BlockIdentifierParam(id)); assertEquals("0x2", result); } @@ -233,13 +256,13 @@ void eth_getCode() { final String addr = "0x0011223344556677880011223344556677889900"; Map blockRef = new HashMap() { { - put("blockHash", "0x0011223344556677880011223344556677889900"); + put("blockHash", "0xc2b835124172db5bd051bb94fa123721eacac43b5cba2499b22c7583a35689b8"); } }; final Web3Impl spyTarget = spy(target); final String expectedData = "0x010203"; doReturn(expectedData).when(spyTarget).invokeByBlockRef(eq(blockRef),any()); - String result = spyTarget.eth_getCode(addr,blockRef); + String result = spyTarget.eth_getCode(new HexAddressParam(addr), new BlockRefParam(blockRef)); assertEquals(expectedData, result); verify(spyTarget).invokeByBlockRef(eq(blockRef),any()); } @@ -253,14 +276,14 @@ void eth_callAtByBlockRef() { argsForCall.setData("ead710c40000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000"); Map blockRef = new HashMap() { { - put("blockHash", "0x0011223344556677880011223344556677889900"); + put("blockHash", "0xc2b835124172db5bd051bb94fa123721eacac43b5cba2499b22c7583a35689b8"); } }; final Web3Impl spyTarget = spy(target); final String expectedData = "0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000"; doReturn(expectedData).when(spyTarget).invokeByBlockRef(eq(blockRef),any()); - String result = spyTarget.eth_call(argsForCall,blockRef); + String result = spyTarget.eth_call(TransactionFactoryHelper.toCallArgumentsParam(argsForCall),blockRef); assertEquals(expectedData, result); verify(spyTarget).invokeByBlockRef(eq(blockRef),any()); } @@ -271,12 +294,12 @@ void eth_getBlockTransactionCountByBlockRef() { String addr = "0x0011223344556677880011223344556677889900"; Map blockRef = new HashMap() { { - put("blockHash", "0x0011223344556677880011223344556677889900"); + put("blockHash", "0xc2b835124172db5bd051bb94fa123721eacac43b5cba2499b22c7583a35689b8"); } }; final Web3Impl spyTarget = spy(target); doReturn("0x1").when(spyTarget).invokeByBlockRef(eq(blockRef),any()); - String result = spyTarget.eth_getTransactionCount(addr, blockRef); + String result = spyTarget.eth_getTransactionCount(new HexAddressParam(addr), new BlockRefParam(blockRef)); assertEquals("0x1", result); verify(spyTarget).invokeByBlockRef(eq(blockRef),any()); } @@ -289,7 +312,7 @@ void eth_getUncleCountByBlockHash_blockNotFound() { when(blockchain.getBlockByHash(bytesHash)).thenReturn(null); RskJsonRpcRequestException exception = TestUtils - .assertThrows(RskJsonRpcRequestException.class, () -> target.eth_getUncleCountByBlockHash(hash)); + .assertThrows(RskJsonRpcRequestException.class, () -> target.eth_getUncleCountByBlockHash(new BlockHashParam(hash))); assertEquals(-32602, (int) exception.getCode()); } @@ -308,22 +331,22 @@ void eth_getUncleCountByBlockHash() { when(block.getUncleList()).thenReturn(uncles); when(blockchain.getBlockByHash(bytesHash)).thenReturn(block); - String result = target.eth_getUncleCountByBlockHash(hash); + String result = target.eth_getUncleCountByBlockHash(new BlockHashParam(hash)); assertEquals("0x2", result); } @Test void eth_getUncleCountByBlockNumber_notFound() { - String identifier = "notFoundable"; + String identifier = "0x00"; when(retriever.getBlock(identifier)).thenReturn(Optional.empty()); TestUtils.assertThrows(RskJsonRpcRequestException.class, - () -> target.eth_getUncleCountByBlockNumber(identifier)); + () -> target.eth_getUncleCountByBlockNumber(new BlockIdentifierParam(identifier))); } @Test void eth_getUncleCountByBlockNumber() { - String identifier = "notFoundable"; + String identifier = "0x00"; Block block = mock(Block.class); List uncles = new LinkedList<>(); uncles.add(mock(BlockHeader.class)); @@ -332,7 +355,7 @@ void eth_getUncleCountByBlockNumber() { when(block.getUncleList()).thenReturn(uncles); when(retriever.getBlock(identifier)).thenReturn(Optional.of(block)); - String result = target.eth_getUncleCountByBlockNumber(identifier); + String result = target.eth_getUncleCountByBlockNumber(new BlockIdentifierParam(identifier)); assertEquals("0x2", result); } diff --git a/rskj-core/src/test/java/org/ethereum/rpc/parameters/BlockIdentifierParamTest.java b/rskj-core/src/test/java/org/ethereum/rpc/parameters/BlockIdentifierParamTest.java new file mode 100644 index 00000000000..c733f465c8f --- /dev/null +++ b/rskj-core/src/test/java/org/ethereum/rpc/parameters/BlockIdentifierParamTest.java @@ -0,0 +1,65 @@ +/* + * This file is part of RskJ + * Copyright (C) 2018 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.rpc.parameters; + +import org.ethereum.core.genesis.BlockTag; +import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class BlockIdentifierParamTest { + @Test + public void testValidStringBlockIdentifier() { + String validBlockIdentifier = BlockTag.LATEST.getTag(); + + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam(validBlockIdentifier); + + assertEquals(validBlockIdentifier, blockIdentifierParam.getIdentifier()); + } + + @Test + public void testValidHexBlockIdentifier() { + String validBlockIdentifier = "0xf892038609184e"; + + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam(validBlockIdentifier); + + assertEquals(validBlockIdentifier, blockIdentifierParam.getIdentifier()); + } + + @Test + public void testValidDecimalBlockIdentifier() { + String validBlockIdentifier = "1028"; + + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam(validBlockIdentifier); + + assertEquals(validBlockIdentifier, blockIdentifierParam.getIdentifier()); + } + + @Test + public void testInvalidHexAddressParam() { + String invalidStringIdentifier = "first"; + String invalidHexIdentifier = "0xf89203860918sv"; + + assertThrows(RskJsonRpcRequestException.class, () -> new BlockIdentifierParam(invalidStringIdentifier)); + assertThrows(RskJsonRpcRequestException.class, () -> new BlockIdentifierParam(invalidHexIdentifier)); + assertThrows(RskJsonRpcRequestException.class, () -> new BlockIdentifierParam(null)); + assertThrows(RskJsonRpcRequestException.class, () -> new BlockIdentifierParam("")); + } +} diff --git a/rskj-core/src/test/java/org/ethereum/rpc/parameters/BlockRefParamTest.java b/rskj-core/src/test/java/org/ethereum/rpc/parameters/BlockRefParamTest.java new file mode 100644 index 00000000000..65a055668ed --- /dev/null +++ b/rskj-core/src/test/java/org/ethereum/rpc/parameters/BlockRefParamTest.java @@ -0,0 +1,115 @@ +/* + * This file is part of RskJ + * Copyright (C) 2018 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.rpc.parameters; + +import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class BlockRefParamTest { + @Test + public void testValidIdentifier() { + String identifier = "latest"; + + BlockRefParam blockRefParam = new BlockRefParam(identifier); + + assertEquals(identifier, blockRefParam.getIdentifier()); + assertNull(blockRefParam.getInputs()); + } + + @Test + public void testValidInputs() { + Map inputs = new HashMap() { + { + put("blockHash", "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3"); + } + }; + + BlockRefParam blockRefParam = new BlockRefParam(inputs); + + assertEquals(inputs, blockRefParam.getInputs()); + assertNull(blockRefParam.getIdentifier()); + } + + @Test + public void testInvalidIdentifierString() { + String invalidStringIdentifier = "first"; + + assertThrows(RskJsonRpcRequestException.class, () -> new BlockRefParam(invalidStringIdentifier)); + } + + @Test + public void testInvalidIdentifierHexString() { + String invalidStringIdentifier = "0x1aw"; + + assertThrows(RskJsonRpcRequestException.class, () -> new BlockRefParam(invalidStringIdentifier)); + } + + @Test + public void testInvalidInputsInvalidKey() { + Map inputs = new HashMap() { + { + put("invalidKey", "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3"); + } + }; + + assertThrows(RskJsonRpcRequestException.class, () -> new BlockRefParam(inputs)); + } + + @Test + public void testInvalidInputsInvalidBlockHash() { + Map inputs = new HashMap() { + { + put("blockHash", "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fxk"); + put("requireCanonical", "false"); + } + }; + + assertThrows(RskJsonRpcRequestException.class, () -> new BlockRefParam(inputs)); + } + + @Test + public void testInvalidInputsInvalidBlockNumber() { + Map inputs = new HashMap() { + { + put("blockNumber", "0x76ty"); + put("requireCanonical", "false"); + } + }; + + assertThrows(RskJsonRpcRequestException.class, () -> new BlockRefParam(inputs)); + } + + @Test + public void testInvalidInputsInvalidRequireCanonical() { + Map inputs = new HashMap() { + { + put("blockNumber", "0x76c0"); + put("requireCanonical", "first"); + } + }; + + assertThrows(RskJsonRpcRequestException.class, () -> new BlockRefParam(inputs)); + } +} diff --git a/rskj-core/src/test/java/org/ethereum/rpc/parameters/CallArgumentsParamTest.java b/rskj-core/src/test/java/org/ethereum/rpc/parameters/CallArgumentsParamTest.java new file mode 100644 index 00000000000..599272d26aa --- /dev/null +++ b/rskj-core/src/test/java/org/ethereum/rpc/parameters/CallArgumentsParamTest.java @@ -0,0 +1,175 @@ +package org.ethereum.rpc.parameters; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.rpc.CallArguments; +import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class CallArgumentsParamTest { + + private final ObjectMapper objectMapper = new ObjectMapper(); + + private final String FROM = "0x7986b3df570230288501eea3d890bd66948c9b79"; + private final String TO = "0xe7b8e91401bf4d1669f54dc5f98109d7efbc4eea"; + private final String GAS = "0x76c0"; + private final String GAS_PRICE = "0x9184e72a000"; + private final String VALUE = "0x9184e72a"; + private final String DATA = "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"; + private final String NONCE = "0x1"; + private final String CHAIN_ID = "0x539"; + + @Test + public void testValidCallArgumentsParam() throws JsonProcessingException { + String callArgumentsInput = "{\n" + + " \"from\": \"" + FROM + "\"," + + " \"to\" : \"" + TO + "\"," + + " \"gas\": \"" + GAS + "\"," + + " \"gasPrice\":\"" + GAS_PRICE + "\"," + + " \"value\":\"" + VALUE + "\"," + + " \"data\": \"" + DATA + "\", " + + " \"nonce\": \"" + NONCE + "\", " + + " \"chainId\": \"" + CHAIN_ID + "\"}"; + + JsonNode jsonNode = objectMapper.readTree(callArgumentsInput); + CallArgumentsParam callArgumentsParam = objectMapper.convertValue(jsonNode, CallArgumentsParam.class); + + assertNotNull(callArgumentsParam); + + assertEquals(FROM, callArgumentsParam.getFrom().getAddress().toJsonString()); + assertEquals(TO, callArgumentsParam.getTo().getAddress().toJsonString()); + assertEquals(GAS, callArgumentsParam.getGas().getHexNumber()); + assertEquals(GAS_PRICE, callArgumentsParam.getGasPrice().getHexNumber()); + assertEquals(VALUE, callArgumentsParam.getValue().getHexNumber()); + assertEquals(DATA, callArgumentsParam.getData().getAsHexString()); + assertEquals(NONCE, callArgumentsParam.getNonce().getHexNumber()); + assertEquals(CHAIN_ID, callArgumentsParam.getChainId().getHexNumber()); + } + + @Test + public void testInvalidFromInCallArgumentsParam() throws JsonProcessingException { + String from = "0x7986b3df570230288501eea3d890bd66948c9b7s"; + + String callArgumentsInput = "{\n" + + " \"from\": \"" + from + "\"}"; + + JsonNode jsonNode = objectMapper.readTree(callArgumentsInput); + + assertThrows(RskJsonRpcRequestException.class, () -> objectMapper.convertValue(jsonNode, CallArgumentsParam.class)); + } + + @Test + public void testInvalidToInCallArgumentsParam() throws JsonProcessingException { + String to = "0xe7b8e91401bf4d1669f54dc5f98109d7efbc4esw"; + + String callArgumentsInput = "{\n" + + " \"to\": \"" + to + "\"}"; + + JsonNode jsonNode = objectMapper.readTree(callArgumentsInput); + + assertThrows(RskJsonRpcRequestException.class, () -> objectMapper.convertValue(jsonNode, CallArgumentsParam.class)); + } + + @Test + public void testInvalidGasInCallArgumentsParam() throws JsonProcessingException { + String gas = "0x76cz"; + + String callArgumentsInput = "{\n" + + " \"gas\": \"" + gas + "\"}"; + + JsonNode jsonNode = objectMapper.readTree(callArgumentsInput); + + assertThrows(RskJsonRpcRequestException.class, () -> objectMapper.convertValue(jsonNode, CallArgumentsParam.class)); + } + + @Test + public void testInvalidGasPriceInCallArgumentsParam() throws JsonProcessingException { + String gasPrice = "0x9184e72a0zq"; + + String callArgumentsInput = "{\n" + + " \"gasPrice\": \"" + gasPrice + "\"}"; + + JsonNode jsonNode = objectMapper.readTree(callArgumentsInput); + + assertThrows(RskJsonRpcRequestException.class, () -> objectMapper.convertValue(jsonNode, CallArgumentsParam.class)); + } + + @Test + public void testInvalidValueInCallArgumentsParam() throws JsonProcessingException { + String value = "0x9184e7tq"; + + String callArgumentsInput = "{\n" + + " \"value\": \"" + value + "\"}"; + + JsonNode jsonNode = objectMapper.readTree(callArgumentsInput); + + assertThrows(RskJsonRpcRequestException.class, () -> objectMapper.convertValue(jsonNode, CallArgumentsParam.class)); + } + + @Test + public void testInvalidDataInCallArgumentsParam() throws JsonProcessingException { + String data = "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f0724456pl"; + + String callArgumentsInput = "{\n" + + " \"data\": \"" + data + "\"}"; + + JsonNode jsonNode = objectMapper.readTree(callArgumentsInput); + + assertThrows(RskJsonRpcRequestException.class, () -> objectMapper.convertValue(jsonNode, CallArgumentsParam.class)); + } + + @Test + public void testInvalidNonceInCallArgumentsParam() throws JsonProcessingException { + String nonce = "0xj"; + + String callArgumentsInput = "{\n" + + " \"nonce\": \"" + nonce + "\"}"; + + JsonNode jsonNode = objectMapper.readTree(callArgumentsInput); + + assertThrows(RskJsonRpcRequestException.class, () -> objectMapper.convertValue(jsonNode, CallArgumentsParam.class)); + } + + @Test + public void testInvalidChainIdInCallArgumentsParam() throws JsonProcessingException { + String chainId = "0xb2r"; + + String callArgumentsInput = "{\n" + + " \"chainId\": \"" + chainId + "\"}"; + + JsonNode jsonNode = objectMapper.readTree(callArgumentsInput); + + assertThrows(RskJsonRpcRequestException.class, () -> objectMapper.convertValue(jsonNode, CallArgumentsParam.class)); + } + + @Test + public void testToCallArguments() { + CallArgumentsParam callArgumentsParam = new CallArgumentsParam( + new HexAddressParam(FROM), + new HexAddressParam(TO), + new HexNumberParam(GAS), + new HexNumberParam(GAS_PRICE), + null, + new HexNumberParam(NONCE), + new HexNumberParam(CHAIN_ID), + new HexNumberParam(VALUE), + new HexDataParam(DATA) + ); + + CallArguments callArguments = callArgumentsParam.toCallArguments(); + + assertEquals(FROM, callArguments.getFrom()); + assertEquals(TO, callArguments.getTo()); + assertEquals(GAS, callArguments.getGas()); + assertEquals(GAS_PRICE, callArguments.getGasPrice()); + assertEquals(NONCE, callArguments.getNonce()); + assertEquals(CHAIN_ID, callArguments.getChainId()); + assertEquals(VALUE, callArguments.getValue()); + assertEquals(DATA, callArguments.getData()); + } +} diff --git a/rskj-core/src/test/java/org/ethereum/rpc/parameters/FilterRequestParamTest.java b/rskj-core/src/test/java/org/ethereum/rpc/parameters/FilterRequestParamTest.java new file mode 100644 index 00000000000..acf2f7c55b3 --- /dev/null +++ b/rskj-core/src/test/java/org/ethereum/rpc/parameters/FilterRequestParamTest.java @@ -0,0 +1,155 @@ +/* + * This file is part of RskJ + * Copyright (C) 2023 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.rpc.parameters; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.ethereum.rpc.FilterRequest; +import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.Collection; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; + +class FilterRequestParamTest { + + private final ObjectMapper objectMapper = new ObjectMapper(); + + @Test + void validInput() throws JsonProcessingException { + String filterRequestInput = "{\n" + + " \"fromBlock\": \"0x1\"," + + " \"toBlock\" : \"0x2\"," + + " \"address\": \"0x7857288e171c6159c5576d1bd9ac40c0c48a771c\"," + + " \"topics\":[\"0x000000000000000000000000000000006d696e696e675f6665655f746f706963\"]," + + " \"blockHash\": \"0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3\"}"; + JsonNode jsonNode = objectMapper.readTree(filterRequestInput); + FilterRequestParam filterRequestParam = objectMapper.convertValue(jsonNode, FilterRequestParam.class); + assertNotNull(filterRequestParam); + assertEquals("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3", filterRequestParam.getBlockHash().getHash().toJsonString()); + assertEquals("0x1", filterRequestParam.getFromBlock().getIdentifier()); + assertEquals("0x2", filterRequestParam.getToBlock().getIdentifier()); + assertEquals("0x7857288e171c6159c5576d1bd9ac40c0c48a771c", filterRequestParam.getAddress()[0].getAddress().toJsonString()); + assertEquals("0x000000000000000000000000000000006d696e696e675f6665655f746f706963", filterRequestParam.getTopics()[0][0].getHash().toJsonString()); + } + + @Test + void filterRequestParsesArrayOfTopic() throws JsonProcessingException { + String filterRequestInput = "{\n" + + " \"topics\":[\"0x000000000000000000000000000000006d696e696e675f6665655f746f706963\", " + + " [\"0x0000000000000000000000000000000000000000000000000000000000001111\",\"0x000000000000000000000000000000006d696e696e675f6665655f746f706963\"]]" + + "}"; + JsonNode jsonNode = objectMapper.readTree(filterRequestInput); + FilterRequestParam filterRequestParam = objectMapper.convertValue(jsonNode, FilterRequestParam.class); + assertNotNull(filterRequestParam); + TopicParam[][] topics = filterRequestParam.getTopics(); + assertEquals(2, topics.length); + TopicParam[] topicParam = topics[1]; + assertEquals(2, topicParam.length); + assertEquals("0x0000000000000000000000000000000000000000000000000000000000001111", topicParam[0].getHash().toJsonString()); + } + + @Test + void invalidTopicFails() throws JsonProcessingException { + String filterRequestInput = "{\n" + + " \"topics\":[\"0x000000000000000000000000000000006d696e696e675f6665655f746f706963\", " + + " [\"0x0000000000000000000000000000000000000000000000000000000000001111\",\"0x0000w0000000000000000000000000006d696e696e675f6665655f746f706963\"]]" + + "}"; + JsonNode jsonNode = objectMapper.readTree(filterRequestInput); + Assertions.assertThrows(RskJsonRpcRequestException.class, () -> objectMapper.convertValue(jsonNode, FilterRequestParam.class)); + } + + @Test + void filterRequestParsesSingleTopic() throws JsonProcessingException { + String filterRequestInput = "{\n" + + " \"topics\":\"0x000000000000000000000000000000006d696e696e675f6665655f746f706963\"" + + "}"; + JsonNode jsonNode = objectMapper.readTree(filterRequestInput); + FilterRequestParam filterRequestParam = objectMapper.convertValue(jsonNode, FilterRequestParam.class); + assertNotNull(filterRequestParam); + TopicParam[][] topics = filterRequestParam.getTopics(); + assertEquals(1, topics.length); + TopicParam[] topicParam = topics[0]; + assertEquals(1, topicParam.length); + assertEquals("0x000000000000000000000000000000006d696e696e675f6665655f746f706963", topicParam[0].getHash().toJsonString()); + } + + @Test + void invalidFromBlockFails() throws JsonProcessingException { + String filterRequestInput = "{\"fromBlock\" : \"0x2w\"}"; + JsonNode jsonNode = objectMapper.readTree(filterRequestInput); + Assertions.assertThrows(RskJsonRpcRequestException.class, () -> objectMapper.convertValue(jsonNode, FilterRequestParam.class)); + } + + @Test + void invalidToBlockFails() throws JsonProcessingException { + String filterRequestInput = "{\"toBlock\" : \"ab\"}"; + JsonNode jsonNode = objectMapper.readTree(filterRequestInput); + Assertions.assertThrows(RskJsonRpcRequestException.class, () -> objectMapper.convertValue(jsonNode, FilterRequestParam.class)); + } + + @Test + void toFilterRequestProducesValidObject() { + FilterRequestParam filterRequestParam = new FilterRequestParam( + new BlockIdentifierParam("0x1"), + new BlockIdentifierParam("0x2"), + new HexAddressParam[]{new HexAddressParam("0x7857288e171c6159c5576d1bd9ac40c0c48a771c")}, + new TopicParam[][]{ + new TopicParam[]{ + new TopicParam("0x000000000000000000000000000000006d696e696e675f6665655f746f706963"), + new TopicParam("0x000000000000000000000000000000006d696e696e675f6665655f746f711111") + }, + new TopicParam[]{ + new TopicParam("0x000000000000000000000000000000006d696e696e675f6665655f746f706963") + } + }, + new BlockHashParam("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")); + FilterRequest filterRequest = filterRequestParam.toFilterRequest(); + assertEquals("0x1", filterRequest.getFromBlock()); + assertEquals("0x2", filterRequest.getToBlock()); + assertEquals("0x7857288e171c6159c5576d1bd9ac40c0c48a771c", filterRequest.getAddress()); + assertEquals(2, filterRequest.getTopics().length); + assertTrue(filterRequest.getTopics()[0] instanceof Collection); + assertEquals("0x000000000000000000000000000000006d696e696e675f6665655f746f711111", ((List) filterRequest.getTopics()[0]).get(1)); + assertTrue(filterRequest.getTopics()[1] instanceof String); + assertEquals("0x000000000000000000000000000000006d696e696e675f6665655f746f706963", filterRequest.getTopics()[1]); + + } + + @Test + void canHandleNullTopics() throws JsonProcessingException { + String filterRequestInput = "{\n" + + " \"topics\":[\"0x000000000000000000000000000000006d696e696e675f6665655f746f706963\", null, [\"0x000000000000000000000000000000006d696e696e675f6665655f746f706963\",null]]}"; + JsonNode jsonNode = objectMapper.readTree(filterRequestInput); + FilterRequestParam filterRequestParam = objectMapper.convertValue(jsonNode, FilterRequestParam.class); + FilterRequest fr = objectMapper.convertValue(jsonNode, FilterRequest.class); + + assertNotNull(filterRequestParam); + assertEquals("0x000000000000000000000000000000006d696e696e675f6665655f746f706963", filterRequestParam.getTopics()[0][0].getHash().toJsonString()); + FilterRequest filterRequest = filterRequestParam.toFilterRequest(); + assertNotNull(filterRequest); + assertEquals(3, filterRequest.getTopics().length); + assertEquals(2, ((List) filterRequest.getTopics()[2]).size()); + + } +} \ No newline at end of file diff --git a/rskj-core/src/test/java/org/ethereum/rpc/parameters/HashParamTest.java b/rskj-core/src/test/java/org/ethereum/rpc/parameters/HashParamTest.java new file mode 100644 index 00000000000..446ab0ef7b6 --- /dev/null +++ b/rskj-core/src/test/java/org/ethereum/rpc/parameters/HashParamTest.java @@ -0,0 +1,63 @@ +/* + * This file is part of RskJ + * Copyright (C) 2018 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.rpc.parameters; + +import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class HashParamTest { + + @Test + void testBlockHashParam() { + String validHash = "0xc2b835124172db5bd051bb94fa123721eacac43b5cba2499b22c7583a35689b8"; + String invalidHash = "invalidhash"; + String shorterHash = "0xc2b835124172db5bd051bb94fa123721eacac43b5cba2499b22c7583a3568"; + String invalidCharHash = "0xc2b835124172db5bdzz1bb94fa123721eacac43b5cba2499b22c7583a3568"; + + BlockHashParam blockHashParam = new BlockHashParam(validHash); + + assertEquals(validHash, blockHashParam.getHash().toJsonString()); + + assertThrows(RskJsonRpcRequestException.class, () -> new BlockHashParam(null)); + assertThrows(RskJsonRpcRequestException.class, () -> new BlockHashParam("")); + assertThrows(RskJsonRpcRequestException.class, () -> new BlockHashParam(invalidHash)); + assertThrows(RskJsonRpcRequestException.class, () -> new BlockHashParam(shorterHash)); + assertThrows(RskJsonRpcRequestException.class, () -> new BlockHashParam(invalidCharHash)); + } + + @Test + void testTxHashParam() { + String validHash = "0xc2b835124172db5bd051bb94fa123721eacac43b5cba2499b22c7583a35689b8"; + String invalidHash = "invalidhash"; + String shorterHash = "0xc2b835124172db5bd051bb94fa123721eacac43b5cba2499b22c7583a3568"; + String invalidCharHash = "0xc2b835124172db5bdzz1bb94fa123721eacac43b5cba2499b22c7583a3568"; + + TxHashParam txHashParam = new TxHashParam(validHash); + + assertEquals(validHash, txHashParam.getHash().toJsonString()); + + assertThrows(RskJsonRpcRequestException.class, () -> new BlockHashParam(null)); + assertThrows(RskJsonRpcRequestException.class, () -> new BlockHashParam("")); + assertThrows(RskJsonRpcRequestException.class, () -> new BlockHashParam(invalidHash)); + assertThrows(RskJsonRpcRequestException.class, () -> new BlockHashParam(shorterHash)); + assertThrows(RskJsonRpcRequestException.class, () -> new BlockHashParam(invalidCharHash)); + } +} \ No newline at end of file diff --git a/rskj-core/src/test/java/org/ethereum/rpc/parameters/HexAddressParamTest.java b/rskj-core/src/test/java/org/ethereum/rpc/parameters/HexAddressParamTest.java new file mode 100644 index 00000000000..76b2e7838c5 --- /dev/null +++ b/rskj-core/src/test/java/org/ethereum/rpc/parameters/HexAddressParamTest.java @@ -0,0 +1,46 @@ +/* + * This file is part of RskJ + * Copyright (C) 2018 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.rpc.parameters; + +import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class HexAddressParamTest { + + @Test + public void testValidHexAddressParam() { + String validHexAddress = "0x407d73d8a49eeb85d32cf465507dd71d507100c1"; + + HexAddressParam hexAddressParam = new HexAddressParam(validHexAddress); + + assertEquals(validHexAddress, hexAddressParam.getAddress().toJsonString()); + } + + @Test + public void testInvalidHexAddressParam() { + String invalidHexAddress = "0x407d73d8a4sseb85d32cf465507dd71d507100c1"; + String shorterHexAddress = "0x407d73"; + + assertThrows(RskJsonRpcRequestException.class, () -> new HexAddressParam(null)); + assertThrows(RskJsonRpcRequestException.class, () -> new HexAddressParam(invalidHexAddress)); + assertThrows(RskJsonRpcRequestException.class, () -> new HexAddressParam(shorterHexAddress)); + } +} diff --git a/rskj-core/src/test/java/org/ethereum/rpc/parameters/HexDataParamTest.java b/rskj-core/src/test/java/org/ethereum/rpc/parameters/HexDataParamTest.java new file mode 100644 index 00000000000..9953dd1b219 --- /dev/null +++ b/rskj-core/src/test/java/org/ethereum/rpc/parameters/HexDataParamTest.java @@ -0,0 +1,43 @@ +/* + * This file is part of RskJ + * Copyright (C) 2018 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.rpc.parameters; + +import co.rsk.util.HexUtils; +import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class HexDataParamTest { + @Test + public void testValidHexDataParam() { + String validHexRawData = "0xf892038609184e72a0008276c094e7b8e91401bf4d1669f54dc5f98109d7efbc4eea849184e72aa9d46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f07244567565a0ea179f22ab9149013f3330a0921cef8fc8fddc84f3e51746ef8d5a35e04bfd8ba020e5640606a3257f32b9ef2f706c7294666d4bf759093769d40e7fdd2ac2f49e"; + + HexDataParam hexDataParam = new HexDataParam(validHexRawData); + + assertEquals(validHexRawData, HexUtils.toUnformattedJsonHex(hexDataParam.getRawDataBytes())); + } + + @Test + public void testInvalidHexDataParam() { + String invalidHexRawData = "0xsv92038609184e72a0008276c094e7b8e91401bf4d1669f54dc5f98109d7efbc4eea849184e72aa9d46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f07244567565a0ea179f22ab9149013f3330a0921cef8fc8fddc84f3e51746ef8d5a35e04bfd8ba020e5640606a3257f32b9ef2f706c7294666d4bf759093769d40e7fdd2ac2f49e"; + + assertThrows(RskJsonRpcRequestException.class, () -> new HexDataParam(invalidHexRawData)); + } +} diff --git a/rskj-core/src/test/java/org/ethereum/rpc/parameters/HexDurationParamTest.java b/rskj-core/src/test/java/org/ethereum/rpc/parameters/HexDurationParamTest.java new file mode 100644 index 00000000000..b85612e8ee6 --- /dev/null +++ b/rskj-core/src/test/java/org/ethereum/rpc/parameters/HexDurationParamTest.java @@ -0,0 +1,47 @@ +/* + * This file is part of RskJ + * Copyright (C) 2018 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.rpc.parameters; + +import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class HexDurationParamTest { + @Test + void testValidHexDurationParam() { + String validHexValue = "0x1e"; + HexDurationParam hexDurationParam = new HexDurationParam(validHexValue); + + assertNotNull(hexDurationParam); + assertEquals(30, hexDurationParam.getDuration()); + } + + @Test + void testInvalidHexDurationParam() { + String invalidHexValue = "1e"; // Missing hex prefix + String nonNumericHexValue = "0x1t"; // Non-valid hex value + String invalidDuration = "0xf1652d8322a880e520f996f7d28b645814a58a202d7d2ab7f058e5566fe4f9f3"; // invalid duration + + assertThrows(RskJsonRpcRequestException.class, () -> new HexDurationParam(invalidHexValue)); + assertThrows(RskJsonRpcRequestException.class, () -> new HexDurationParam(nonNumericHexValue)); + assertThrows(RskJsonRpcRequestException.class, () -> new HexDurationParam(invalidDuration)); + } +} diff --git a/rskj-core/src/test/java/org/ethereum/rpc/parameters/HexIndexParamTest.java b/rskj-core/src/test/java/org/ethereum/rpc/parameters/HexIndexParamTest.java new file mode 100644 index 00000000000..7b0b81058cf --- /dev/null +++ b/rskj-core/src/test/java/org/ethereum/rpc/parameters/HexIndexParamTest.java @@ -0,0 +1,49 @@ +/* + * This file is part of RskJ + * Copyright (C) 2023 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.rpc.parameters; + +import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class HexIndexParamTest { + + @Test + void testValidHexIndexParam() { + String validHexValue = "0x123"; + HexIndexParam hexIndexParam = new HexIndexParam(validHexValue); + + assertNotNull(hexIndexParam); + assertEquals(291, hexIndexParam.getIndex()); + } + + @Test + void testInvalidHexIndexParam() { + String invalidHexValue = "123"; // Missing hex prefix + String nonNumericHexValue = "0xabcz"; // Non-valid hex value + String emptyString = ""; // empty value + String invalidIndex = "0xf1652d8322a880e520f996f7d28b645814a58a202d7d2ab7f058e5566fe4f9f3"; // Invalid index + + assertThrows(RskJsonRpcRequestException.class, () -> new HexIndexParam(invalidHexValue)); + assertThrows(RskJsonRpcRequestException.class, () -> new HexIndexParam(nonNumericHexValue)); + assertThrows(RskJsonRpcRequestException.class, () -> new HexIndexParam(emptyString)); + assertThrows(RskJsonRpcRequestException.class, () -> new HexIndexParam(invalidIndex)); + } + +} \ No newline at end of file diff --git a/rskj-core/src/test/java/org/ethereum/rpc/parameters/HexKeyParamTest.java b/rskj-core/src/test/java/org/ethereum/rpc/parameters/HexKeyParamTest.java new file mode 100644 index 00000000000..58305c00278 --- /dev/null +++ b/rskj-core/src/test/java/org/ethereum/rpc/parameters/HexKeyParamTest.java @@ -0,0 +1,43 @@ +/* + * This file is part of RskJ + * Copyright (C) 2018 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.rpc.parameters; + +import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class HexKeyParamTest { + @Test + void testValidHexKeyParam() { + String validHexValue = "0xcd3376bb711cb332ee3fb2ca04c6a8b9f70c316fcdf7a1f44ef4c7999483295e"; + HexKeyParam hexKeyParam = new HexKeyParam(validHexValue); + + assertNotNull(hexKeyParam); + assertEquals(validHexValue, hexKeyParam.getHexKey()); + } + + @Test + void testInvalidHexKeyParam() { + String invalidHexValue = "0xcd3376bb711cb332ee3fb2ca04c6a8b9f70c316fcdf7a1f44ef4c79994832zxt"; + + assertThrows(RskJsonRpcRequestException.class, () -> new HexKeyParam(invalidHexValue)); + } +} diff --git a/rskj-core/src/test/java/org/ethereum/rpc/parameters/HexNumberParamTest.java b/rskj-core/src/test/java/org/ethereum/rpc/parameters/HexNumberParamTest.java new file mode 100644 index 00000000000..ad819283fec --- /dev/null +++ b/rskj-core/src/test/java/org/ethereum/rpc/parameters/HexNumberParamTest.java @@ -0,0 +1,53 @@ +/* + * This file is part of RskJ + * Copyright (C) 2018 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.rpc.parameters; + +import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class HexNumberParamTest { + + @Test + public void testValidHexNumberParam() { + String validHexNumber = "0x76c0"; + HexNumberParam hexNumberParam = new HexNumberParam(validHexNumber); + + assertNotNull(hexNumberParam); + assertEquals(validHexNumber, hexNumberParam.getHexNumber()); + } + + @Test + public void testValidHexNumberParamAsStringNumber() { + String validStringNumber = "1500"; + HexNumberParam hexNumberParam = new HexNumberParam(validStringNumber); + + assertNotNull(hexNumberParam); + assertEquals(validStringNumber, hexNumberParam.getHexNumber()); + } + + @Test + public void testInvalidHexNumberParam() { + String invalidHexNumber = "0x76ty"; + + assertThrows(RskJsonRpcRequestException.class, () -> new HexNumberParam(invalidHexNumber)); + } +} diff --git a/rskj-core/src/test/java/org/ethereum/util/TransactionFactoryHelper.java b/rskj-core/src/test/java/org/ethereum/util/TransactionFactoryHelper.java index a92f7cd8176..bea56c4e635 100644 --- a/rskj-core/src/test/java/org/ethereum/util/TransactionFactoryHelper.java +++ b/rskj-core/src/test/java/org/ethereum/util/TransactionFactoryHelper.java @@ -1,6 +1,7 @@ package org.ethereum.util; import java.math.BigInteger; +import java.util.Optional; import org.ethereum.core.Account; import org.ethereum.core.Transaction; @@ -10,6 +11,10 @@ import co.rsk.test.builders.AccountBuilder; import co.rsk.test.builders.TransactionBuilder; import co.rsk.util.HexUtils; +import org.ethereum.rpc.parameters.CallArgumentsParam; +import org.ethereum.rpc.parameters.HexAddressParam; +import org.ethereum.rpc.parameters.HexDataParam; +import org.ethereum.rpc.parameters.HexNumberParam; /** * Created by ajlopez on 28/02/2018. @@ -116,4 +121,18 @@ public static Transaction createTransaction(CallArguments args, byte chainId, Ac return tx; } + public static CallArgumentsParam toCallArgumentsParam(CallArguments args) { + return new CallArgumentsParam( + Optional.ofNullable(args.getFrom()).filter(p -> !p.isEmpty()).map(HexAddressParam::new).orElse(null), + Optional.ofNullable(args.getTo()).filter(p -> !p.isEmpty()).map(HexAddressParam::new).orElse(null), + Optional.ofNullable(args.getGas()).filter(p -> !p.isEmpty()).map(HexNumberParam::new).orElse(null), + Optional.ofNullable(args.getGasPrice()).filter(p -> !p.isEmpty()).map(HexNumberParam::new).orElse(null), + Optional.ofNullable(args.getGasLimit()).filter(p -> !p.isEmpty()).map(HexNumberParam::new).orElse(null), + Optional.ofNullable(args.getNonce()).filter(p -> !p.isEmpty()).map(HexNumberParam::new).orElse(null), + Optional.ofNullable(args.getChainId()).filter(p -> !p.isEmpty()).map(HexNumberParam::new).orElse(null), + Optional.ofNullable(args.getValue()).filter(p -> !p.isEmpty()).map(HexNumberParam::new).orElse(null), + Optional.ofNullable(args.getData()).filter(p -> !p.isEmpty()).map(HexDataParam::new).orElse(null) + ); + } + } diff --git a/rskj-core/src/test/java/org/ethereum/vm/program/NestedContractsTest.java b/rskj-core/src/test/java/org/ethereum/vm/program/NestedContractsTest.java index acff8d03dfd..dada3866b25 100644 --- a/rskj-core/src/test/java/org/ethereum/vm/program/NestedContractsTest.java +++ b/rskj-core/src/test/java/org/ethereum/vm/program/NestedContractsTest.java @@ -34,6 +34,9 @@ import org.ethereum.core.ReceivedTxSignatureCache; import org.ethereum.rpc.CallArguments; import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.ethereum.rpc.parameters.BlockIdentifierParam; +import org.ethereum.rpc.parameters.CallArgumentsParam; +import org.ethereum.util.TransactionFactoryHelper; import org.ethereum.vm.DataWord; import org.ethereum.vm.PrecompiledContracts; import org.ethereum.vm.program.invoke.ProgramInvokeFactoryImpl; @@ -110,8 +113,10 @@ void testNested_interfaceCall_require() throws FileNotFoundException, DslProcess //Failed Call ContractA.buy(0) -> 0 > 0 final String contractA = getContractAddressString(TX_CONTRACTA); CallArguments args = buildArgs(contractA, Hex.toHexString(BUY_FUNCTION.encode(0))); + CallArgumentsParam callArgumentsParam = TransactionFactoryHelper.toCallArgumentsParam(args); + BlockIdentifierParam blockIdentifierParam = new BlockIdentifierParam("latest"); try { - ethModule.call(args, "latest"); + ethModule.call(callArgumentsParam, blockIdentifierParam); fail(); } catch (RskJsonRpcRequestException e) { MatcherAssert.assertThat(e.getMessage(), Matchers.containsString("Negative value")); @@ -119,7 +124,7 @@ void testNested_interfaceCall_require() throws FileNotFoundException, DslProcess //Success Call -> 2 > 0 args = buildArgs(contractA, Hex.toHexString(BUY_FUNCTION.encode(2))); - final String call = ethModule.call(args, "latest"); + final String call = ethModule.call(TransactionFactoryHelper.toCallArgumentsParam(args), new BlockIdentifierParam("latest")); //assertEquals("0x" + DataWord.valueOf(2).toString(), call); } @@ -151,12 +156,12 @@ void testNested_ABICall_require() throws FileNotFoundException, DslProcessorExce //Failed Call ContractA.buy(0) -> 0 > 0 final String contractA = getContractAddressString("tx03"); CallArguments args = buildArgs(contractA, Hex.toHexString(BUY_FUNCTION.encode(0))); - String call = ethModule.call(args, "latest"); + String call = ethModule.call(TransactionFactoryHelper.toCallArgumentsParam(args), new BlockIdentifierParam("latest")); assertEquals("0x" + DataWord.valueOf(0).toString(), call); //Success Call -> 2 > 0 args = buildArgs(contractA, Hex.toHexString(BUY_FUNCTION.encode(2))); - call = ethModule.call(args, "latest"); + call = ethModule.call(TransactionFactoryHelper.toCallArgumentsParam(args), new BlockIdentifierParam("latest")); assertEquals("0x" + DataWord.valueOf(2).toString(), call); }