Skip to content

Commit

Permalink
Merge pull request #2191 from rsksmart/add_new_rpc_method_rsk_getStor…
Browse files Browse the repository at this point in the history
…ageAt

Adding new rsk_getStorageBytesAt JSON-RPC method
  • Loading branch information
Vovchyk authored Jan 12, 2024
2 parents 6ba039d + 3b88287 commit d2d584c
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 53 deletions.
6 changes: 6 additions & 0 deletions rskj-core/src/main/java/co/rsk/rpc/Web3RskModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down Expand Up @@ -47,4 +50,7 @@ default void rsk_flush() {
}

RskModule getRskModule();

String rsk_getStorageBytesAt(HexAddressParam address, HexNumberParam storageIdx, BlockRefParam blockRefParam);

}
52 changes: 36 additions & 16 deletions rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java
Original file line number Diff line number Diff line change
Expand Up @@ -465,41 +465,61 @@ 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<String, String> blockRef) {
return invokeByBlockRef(blockRef, blockNumber -> this.eth_getStorageAt(address, storageIdx, blockNumber));
}

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<String, String> blockRef) {
return invokeByBlockRef(blockRef, blockNumber -> this.rsk_getStorageBytesAt(address, storageIdx, blockNumber));
}

@Override
public String eth_getTransactionCount(HexAddressParam address, BlockRefParam blockRefParam) {
if (blockRefParam.getIdentifier() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ public RskAddress getAddress() {
return address;
}

@Override
public String toString() {
return address.toString();
}

public static class Deserializer extends StdDeserializer<HexAddressParam> {
private static final long serialVersionUID = 1L;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ public String getHexNumber() {
return this.hexNumber;
}

@Override
public String toString() {
return this.hexNumber;
}

public static class Deserializer extends StdDeserializer<HexNumberParam> {
private static final long serialVersionUID = 1L;

Expand Down
2 changes: 1 addition & 1 deletion rskj-core/src/main/resources/reference.conf
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ rpc {
version: "1.0",
enabled: "true",
methods: {
disabled: [ "rsk_shutdown", "rsk_flush" ]
disabled: [ "rsk_shutdown", "rsk_flush", "rsk_getStorageBytesAt" ]
}
}
}
Expand Down
106 changes: 70 additions & 36 deletions rskj-core/src/test/java/org/ethereum/rpc/Web3ImplUnitTest.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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 {

Expand Down Expand Up @@ -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";
Expand Down

0 comments on commit d2d584c

Please sign in to comment.