Skip to content

Commit

Permalink
Add get storage at (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
rmeissner authored May 13, 2019
1 parent 7482fc9 commit b36cbbe
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ interface EthereumRpcConnector {
const val FUNCTION_ESTIMATE_GAS = "eth_estimateGas"
const val FUNCTION_GAS_PRICE = "eth_gasPrice"
const val FUNCTION_GET_TRANSACTION_COUNT = "eth_getTransactionCount"
const val FUNCTION_GET_STORAGE_AT = "eth_getStorageAt"
const val FUNCTION_SEND_RAW_TRANSACTION = "eth_sendRawTransaction"
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,21 +103,21 @@ class RpcEthereumRepository(private val ethereumRpcApi: EthereumRpcConnector) :
params = listOf(transactionHash)
)
).map {
it.result?.let {
it.result?.let { result ->
TransactionData(
hash = transactionHash,
from = it.from,
from = result.from,
transaction = Transaction(
it.to,
value = Wei(it.value),
data = it.data,
gas = it.gas,
gasPrice = it.gasPrice,
nonce = it.nonce
result.to,
value = Wei(result.value),
data = result.data,
gas = result.gas,
gasPrice = result.gasPrice,
nonce = result.nonce
),
blockHash = it.blockHash,
blockNumber = it.blockNumber,
transactionIndex = it.transactionIndex
blockHash = result.blockHash,
blockNumber = result.blockNumber,
transactionIndex = result.transactionIndex
)
} ?: throw TransactionNotFound()

Expand Down Expand Up @@ -153,5 +153,5 @@ private fun <T> EthRequest<T>.toRpcRequest() =
is EthGasPrice -> RpcGasPriceRequest(this)
is EthGetTransactionCount -> RpcTransactionCountRequest(this)
is EthSendRawTransaction -> RpcSendRawTransaction(this)
else -> throw IllegalArgumentException()
is EthGetStorageAt -> RpcGetStorageAt(this)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import pm.gnosis.ethereum.rpc.EthereumRpcConnector.Companion.FUNCTION_CALL
import pm.gnosis.ethereum.rpc.EthereumRpcConnector.Companion.FUNCTION_ESTIMATE_GAS
import pm.gnosis.ethereum.rpc.EthereumRpcConnector.Companion.FUNCTION_GAS_PRICE
import pm.gnosis.ethereum.rpc.EthereumRpcConnector.Companion.FUNCTION_GET_BALANCE
import pm.gnosis.ethereum.rpc.EthereumRpcConnector.Companion.FUNCTION_GET_STORAGE_AT
import pm.gnosis.ethereum.rpc.EthereumRpcConnector.Companion.FUNCTION_GET_TRANSACTION_COUNT
import pm.gnosis.ethereum.rpc.EthereumRpcConnector.Companion.FUNCTION_SEND_RAW_TRANSACTION
import pm.gnosis.models.Transaction
Expand Down Expand Up @@ -101,6 +102,22 @@ class RpcTransactionCountRequest(raw: EthGetTransactionCount) :
}
}

class RpcGetStorageAt(raw: EthGetStorageAt) :
RpcRequest<EthGetStorageAt>(raw) {
override fun request() =
JsonRpcRequest(
method = FUNCTION_GET_STORAGE_AT,
params = arrayListOf(raw.from.asEthereumAddressString(), raw.location.toHexString(), raw.block.asString()),
id = raw.id
)

override fun parse(response: JsonRpcResult) {
raw.response = response.error?.let { EthRequest.Response.Failure<String>(it.message) }
?: response.result?.let { EthRequest.Response.Success(response.result) }
?: EthRequest.Response.Failure("Missing result")
}
}

class RpcSendRawTransaction(raw: EthSendRawTransaction) : RpcRequest<EthSendRawTransaction>(raw) {
override fun request() =
JsonRpcRequest(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,82 @@ class RpcRequestTest {
EthRequest.Response.Failure<BigInteger>("Invalid transaction count!")
),

// GetStorageAt
TestCase(
RpcGetStorageAt(EthGetStorageAt(Solidity.Address(BigInteger.TEN), BigInteger.valueOf(12345), id = 15)),
"eth_getStorageAt",
listOf(Solidity.Address(BigInteger.TEN).asEthereumAddressString(), BigInteger.valueOf(12345).toHexString(), "pending"),
rpcResult(BigInteger.valueOf(23).toHexString()),
EthRequest.Response.Success("0x17"),
15
),
TestCase(
RpcGetStorageAt(
EthGetStorageAt(
Solidity.Address(BigInteger.TEN),
BigInteger.valueOf(1234),
id = 15,
block = Block.PENDING
)
),
"eth_getStorageAt",
listOf(Solidity.Address(BigInteger.TEN).asEthereumAddressString(), BigInteger.valueOf(1234).toHexString(), "pending"),
rpcResult(BigInteger.valueOf(23).toHexString()),
EthRequest.Response.Success("0x17"),
15
),
TestCase(
RpcGetStorageAt(
EthGetStorageAt(
Solidity.Address(BigInteger.TEN),
BigInteger.valueOf(12346),
id = 15,
block = Block.LATEST
)
),
"eth_getStorageAt",
listOf(Solidity.Address(BigInteger.TEN).asEthereumAddressString(), BigInteger.valueOf(12346).toHexString(), "latest"),
rpcResult("some data"),
EthRequest.Response.Success("some data"),
15
),
TestCase(
RpcGetStorageAt(
EthGetStorageAt(
Solidity.Address(BigInteger.TEN),
BigInteger.valueOf(1236),
id = 15,
block = Block.EARLIEST
)
),
"eth_getStorageAt",
listOf(Solidity.Address(BigInteger.TEN).asEthereumAddressString(), BigInteger.valueOf(1236).toHexString(), "earliest"),
rpcResult(""),
EthRequest.Response.Success(""),
15
),
TestCase(
RpcGetStorageAt(
EthGetStorageAt(
Solidity.Address(BigInteger.TEN), BigInteger.valueOf(123), id = 15, block = BlockNumber(
BigInteger.ONE
)
)
),
"eth_getStorageAt",
listOf(Solidity.Address(BigInteger.TEN).asEthereumAddressString(), BigInteger.valueOf(123).toHexString(), "0x1"),
rpcResult(BigInteger.valueOf(22).toHexString()),
EthRequest.Response.Success("0x16"),
15
),
TestCase(
RpcGetStorageAt(EthGetStorageAt(Solidity.Address(BigInteger.TEN), BigInteger.valueOf(123))),
"eth_getStorageAt",
listOf(Solidity.Address(BigInteger.TEN).asEthereumAddressString(), BigInteger.valueOf(123).toHexString(), "pending"),
rpcResult(error = "Some Error"),
EthRequest.Response.Failure<BigInteger>("Some Error")
),

// SendRawTransaction
TestCase(
RpcSendRawTransaction(EthSendRawTransaction("0x42cde4e8SomeSignedData", id = 13)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ class EthEstimateGas(
class EthGetTransactionCount(val from: Solidity.Address, id: Int = 0, val block: Block = Block.PENDING) :
EthRequest<BigInteger>(id)

class EthGetStorageAt(val from: Solidity.Address, val location: BigInteger, id: Int = 0, val block: Block = Block.PENDING) :
EthRequest<String>(id)

class EthSendRawTransaction(val signedData: String, id: Int = 0) : EthRequest<String>(id)

class TransactionReceiptNotFound : NoSuchElementException()
Expand Down
4 changes: 2 additions & 2 deletions ethereum/src/test/java/pm/gnosis/ethereum/EthRequestTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class EthRequestTest {
assertEquals(result, request.checkedResult())
}

@Test()
@Test
fun failure() {
val request = EthBalance(Solidity.Address(BigInteger.ONE), 10)
val errorMsg = "Revert ... because we can"
Expand All @@ -37,7 +37,7 @@ class EthRequestTest {
})
}

@Test()
@Test
fun notExecuted() {
val request = EthBalance(Solidity.Address(BigInteger.ONE), 10)
assertNull("Should not return result if not executed", request.result())
Expand Down
22 changes: 11 additions & 11 deletions ethereum/src/test/java/pm/gnosis/ethereum/MappingBulkRequestTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ class MappingBulkRequestTest {
transaction = Transaction(Solidity.Address(BigInteger.ONE), data = "tokenBalanceData")
)
val request = MappingBulkRequest(
MappedRequest(etherBalance, { it?.value }),
MappedRequest(tokenBalance, {
it?.let { BigInteger(it.removePrefix("0x"), 16) }
})
MappedRequest(etherBalance) { it?.value },
MappedRequest(tokenBalance) { result ->
result?.let { BigInteger(it.removePrefix("0x"), 16) }
}
)

etherBalance.response = EthRequest.Response.Success(Wei(BigInteger.valueOf(11)))
Expand All @@ -42,13 +42,13 @@ class MappingBulkRequestTest {
transaction = Transaction(Solidity.Address(BigInteger.valueOf(5)), data = "token2BalanceData")
)
val request = MappingBulkRequest(
MappedRequest(etherBalance, { it?.value }),
MappedRequest(tokenBalance, {
it?.let { BigInteger(it.removePrefix("0x"), 16) }
}),
MappedRequest(token2Balance, {
it?.let { BigInteger(it.removePrefix("0x"), 16) }
})
MappedRequest(etherBalance) { it?.value },
MappedRequest(tokenBalance) { result ->
result?.let { BigInteger(result.removePrefix("0x"), 16) }
},
MappedRequest(token2Balance) { result ->
result?.let { BigInteger(result.removePrefix("0x"), 16) }
}
)

etherBalance.response = EthRequest.Response.Success(Wei(BigInteger.valueOf(11)))
Expand Down

0 comments on commit b36cbbe

Please sign in to comment.