diff --git a/lib/rpc-lib4j-1.0-69e3f8a.jar b/lib/rpc-lib4j-1.0-a72ec68.jar similarity index 76% rename from lib/rpc-lib4j-1.0-69e3f8a.jar rename to lib/rpc-lib4j-1.0-a72ec68.jar index 2c398676c4..3c50065acb 100644 Binary files a/lib/rpc-lib4j-1.0-69e3f8a.jar and b/lib/rpc-lib4j-1.0-a72ec68.jar differ diff --git a/modApiServer/build.gradle b/modApiServer/build.gradle index eb3aed32b3..418c252064 100644 --- a/modApiServer/build.gradle +++ b/modApiServer/build.gradle @@ -52,7 +52,7 @@ dependencies { compile project(':3rdParty.libnzmq') compile files("${rootProject.projectDir}/lib/aion-types-22a3be9.jar") compile files("${rootProject.projectDir}/lib/AionRpc.jar") - compile files("${rootProject.projectDir}/lib/rpc-lib4j-1.0-69e3f8a.jar") + compile files("${rootProject.projectDir}/lib/rpc-lib4j-1.0-a72ec68.jar") compile 'org.json:json:20180813' compile group: 'com.google.protobuf', name: 'protobuf-java', version: '3.5.0' compile group: 'org.apache.commons', name: 'commons-collections4', version: '4.0' diff --git a/modApiServer/src/org/aion/api/server/rpc3/RPCMethods.java b/modApiServer/src/org/aion/api/server/rpc3/RPCMethods.java index a78b35885f..49462a319b 100644 --- a/modApiServer/src/org/aion/api/server/rpc3/RPCMethods.java +++ b/modApiServer/src/org/aion/api/server/rpc3/RPCMethods.java @@ -114,6 +114,9 @@ public BlockDetails blockDetailsByEnum(BlockEnum block) { switch (block) { case LATEST: return serializeBlockDetails(chainHolder.getBestBlock()); + case EARLIEST: + return serializeBlockDetails(chainHolder.getBlockByNumber(0L)); + case PENDING: default: throw RPCExceptions.InvalidParamsRPCException.INSTANCE; } @@ -408,23 +411,35 @@ public BlockDetails ops_getBlockDetailsByHash(ByteArray blockHash) { } @Override - public BigInteger eth_getBalance(AionAddress aionAddress, - BlockNumberEnumUnion blockNumberEnumUnion) { - if (blockNumberEnumUnion.blockEnum == BlockEnum.LATEST){ - return chainHolder.getAccountBalance(aionAddress); + public BigInteger eth_getBalance( + AionAddress aionAddress, BlockNumberEnumUnion blockNumberEnumUnion) { + final BigInteger res; + if (blockNumberEnumUnion.blockEnum == BlockEnum.LATEST) { // best block + res = chainHolder.getAccountBalance(aionAddress, chainHolder.blockNumber()); + } else if (blockNumberEnumUnion.blockEnum == BlockEnum.PENDING) { // pending block + res = chainHolder.getAccountBalance(aionAddress); + } else if (blockNumberEnumUnion.blockEnum == BlockEnum.EARLIEST) { // genesis block + res = chainHolder.getAccountBalance(aionAddress, 0L); } else { - return chainHolder.getAccountBalance(aionAddress, blockNumberEnumUnion.blockNumber); + res = chainHolder.getAccountBalance(aionAddress, blockNumberEnumUnion.blockNumber); } + return res; } @Override - public BigInteger eth_getTransactionCount(AionAddress aionAddress, - BlockNumberEnumUnion blockNumberEnumUnion) { - if (blockNumberEnumUnion.blockEnum == BlockEnum.LATEST){ - return chainHolder.getAccountNonce(aionAddress); + public BigInteger eth_getTransactionCount( + AionAddress aionAddress, BlockNumberEnumUnion blockNumberEnumUnion) { + final BigInteger res; + if (blockNumberEnumUnion.blockEnum == BlockEnum.LATEST) { // best block + res = chainHolder.getAccountNonce(aionAddress, chainHolder.blockNumber()); + } else if (blockNumberEnumUnion.blockEnum == BlockEnum.PENDING) { // pending block + res = chainHolder.getAccountNonce(aionAddress); + } else if (blockNumberEnumUnion.blockEnum == BlockEnum.EARLIEST) { // genesis block + res = chainHolder.getAccountNonce(aionAddress, 0L); } else { - return chainHolder.getAccountNonce(aionAddress, blockNumberEnumUnion.blockNumber); + res = chainHolder.getAccountNonce(aionAddress, blockNumberEnumUnion.blockNumber); } + return res; } diff --git a/modApiServer/test/org/aion/api/server/rpc3/EthRPCImplTest.java b/modApiServer/test/org/aion/api/server/rpc3/EthRPCImplTest.java index 6e8ebb496e..1e3cc303d4 100644 --- a/modApiServer/test/org/aion/api/server/rpc3/EthRPCImplTest.java +++ b/modApiServer/test/org/aion/api/server/rpc3/EthRPCImplTest.java @@ -18,8 +18,7 @@ import org.aion.rpc.types.RPCTypes.Request; import org.aion.rpc.types.RPCTypes.VersionType; import org.aion.rpc.types.RPCTypesConverter.AddressBlockParamsConverter; -import org.aion.rpc.types.RPCTypesConverter.Uint128Converter; -import org.aion.rpc.types.RPCTypesConverter.Uint128HexStringConverter; +import org.aion.rpc.types.RPCTypesConverter.BigIntHexStringConverter; import org.aion.rpc.types.RPCTypesConverter.Uint256HexStringConverter; import org.aion.types.AionAddress; import org.aion.util.conversions.Hex; @@ -33,6 +32,7 @@ public class EthRPCImplTest { new AionAddress( Hex.decode("a0fe13f22d73a80743d9d3afc5b7ed02566a23df12e3f4438f8b46921bc38ef5")); private final long blockNumber = 10; + private final long bestBlock = 11; private final IDGeneratorStrategy idGenerator = new SimpleIDGenerator(); private final String ethGetAccountBalanceMethod = "eth_getBalance"; private final String ethGetTransactionCountMethod = "eth_getTransactionCount"; @@ -43,16 +43,13 @@ public class EthRPCImplTest { public void setup() { chainHolder = mock(ChainHolder.class); rpcMethods = new RPCMethods(chainHolder); - doReturn(BigInteger.TEN).when(chainHolder).getAccountBalance(eq(address), eq(blockNumber)); - doReturn(BigInteger.TWO).when(chainHolder).getAccountNonce(eq(address), eq(blockNumber)); - - doReturn(BigInteger.TWO).when(chainHolder).getAccountBalance(eq(address)); - doReturn(BigInteger.ONE).when(chainHolder).getAccountNonce(eq(address)); + doReturn(bestBlock).when(chainHolder).blockNumber(); } @Test public void testEth_getAccountBalance() { // get account by explicitly setting the block number + doReturn(BigInteger.TEN).when(chainHolder).getAccountBalance(eq(address), eq(blockNumber)); assertEquals( BigInteger.TEN, RPCTestUtils.executeRequest( @@ -66,8 +63,9 @@ public void testEth_getAccountBalance() { rpcMethods, Uint256HexStringConverter::decode)); // get account by requesting the best block + doReturn(BigInteger.valueOf(12L)).when(chainHolder).getAccountBalance(eq(address), eq(bestBlock)); assertEquals( - BigInteger.TWO, + BigInteger.valueOf(12L), RPCTestUtils.executeRequest( new Request( idGenerator.generateID(), @@ -79,27 +77,57 @@ public void testEth_getAccountBalance() { VersionType.Version2), rpcMethods, Uint256HexStringConverter::decode)); - // test the default value + // test the pending value + doReturn(BigInteger.ONE).when(chainHolder).getAccountBalance(eq(address)); assertEquals( - BigInteger.TWO, + BigInteger.ONE, RPCTestUtils.executeRequest( new Request( idGenerator.generateID(), ethGetAccountBalanceMethod, AddressBlockParamsConverter.encode( - new AddressBlockParams(address, null)), + new AddressBlockParams(address, + BlockNumberEnumUnion.wrap(BlockEnum.PENDING))), VersionType.Version2), rpcMethods, Uint256HexStringConverter::decode)); + // test the default value + assertEquals( + BigInteger.valueOf(12), + RPCTestUtils.executeRequest( + new Request( + idGenerator.generateID(), + ethGetAccountBalanceMethod, + AddressBlockParamsConverter.encode( + new AddressBlockParams(address, null)), + VersionType.Version2), + rpcMethods, + Uint256HexStringConverter::decode)); + + // test the genesis value + doReturn(BigInteger.ZERO).when(chainHolder).getAccountBalance(eq(address), eq(0L)); + assertEquals( + BigInteger.ZERO, + RPCTestUtils.executeRequest( + new Request( + idGenerator.generateID(), + ethGetAccountBalanceMethod, + AddressBlockParamsConverter.encode( + new AddressBlockParams(address, + BlockNumberEnumUnion.wrap(BlockEnum.EARLIEST))), + VersionType.Version2), + rpcMethods, + Uint256HexStringConverter::decode)); // test that mock was called as expected - Mockito.verify(chainHolder, times(2)).getAccountBalance(any()); - Mockito.verify(chainHolder, times(1)).getAccountBalance(any(), anyLong()); + Mockito.verify(chainHolder, times(1)).getAccountBalance(any()); + Mockito.verify(chainHolder, times(4)).getAccountBalance(any(), anyLong()); } @Test public void testEth_getTransactionCount() { // get account by explicitly setting the block number + doReturn(BigInteger.TWO).when(chainHolder).getAccountNonce(eq(address),eq(blockNumber)); assertEquals( BigInteger.TWO, RPCTestUtils.executeRequest( @@ -111,10 +139,11 @@ public void testEth_getTransactionCount() { address, BlockNumberEnumUnion.wrap(blockNumber))), VersionType.Version2), rpcMethods, - Uint128HexStringConverter::decode)); + BigIntHexStringConverter::decode)); // get account by requesting the best block + doReturn(BigInteger.TWO).when(chainHolder).getAccountNonce(eq(address),eq(bestBlock)); assertEquals( - BigInteger.ONE, + BigInteger.TWO, RPCTestUtils.executeRequest( new Request( idGenerator.generateID(), @@ -125,10 +154,10 @@ public void testEth_getTransactionCount() { BlockNumberEnumUnion.wrap(BlockEnum.LATEST))), VersionType.Version2), rpcMethods, - Uint128HexStringConverter::decode)); + BigIntHexStringConverter::decode)); // test the default value assertEquals( - BigInteger.ONE, + BigInteger.TWO, RPCTestUtils.executeRequest( new Request( idGenerator.generateID(), @@ -137,10 +166,39 @@ public void testEth_getTransactionCount() { new AddressBlockParams(address, null)), VersionType.Version2), rpcMethods, - Uint128HexStringConverter::decode)); + BigIntHexStringConverter::decode)); + + + // test pending value + doReturn(BigInteger.TEN).when(chainHolder).getAccountNonce(eq(address)); + assertEquals( + BigInteger.TEN, + RPCTestUtils.executeRequest( + new Request( + idGenerator.generateID(), + ethGetTransactionCountMethod, + AddressBlockParamsConverter.encode( + new AddressBlockParams(address, BlockNumberEnumUnion.wrap(BlockEnum.PENDING))), + VersionType.Version2), + rpcMethods, + BigIntHexStringConverter::decode)); + // test the genesis value + doReturn(BigInteger.ZERO).when(chainHolder).getAccountNonce(eq(address), eq(0L)); + assertEquals( + BigInteger.ZERO, + RPCTestUtils.executeRequest( + new Request( + idGenerator.generateID(), + ethGetTransactionCountMethod, + AddressBlockParamsConverter.encode( + new AddressBlockParams(address, + BlockNumberEnumUnion.wrap(BlockEnum.EARLIEST))), + VersionType.Version2), + rpcMethods, + BigIntHexStringConverter::decode)); // test that mock was called as expected - Mockito.verify(chainHolder, times(2)).getAccountNonce(any()); - Mockito.verify(chainHolder, times(1)).getAccountNonce(any(), anyLong()); + Mockito.verify(chainHolder, times(1)).getAccountNonce(any()); + Mockito.verify(chainHolder, times(4)).getAccountNonce(any(), anyLong()); } }