From e3c33e4c11f161ff983268f66427286391bfcbb0 Mon Sep 17 00:00:00 2001 From: Angel Soto Date: Thu, 23 Nov 2023 17:31:56 +0100 Subject: [PATCH 1/3] Adding new rsk_getStorageBytesAt JSON-RPC method --- .../main/java/co/rsk/rpc/Web3RskModule.java | 6 + .../main/java/org/ethereum/rpc/Web3Impl.java | 52 ++++++--- .../org/ethereum/rpc/Web3ImplUnitTest.java | 106 ++++++++++++------ 3 files changed, 112 insertions(+), 52 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/rpc/Web3RskModule.java b/rskj-core/src/main/java/co/rsk/rpc/Web3RskModule.java index af22e9f7e97..7a727ef966d 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/Web3RskModule.java +++ b/rskj-core/src/main/java/co/rsk/rpc/Web3RskModule.java @@ -19,6 +19,9 @@ package co.rsk.rpc; import co.rsk.rpc.modules.rsk.RskModule; +import org.ethereum.rpc.parameters.BlockRefParam; +import org.ethereum.rpc.parameters.HexAddressParam; +import org.ethereum.rpc.parameters.HexNumberParam; public interface Web3RskModule { @@ -47,4 +50,7 @@ default void rsk_flush() { } RskModule getRskModule(); + + String rsk_getStorageBytesAt(HexAddressParam address, HexNumberParam storageIdx, BlockRefParam blockRefParam); + } 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 1c224f659d3..ed46bc14a62 100644 --- a/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java +++ b/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java @@ -465,9 +465,8 @@ public String eth_getBalance(HexAddressParam address) { 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()); } + return this.eth_getStorageAt(address, storageIdx, blockRefParam.getInputs()); } private String eth_getStorageAt(HexAddressParam address, HexNumberParam storageIdx, Map blockRef) { @@ -475,31 +474,52 @@ private String eth_getStorageAt(HexAddressParam address, HexNumberParam storageI } private String eth_getStorageAt(HexAddressParam address, HexNumberParam storageIdx, String blockId) { - String s = null; + String response = null; try { - RskAddress addr = address.getAddress(); - AccountInformationProvider accountInformationProvider = web3InformationRetriever.getInformationProvider(blockId); + DataWord key = DataWord.valueOf(HexUtils.strHexOrStrNumberToByteArray(storageIdx.getHexNumber())); - DataWord sv = accountInformationProvider - .getStorageValue(addr, DataWord.valueOf(HexUtils.strHexOrStrNumberToByteArray(storageIdx.getHexNumber()))); + response = Optional.ofNullable(accountInformationProvider.getStorageValue(address.getAddress(), key)) + .map(DataWord::getData) + .map(HexUtils::toUnformattedJsonHex) + .orElse("0x0"); + return response; + } finally { + logger.debug("eth_getStorageAt({}, {}, {}): {}", address, storageIdx, blockId, response); + } + } - if (sv == null) { - s = "0x0"; - } else { - s = HexUtils.toUnformattedJsonHex(sv.getData()); - } + @Override + public String rsk_getStorageBytesAt(HexAddressParam address, HexNumberParam storageIdx, BlockRefParam blockRefParam) { + if (blockRefParam.getIdentifier() != null) { + return this.rsk_getStorageBytesAt(address, storageIdx, blockRefParam.getIdentifier()); + } + return this.rsk_getStorageBytesAt(address, storageIdx, blockRefParam.getInputs()); + } - return s; + private String rsk_getStorageBytesAt(HexAddressParam address, HexNumberParam storageIdx, String blockId) { + String response = null; + + try { + AccountInformationProvider accountInformationProvider = + web3InformationRetriever.getInformationProvider(blockId); + DataWord key = DataWord.valueOf(HexUtils.strHexOrStrNumberToByteArray(storageIdx.getHexNumber())); + + response = Optional.ofNullable(accountInformationProvider.getStorageBytes(address.getAddress(), key)) + .map(HexUtils::toUnformattedJsonHex) + .orElse("0x0"); + return response; } finally { - if (logger.isDebugEnabled()) { - logger.debug("eth_getStorageAt({}, {}, {}): {}", address, storageIdx, blockId, s); - } + logger.debug("rsk_getStorageAt({}, {}, {}): {}", address, storageIdx, blockId, response); } } + private String rsk_getStorageBytesAt(HexAddressParam address, HexNumberParam storageIdx, Map blockRef) { + return invokeByBlockRef(blockRef, blockNumber -> this.rsk_getStorageBytesAt(address, storageIdx, blockNumber)); + } + @Override public String eth_getTransactionCount(HexAddressParam address, BlockRefParam blockRefParam) { if (blockRefParam.getIdentifier() != null) { 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 6dfe17b61fd..7b1663bdfbd 100644 --- a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplUnitTest.java +++ b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplUnitTest.java @@ -1,41 +1,5 @@ package org.ethereum.rpc; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.math.BigInteger; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Optional; - -import org.ethereum.TestUtils; -import org.ethereum.core.*; -import org.ethereum.db.BlockStore; -import org.ethereum.db.ReceiptStore; -import org.ethereum.facade.Ethereum; -import org.ethereum.net.client.ConfigCapabilities; -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; - import co.rsk.config.RskSystemProperties; import co.rsk.core.Coin; import co.rsk.core.RskAddress; @@ -55,6 +19,29 @@ import co.rsk.rpc.modules.txpool.TxPoolModule; import co.rsk.scoring.PeerScoringManager; import co.rsk.util.HexUtils; +import org.ethereum.TestUtils; +import org.ethereum.core.*; +import org.ethereum.db.BlockStore; +import org.ethereum.db.ReceiptStore; +import org.ethereum.facade.Ethereum; +import org.ethereum.net.client.ConfigCapabilities; +import org.ethereum.net.server.ChannelManager; +import org.ethereum.net.server.PeerServer; +import org.ethereum.rpc.exception.RskJsonRpcRequestException; +import org.ethereum.rpc.parameters.*; +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; + +import java.math.BigInteger; +import java.util.*; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; class Web3ImplUnitTest { @@ -226,6 +213,53 @@ void eth_getStorageAtEmptyCell() { result); } + @Test + void rsk_getStorageBytesAt() { + 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); + byte[] resultBytes = TestUtils.generateBytes("result",64); + + AccountInformationProvider aip = mock(AccountInformationProvider.class); + when(retriever.getInformationProvider(id)).thenReturn(aip); + when(aip.getStorageBytes(expectedAddress, expectedIdx)) + .thenReturn(resultBytes); + + String expectedResult = HexUtils.toUnformattedJsonHex(resultBytes); + + String result = target.rsk_getStorageBytesAt(hexAddressParam, hexNumberParam, blockRefParam); + assertEquals(expectedResult, + result); + } + + @Test + void rsk_getStorageBytesAtEmptyCell() { + 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.rsk_getStorageBytesAt(hexAddressParam, hexNumberParam, blockRefParam); + assertEquals("0x0", + result); + } + @Test void eth_getBlockTransactionCountByNumber_blockNotFound() { String id = "0x00"; From b4fe52a7930ecafa1311e091d2a84f74e95d7217 Mon Sep 17 00:00:00 2001 From: Angel Soto Date: Fri, 24 Nov 2023 10:50:08 +0100 Subject: [PATCH 2/3] adding toString methods in rpc parameters --- .../java/org/ethereum/rpc/parameters/HexAddressParam.java | 5 +++++ .../java/org/ethereum/rpc/parameters/HexNumberParam.java | 5 +++++ 2 files changed, 10 insertions(+) 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 index a8c939cc7e5..863a682018c 100644 --- a/rskj-core/src/main/java/org/ethereum/rpc/parameters/HexAddressParam.java +++ b/rskj-core/src/main/java/org/ethereum/rpc/parameters/HexAddressParam.java @@ -49,6 +49,11 @@ public RskAddress getAddress() { return address; } + @Override + public String toString() { + return address.toString(); + } + public static class Deserializer extends StdDeserializer { private static final long serialVersionUID = 1L; 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 index aca8eeb28ef..bbb3539fdd7 100644 --- a/rskj-core/src/main/java/org/ethereum/rpc/parameters/HexNumberParam.java +++ b/rskj-core/src/main/java/org/ethereum/rpc/parameters/HexNumberParam.java @@ -51,6 +51,11 @@ public String getHexNumber() { return this.hexNumber; } + @Override + public String toString() { + return this.hexNumber; + } + public static class Deserializer extends StdDeserializer { private static final long serialVersionUID = 1L; From 3b88287e6519adc033a5b9f81424ad2348714c57 Mon Sep 17 00:00:00 2001 From: Angel Soto Date: Wed, 29 Nov 2023 14:41:01 +0100 Subject: [PATCH 3/3] Updating config to disable the method by default --- rskj-core/src/main/resources/reference.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rskj-core/src/main/resources/reference.conf b/rskj-core/src/main/resources/reference.conf index 7fb2ae06c6b..39823139df6 100644 --- a/rskj-core/src/main/resources/reference.conf +++ b/rskj-core/src/main/resources/reference.conf @@ -428,7 +428,7 @@ rpc { version: "1.0", enabled: "true", methods: { - disabled: [ "rsk_shutdown", "rsk_flush" ] + disabled: [ "rsk_shutdown", "rsk_flush", "rsk_getStorageBytesAt" ] } } }