2019-01-06 19:19:48 +00:00
|
|
|
# Nimbus
|
2023-01-31 12:38:08 +00:00
|
|
|
# Copyright (c) 2018-2023 Status Research & Development GmbH
|
2019-01-06 19:19:48 +00:00
|
|
|
# Licensed under either of
|
|
|
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
|
|
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
|
|
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
|
|
|
|
2018-07-26 21:48:01 +00:00
|
|
|
import
|
2023-12-08 09:35:50 +00:00
|
|
|
std/[json, tables, os, typetraits, times],
|
|
|
|
asynctest, web3/eth_api,
|
|
|
|
nimcrypto/[hash], stew/byteutils,
|
2022-12-02 04:39:12 +00:00
|
|
|
json_rpc/[rpcserver, rpcclient],
|
|
|
|
eth/[rlp, keys, p2p/private/p2p_types],
|
|
|
|
../nimbus/[constants, transaction, config,
|
2022-03-27 11:21:15 +00:00
|
|
|
vm_state, vm_types, version],
|
2023-12-12 19:12:56 +00:00
|
|
|
../nimbus/db/[ledger, storage_types],
|
2022-05-13 16:30:10 +00:00
|
|
|
../nimbus/sync/protocol,
|
2022-12-02 04:39:12 +00:00
|
|
|
../nimbus/core/[tx_pool, chain, executor, executor/executor_helpers, pow/difficulty],
|
|
|
|
../nimbus/utils/utils,
|
|
|
|
../nimbus/common,
|
|
|
|
../nimbus/rpc,
|
2023-12-08 09:35:50 +00:00
|
|
|
../nimbus/rpc/rpc_types,
|
|
|
|
../nimbus/beacon/web3_eth_conv,
|
|
|
|
./test_helpers,
|
|
|
|
./macro_assembler,
|
|
|
|
./test_block_fixture
|
2018-07-26 21:48:01 +00:00
|
|
|
|
2022-01-18 16:19:32 +00:00
|
|
|
const
|
|
|
|
zeroAddress = block:
|
|
|
|
var rc: EthAddress
|
|
|
|
rc
|
|
|
|
|
2020-07-30 07:21:11 +00:00
|
|
|
type
|
2023-12-08 09:35:50 +00:00
|
|
|
Hash256 = common.Hash256
|
|
|
|
BlockHeader = common.BlockHeader
|
|
|
|
|
2020-07-30 07:21:11 +00:00
|
|
|
TestEnv = object
|
|
|
|
txHash: Hash256
|
2022-04-08 04:54:11 +00:00
|
|
|
blockHash: Hash256
|
2020-07-30 07:21:11 +00:00
|
|
|
|
2023-12-08 09:35:50 +00:00
|
|
|
func ethAddr(x: string): EthAddress =
|
|
|
|
hexToByteArray[20](x)
|
|
|
|
|
|
|
|
func w3Addr(x: string): Web3Address =
|
|
|
|
w3Addr hexToByteArray[20](x)
|
|
|
|
|
|
|
|
func w3Hash(x: string): Web3Hash =
|
|
|
|
Web3Hash hexToByteArray[32](x)
|
|
|
|
|
2023-08-04 11:10:09 +00:00
|
|
|
proc persistFixtureBlock(chainDB: CoreDbRef) =
|
2022-06-29 15:44:08 +00:00
|
|
|
let header = getBlockHeader4514995()
|
|
|
|
# Manually inserting header to avoid any parent checks
|
2023-08-04 11:10:09 +00:00
|
|
|
chainDB.kvt.put(genericHashKey(header.blockHash).toOpenArray, rlp.encode(header))
|
2022-06-29 15:44:08 +00:00
|
|
|
chainDB.addBlockNumberToHashLookup(header)
|
|
|
|
discard chainDB.persistTransactions(header.blockNumber, getBlockBody4514995().transactions)
|
|
|
|
discard chainDB.persistReceipts(getReceipts4514995())
|
|
|
|
|
2022-12-02 04:39:12 +00:00
|
|
|
proc setupEnv(com: CommonRef, signer, ks2: EthAddress, ctx: EthContext): TestEnv =
|
2020-07-28 16:48:45 +00:00
|
|
|
var
|
2022-12-02 04:39:12 +00:00
|
|
|
parent = com.db.getCanonicalHead()
|
2021-09-07 12:30:12 +00:00
|
|
|
acc = ctx.am.getAccount(signer).tryGet()
|
2020-07-28 16:48:45 +00:00
|
|
|
blockNumber = 1.toBlockNumber
|
|
|
|
parentHash = parent.blockHash
|
|
|
|
|
|
|
|
const code = evmByteCode:
|
2022-04-08 04:54:11 +00:00
|
|
|
Push4 "0xDEADBEEF" # PUSH
|
|
|
|
Push1 "0x00" # MSTORE AT 0x00
|
|
|
|
Mstore
|
|
|
|
Push1 "0x04" # RETURN LEN
|
|
|
|
Push1 "0x1C" # RETURN OFFSET at 28
|
|
|
|
Return
|
2020-07-28 16:48:45 +00:00
|
|
|
|
2022-01-18 16:19:32 +00:00
|
|
|
let
|
2023-04-11 08:28:45 +00:00
|
|
|
vmHeader = BlockHeader(parentHash: parentHash, gasLimit: 5_000_000)
|
2022-01-18 16:19:32 +00:00
|
|
|
vmState = BaseVMState.new(
|
|
|
|
parent = BlockHeader(stateRoot: parent.stateRoot),
|
|
|
|
header = vmHeader,
|
2022-12-02 04:39:12 +00:00
|
|
|
com = com)
|
2022-01-18 16:19:32 +00:00
|
|
|
|
|
|
|
vmState.stateDB.setCode(ks2, code)
|
|
|
|
vmState.stateDB.addBalance(signer, 9_000_000_000.u256)
|
2020-07-28 16:48:45 +00:00
|
|
|
|
|
|
|
let
|
2021-06-27 04:19:43 +00:00
|
|
|
unsignedTx1 = Transaction(
|
|
|
|
txType : TxLegacy,
|
2020-07-28 16:48:45 +00:00
|
|
|
nonce : 0,
|
|
|
|
gasPrice: 1_100,
|
|
|
|
gasLimit: 70_000,
|
|
|
|
value : 1.u256,
|
2021-06-27 04:19:43 +00:00
|
|
|
to : some(zeroAddress)
|
2020-07-28 16:48:45 +00:00
|
|
|
)
|
2021-06-27 04:19:43 +00:00
|
|
|
unsignedTx2 = Transaction(
|
|
|
|
txType : TxLegacy,
|
2023-04-11 08:28:45 +00:00
|
|
|
nonce : 1,
|
2020-07-28 16:48:45 +00:00
|
|
|
gasPrice: 1_200,
|
|
|
|
gasLimit: 70_000,
|
|
|
|
value : 2.u256,
|
2021-06-27 04:19:43 +00:00
|
|
|
to : some(zeroAddress)
|
2020-07-28 16:48:45 +00:00
|
|
|
)
|
2022-12-02 04:39:12 +00:00
|
|
|
eip155 = com.isEIP155(com.syncCurrent)
|
|
|
|
signedTx1 = signTransaction(unsignedTx1, acc.privateKey, com.chainId, eip155)
|
|
|
|
signedTx2 = signTransaction(unsignedTx2, acc.privateKey, com.chainId, eip155)
|
2020-07-28 16:48:45 +00:00
|
|
|
txs = [signedTx1, signedTx2]
|
2022-12-02 04:39:12 +00:00
|
|
|
txRoot = com.db.persistTransactions(blockNumber, txs)
|
2020-07-28 16:48:45 +00:00
|
|
|
|
|
|
|
vmState.receipts = newSeq[Receipt](txs.len)
|
|
|
|
vmState.cumulativeGasUsed = 0
|
|
|
|
for txIndex, tx in txs:
|
|
|
|
let sender = tx.getSender()
|
2023-04-11 08:28:45 +00:00
|
|
|
let rc = vmState.processTransaction(tx, sender, vmHeader)
|
|
|
|
doAssert(rc.isOk, "Invalid transaction")
|
2021-07-06 13:14:45 +00:00
|
|
|
vmState.receipts[txIndex] = makeReceipt(vmState, tx.txType)
|
2020-07-28 16:48:45 +00:00
|
|
|
|
|
|
|
let
|
2022-12-02 04:39:12 +00:00
|
|
|
receiptRoot = com.db.persistReceipts(vmState.receipts)
|
2023-06-12 04:29:03 +00:00
|
|
|
date = dateTime(2017, mMar, 30)
|
2023-10-18 02:16:11 +00:00
|
|
|
timeStamp = date.toTime.toUnix.EthTime
|
2022-12-02 04:39:12 +00:00
|
|
|
difficulty = com.calcDifficulty(timeStamp, parent)
|
2020-07-28 16:48:45 +00:00
|
|
|
|
2021-10-26 15:18:08 +00:00
|
|
|
# call persist() before we get the rootHash
|
|
|
|
vmState.stateDB.persist()
|
2022-01-23 11:39:43 +00:00
|
|
|
|
2020-07-30 07:21:11 +00:00
|
|
|
var header = BlockHeader(
|
2020-07-28 16:48:45 +00:00
|
|
|
parentHash : parentHash,
|
|
|
|
#coinbase*: EthAddress
|
2021-10-28 09:42:39 +00:00
|
|
|
stateRoot : vmState.stateDB.rootHash,
|
2020-07-28 16:48:45 +00:00
|
|
|
txRoot : txRoot,
|
|
|
|
receiptRoot : receiptRoot,
|
|
|
|
bloom : createBloom(vmState.receipts),
|
|
|
|
difficulty : difficulty,
|
|
|
|
blockNumber : blockNumber,
|
2020-07-29 05:42:32 +00:00
|
|
|
gasLimit : vmState.cumulativeGasUsed + 1_000_000,
|
2020-07-28 16:48:45 +00:00
|
|
|
gasUsed : vmState.cumulativeGasUsed,
|
|
|
|
timestamp : timeStamp
|
|
|
|
#extraData: Blob
|
|
|
|
#mixDigest: Hash256
|
|
|
|
#nonce: BlockNonce
|
|
|
|
)
|
|
|
|
|
2020-07-30 07:21:11 +00:00
|
|
|
let uncles = [header]
|
2022-12-02 04:39:12 +00:00
|
|
|
header.ommersHash = com.db.persistUncles(uncles)
|
2020-07-30 07:21:11 +00:00
|
|
|
|
2022-12-10 01:32:55 +00:00
|
|
|
discard com.db.persistHeaderToDb(header,
|
|
|
|
com.consensus == ConsensusType.POS)
|
2022-12-02 04:39:12 +00:00
|
|
|
com.db.persistFixtureBlock()
|
2020-07-30 07:21:11 +00:00
|
|
|
result = TestEnv(
|
|
|
|
txHash: signedTx1.rlpHash,
|
|
|
|
blockHash: header.hash
|
|
|
|
)
|
|
|
|
|
2021-06-22 01:32:32 +00:00
|
|
|
proc rpcMain*() =
|
|
|
|
suite "Remote Procedure Calls":
|
|
|
|
# TODO: Include other transports such as Http
|
|
|
|
let
|
2021-09-16 15:59:46 +00:00
|
|
|
conf = makeTestConfig()
|
2021-09-07 13:45:01 +00:00
|
|
|
ctx = newEthContext()
|
|
|
|
ethNode = setupEthNode(conf, ctx, eth)
|
2022-12-02 04:39:12 +00:00
|
|
|
com = CommonRef.new(
|
2023-08-04 11:10:09 +00:00
|
|
|
newCoreDbRef LegacyDbMemory,
|
2021-09-11 14:58:01 +00:00
|
|
|
conf.pruneMode == PruneMode.Full,
|
2021-09-16 15:59:46 +00:00
|
|
|
conf.networkId,
|
|
|
|
conf.networkParams
|
2021-09-11 14:58:01 +00:00
|
|
|
)
|
2023-12-08 09:35:50 +00:00
|
|
|
signer = ethAddr("0x0e69cde81b1aa07a45c32c6cd85d67229d36bb1b")
|
|
|
|
ks2 = ethAddr("0xa3b2222afa5c987da6ef773fde8d01b9f23d481f")
|
|
|
|
ks3 = ethAddr("0x597176e9a64aad0845d83afdaf698fbeff77703b")
|
2021-06-22 01:32:32 +00:00
|
|
|
|
2022-11-12 04:12:17 +00:00
|
|
|
# disable POS/post Merge feature
|
2022-12-02 04:39:12 +00:00
|
|
|
com.setTTD none(DifficultyInt)
|
2022-11-12 04:12:17 +00:00
|
|
|
|
2021-09-11 14:58:01 +00:00
|
|
|
let keyStore = "tests" / "keystore"
|
|
|
|
let res = ctx.am.loadKeystores(keyStore)
|
2021-06-22 01:32:32 +00:00
|
|
|
if res.isErr:
|
|
|
|
debugEcho res.error
|
|
|
|
doAssert(res.isOk)
|
|
|
|
|
2021-09-07 12:30:12 +00:00
|
|
|
let acc1 = ctx.am.getAccount(signer).tryGet()
|
|
|
|
let unlock = ctx.am.unlockAccount(signer, acc1.keystore["password"].getStr())
|
2021-06-22 01:32:32 +00:00
|
|
|
if unlock.isErr:
|
|
|
|
debugEcho unlock.error
|
|
|
|
doAssert(unlock.isOk)
|
|
|
|
|
2022-12-02 04:39:12 +00:00
|
|
|
com.initializeEmptyDb()
|
|
|
|
let env = setupEnv(com, signer, ks2, ctx)
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
# Create Ethereum RPCs
|
|
|
|
let RPC_PORT = 8545
|
|
|
|
var
|
2023-07-24 14:50:39 +00:00
|
|
|
rpcServer = newRpcSocketServer(["127.0.0.1:" & $RPC_PORT])
|
2021-06-22 01:32:32 +00:00
|
|
|
client = newRpcSocketClient()
|
2022-12-02 04:39:12 +00:00
|
|
|
txPool = TxPoolRef.new(com, conf.engineSigner)
|
2022-01-23 11:39:43 +00:00
|
|
|
|
2021-09-07 15:00:21 +00:00
|
|
|
setupCommonRpc(ethNode, conf, rpcServer)
|
2022-12-02 04:39:12 +00:00
|
|
|
setupEthRpc(ethNode, ctx, com, txPool, rpcServer)
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
# Begin tests
|
|
|
|
rpcServer.start()
|
2023-07-24 14:50:39 +00:00
|
|
|
waitFor client.connect("127.0.0.1", Port(RPC_PORT))
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
# TODO: add more tests here
|
|
|
|
test "web3_clientVersion":
|
|
|
|
let res = await client.web3_clientVersion()
|
|
|
|
check res == NimbusIdent
|
|
|
|
|
|
|
|
test "web3_sha3":
|
2023-12-08 09:35:50 +00:00
|
|
|
let data = @(NimbusName.toOpenArrayByte(0, NimbusName.len-1))
|
|
|
|
let res = await client.web3_sha3(data)
|
|
|
|
let hash = keccakHash(data)
|
|
|
|
check hash == ethHash res
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "net_version":
|
|
|
|
let res = await client.net_version()
|
2021-09-16 15:59:46 +00:00
|
|
|
check res == $conf.networkId
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "net_listening":
|
|
|
|
let res = await client.net_listening()
|
2021-09-11 14:58:01 +00:00
|
|
|
let listening = ethNode.peerPool.connectedNodes.len < conf.maxPeers
|
2021-06-22 01:32:32 +00:00
|
|
|
check res == listening
|
|
|
|
|
|
|
|
test "net_peerCount":
|
|
|
|
let res = await client.net_peerCount()
|
|
|
|
let peerCount = ethNode.peerPool.connectedNodes.len
|
2023-12-08 09:35:50 +00:00
|
|
|
check res == w3Qty(peerCount)
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "eth_protocolVersion":
|
|
|
|
let res = await client.eth_protocolVersion()
|
2021-07-23 17:02:56 +00:00
|
|
|
# Use a hard-coded number instead of the same expression as the client,
|
|
|
|
# so that bugs introduced via that expression are detected. Using the
|
|
|
|
# same expression as the client can hide issues when the value is wrong
|
|
|
|
# in both places. When the expected value genuinely changes, it'll be
|
|
|
|
# obvious. Just change this number.
|
2022-03-21 17:12:07 +00:00
|
|
|
check res == $ethVersion
|
2021-06-22 01:32:32 +00:00
|
|
|
|
2022-09-10 13:05:32 +00:00
|
|
|
test "eth_chainId":
|
|
|
|
let res = await client.eth_chainId()
|
2023-12-08 09:35:50 +00:00
|
|
|
check res == w3Qty(distinctBase(com.chainId))
|
2022-09-10 13:05:32 +00:00
|
|
|
|
2021-06-22 01:32:32 +00:00
|
|
|
test "eth_syncing":
|
|
|
|
let res = await client.eth_syncing()
|
|
|
|
if res.kind == JBool:
|
|
|
|
let syncing = ethNode.peerPool.connectedNodes.len > 0
|
|
|
|
check res.getBool() == syncing
|
|
|
|
else:
|
|
|
|
check res.kind == JObject
|
2022-12-02 04:39:12 +00:00
|
|
|
check com.syncStart == UInt256.fromHex(res["startingBlock"].getStr())
|
|
|
|
check com.syncCurrent == UInt256.fromHex(res["currentBlock"].getStr())
|
|
|
|
check com.syncHighest == UInt256.fromHex(res["highestBlock"].getStr())
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "eth_coinbase":
|
|
|
|
let res = await client.eth_coinbase()
|
|
|
|
# currently we don't have miner
|
2023-12-08 09:35:50 +00:00
|
|
|
check res == w3Address()
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "eth_mining":
|
|
|
|
let res = await client.eth_mining()
|
|
|
|
# currently we don't have miner
|
|
|
|
check res == false
|
|
|
|
|
|
|
|
test "eth_hashrate":
|
|
|
|
let res = await client.eth_hashrate()
|
|
|
|
# currently we don't have miner
|
2023-12-08 09:35:50 +00:00
|
|
|
check res == w3Qty(0'u64)
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "eth_gasPrice":
|
|
|
|
let res = await client.eth_gasPrice()
|
2023-12-08 09:35:50 +00:00
|
|
|
check res == w3Qty(0x47E'u64)
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "eth_accounts":
|
|
|
|
let res = await client.eth_accounts()
|
2023-12-08 09:35:50 +00:00
|
|
|
check signer.w3Addr in res
|
|
|
|
check ks2.w3Addr in res
|
|
|
|
check ks3.w3Addr in res
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "eth_blockNumber":
|
|
|
|
let res = await client.eth_blockNumber()
|
2023-12-08 09:35:50 +00:00
|
|
|
check res == w3Qty(0x1'u64)
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "eth_getBalance":
|
2023-12-08 09:35:50 +00:00
|
|
|
let a = await client.eth_getBalance(w3Addr("0xfff33a3bd36abdbd412707b8e310d6011454a7ae"), blockId(0'u64))
|
|
|
|
check a == UInt256.fromHex("0x1b1ae4d6e2ef5000000")
|
|
|
|
let b = await client.eth_getBalance(w3Addr("0xfff4bad596633479a2a29f9a8b3f78eefd07e6ee"), blockId(0'u64))
|
|
|
|
check b == UInt256.fromHex("0x56bc75e2d63100000")
|
|
|
|
let c = await client.eth_getBalance(w3Addr("0xfff7ac99c8e4feb60c9750054bdc14ce1857f181"), blockId(0'u64))
|
|
|
|
check c == UInt256.fromHex("0x3635c9adc5dea00000")
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "eth_getStorageAt":
|
2023-12-08 09:35:50 +00:00
|
|
|
let res = await client.eth_getStorageAt(w3Addr("0xfff33a3bd36abdbd412707b8e310d6011454a7ae"), 0.u256, blockId(0'u64))
|
|
|
|
check 0.u256 == res
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "eth_getTransactionCount":
|
2023-12-08 09:35:50 +00:00
|
|
|
let res = await client.eth_getTransactionCount(w3Addr("0xfff7ac99c8e4feb60c9750054bdc14ce1857f181"), blockId(0'u64))
|
|
|
|
check res == w3Qty(0'u64)
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "eth_getBlockTransactionCountByHash":
|
2022-12-02 04:39:12 +00:00
|
|
|
let hash = com.db.getBlockHash(0.toBlockNumber)
|
2023-12-08 09:35:50 +00:00
|
|
|
let res = await client.eth_getBlockTransactionCountByHash(w3Hash hash)
|
|
|
|
check res == w3Qty(0'u64)
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "eth_getBlockTransactionCountByNumber":
|
2023-12-08 09:35:50 +00:00
|
|
|
let res = await client.eth_getBlockTransactionCountByNumber(blockId(0'u64))
|
|
|
|
check res == w3Qty(0'u64)
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "eth_getUncleCountByBlockHash":
|
2022-12-02 04:39:12 +00:00
|
|
|
let hash = com.db.getBlockHash(0.toBlockNumber)
|
2023-12-08 09:35:50 +00:00
|
|
|
let res = await client.eth_getUncleCountByBlockHash(w3Hash hash)
|
|
|
|
check res == w3Qty(0'u64)
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "eth_getUncleCountByBlockNumber":
|
2023-12-08 09:35:50 +00:00
|
|
|
let res = await client.eth_getUncleCountByBlockNumber(blockId(0'u64))
|
|
|
|
check res == w3Qty(0'u64)
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "eth_getCode":
|
2023-12-08 09:35:50 +00:00
|
|
|
let res = await client.eth_getCode(w3Addr("0xfff7ac99c8e4feb60c9750054bdc14ce1857f181"), blockId(0'u64))
|
|
|
|
check res.len == 0
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "eth_sign":
|
|
|
|
let msg = "hello world"
|
2023-12-08 09:35:50 +00:00
|
|
|
let msgBytes = @(msg.toOpenArrayByte(0, msg.len-1))
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
expect ValueError:
|
2023-12-08 09:35:50 +00:00
|
|
|
discard await client.eth_sign(w3Addr(ks2), msgBytes)
|
2021-06-22 01:32:32 +00:00
|
|
|
|
2023-12-08 09:35:50 +00:00
|
|
|
let res = await client.eth_sign(w3Addr(signer), msgBytes)
|
|
|
|
let sig = Signature.fromRaw(res).tryGet()
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
# now let us try to verify signature
|
|
|
|
let msgData = "\x19Ethereum Signed Message:\n" & $msg.len & msg
|
2023-12-08 09:35:50 +00:00
|
|
|
let msgDataBytes = @(msgData.toOpenArrayByte(0, msgData.len-1))
|
|
|
|
let msgHash = await client.web3_sha3(msgDataBytes)
|
|
|
|
let pubkey = recover(sig, SkMessage(msgHash.bytes)).tryGet()
|
2021-06-22 01:32:32 +00:00
|
|
|
let recoveredAddr = pubkey.toCanonicalAddress()
|
|
|
|
check recoveredAddr == signer # verified
|
|
|
|
|
|
|
|
test "eth_signTransaction, eth_sendTransaction, eth_sendRawTransaction":
|
2023-12-08 09:35:50 +00:00
|
|
|
var unsignedTx = EthSend(
|
|
|
|
`from`: w3Addr(signer),
|
|
|
|
to: w3Addr(ks2).some,
|
|
|
|
gas: w3Qty(100000'u).some,
|
|
|
|
gasPrice: none(Quantity),
|
|
|
|
value: some 100.u256,
|
|
|
|
data: @[],
|
|
|
|
nonce: none(Quantity)
|
2021-06-22 01:32:32 +00:00
|
|
|
)
|
|
|
|
|
2023-12-08 09:35:50 +00:00
|
|
|
let signedTxBytes = await client.eth_signTransaction(unsignedTx)
|
|
|
|
let signedTx = rlp.decode(signedTxBytes, Transaction)
|
2021-06-22 01:32:32 +00:00
|
|
|
check signer == signedTx.getSender() # verified
|
|
|
|
|
|
|
|
let hashAhex = await client.eth_sendTransaction(unsignedTx)
|
2023-12-08 09:35:50 +00:00
|
|
|
let hashBhex = await client.eth_sendRawTransaction(signedTxBytes)
|
|
|
|
check hashAhex == hashBhex
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "eth_call":
|
|
|
|
var ec = EthCall(
|
2023-12-08 09:35:50 +00:00
|
|
|
source: w3Addr(signer).some,
|
|
|
|
to: w3Addr(ks2).some,
|
|
|
|
gas: w3Qty(100000'u).some,
|
|
|
|
gasPrice: none(Quantity),
|
|
|
|
value: some 100.u256
|
2021-06-22 01:32:32 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
let res = await client.eth_call(ec, "latest")
|
2023-12-08 09:35:50 +00:00
|
|
|
check res == hexToSeqByte("deadbeef")
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "eth_estimateGas":
|
|
|
|
var ec = EthCall(
|
2023-12-08 09:35:50 +00:00
|
|
|
source: w3Addr(signer).some,
|
|
|
|
to: w3Addr(ks3).some,
|
|
|
|
gas: w3Qty(42000'u).some,
|
|
|
|
gasPrice: w3Qty(100'u).some,
|
|
|
|
value: some 100.u256
|
2021-06-22 01:32:32 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
let res = await client.eth_estimateGas(ec, "latest")
|
2023-12-08 09:35:50 +00:00
|
|
|
check res == w3Qty(21000'u64)
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "eth_getBlockByHash":
|
2023-12-08 09:35:50 +00:00
|
|
|
let res = await client.eth_getBlockByHash(w3Hash env.blockHash, true)
|
|
|
|
check res.isNil.not
|
|
|
|
check res.hash == w3Hash env.blockHash
|
|
|
|
let res2 = await client.eth_getBlockByHash(w3Hash env.txHash, true)
|
|
|
|
check res2.isNil
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "eth_getBlockByNumber":
|
|
|
|
let res = await client.eth_getBlockByNumber("latest", true)
|
2023-12-08 09:35:50 +00:00
|
|
|
check res.isNil.not
|
|
|
|
check res.hash == w3Hash env.blockHash
|
2021-06-22 01:32:32 +00:00
|
|
|
let res2 = await client.eth_getBlockByNumber($1, true)
|
2023-12-08 09:35:50 +00:00
|
|
|
check res2.isNil
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "eth_getTransactionByHash":
|
2023-12-08 09:35:50 +00:00
|
|
|
let res = await client.eth_getTransactionByHash(w3Hash env.txHash)
|
|
|
|
check res.isNil.not
|
|
|
|
check res.blockNumber.get() == w3Qty(1'u64)
|
|
|
|
let res2 = await client.eth_getTransactionByHash(w3Hash env.blockHash)
|
|
|
|
check res2.isNil
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "eth_getTransactionByBlockHashAndIndex":
|
2023-12-08 09:35:50 +00:00
|
|
|
let res = await client.eth_getTransactionByBlockHashAndIndex(w3Hash env.blockHash, w3Qty(0'u64))
|
|
|
|
check res.isNil.not
|
|
|
|
check res.blockNumber.get() == w3Qty(1'u64)
|
2021-06-22 01:32:32 +00:00
|
|
|
|
2023-12-08 09:35:50 +00:00
|
|
|
let res2 = await client.eth_getTransactionByBlockHashAndIndex(w3Hash env.blockHash, w3Qty(3'u64))
|
|
|
|
check res2.isNil
|
2021-06-22 01:32:32 +00:00
|
|
|
|
2023-12-08 09:35:50 +00:00
|
|
|
let res3 = await client.eth_getTransactionByBlockHashAndIndex(w3Hash env.txHash, w3Qty(3'u64))
|
|
|
|
check res3.isNil
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "eth_getTransactionByBlockNumberAndIndex":
|
2023-12-08 09:35:50 +00:00
|
|
|
let res = await client.eth_getTransactionByBlockNumberAndIndex("latest", w3Qty(1'u64))
|
|
|
|
check res.isNil.not
|
|
|
|
check res.blockNumber.get() == w3Qty(1'u64)
|
2021-06-22 01:32:32 +00:00
|
|
|
|
2023-12-08 09:35:50 +00:00
|
|
|
let res2 = await client.eth_getTransactionByBlockNumberAndIndex("latest", w3Qty(3'u64))
|
|
|
|
check res2.isNil
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "eth_getTransactionReceipt":
|
2023-12-08 09:35:50 +00:00
|
|
|
let res = await client.eth_getTransactionReceipt(w3Hash env.txHash)
|
|
|
|
check res.isNil.not
|
|
|
|
check res.blockNumber == w3Qty(1'u64)
|
2021-06-22 01:32:32 +00:00
|
|
|
|
2023-12-08 09:35:50 +00:00
|
|
|
let res2 = await client.eth_getTransactionReceipt(w3Hash env.blockHash)
|
|
|
|
check res2.isNil
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "eth_getUncleByBlockHashAndIndex":
|
2023-12-08 09:35:50 +00:00
|
|
|
let res = await client.eth_getUncleByBlockHashAndIndex(w3Hash env.blockHash, w3Qty(0'u64))
|
|
|
|
check res.isNil.not
|
|
|
|
check res.number == w3Qty(1'u64)
|
2021-06-22 01:32:32 +00:00
|
|
|
|
2023-12-08 09:35:50 +00:00
|
|
|
let res2 = await client.eth_getUncleByBlockHashAndIndex(w3Hash env.blockHash, w3Qty(1'u64))
|
|
|
|
check res2.isNil
|
2021-06-22 01:32:32 +00:00
|
|
|
|
2023-12-08 09:35:50 +00:00
|
|
|
let res3 = await client.eth_getUncleByBlockHashAndIndex(w3Hash env.txHash, w3Qty(0'u64))
|
|
|
|
check res3.isNil
|
2021-06-22 01:32:32 +00:00
|
|
|
|
|
|
|
test "eth_getUncleByBlockNumberAndIndex":
|
2023-12-08 09:35:50 +00:00
|
|
|
let res = await client.eth_getUncleByBlockNumberAndIndex("latest", w3Qty(0'u64))
|
|
|
|
check res.isNil.not
|
|
|
|
check res.number == w3Qty(1'u64)
|
2021-06-22 01:32:32 +00:00
|
|
|
|
2023-12-08 09:35:50 +00:00
|
|
|
let res2 = await client.eth_getUncleByBlockNumberAndIndex("latest", w3Qty(1'u64))
|
|
|
|
check res2.isNil
|
2021-06-22 01:32:32 +00:00
|
|
|
|
2022-06-29 15:44:08 +00:00
|
|
|
test "eth_getLogs by blockhash, no filters":
|
|
|
|
let testHeader = getBlockHeader4514995()
|
|
|
|
let testHash = testHeader.blockHash
|
|
|
|
let filterOptions = FilterOptions(
|
2023-12-08 09:35:50 +00:00
|
|
|
blockHash: some(w3Hash testHash),
|
2022-06-29 15:44:08 +00:00
|
|
|
topics: @[]
|
|
|
|
)
|
|
|
|
let logs = await client.eth_getLogs(filterOptions)
|
|
|
|
|
|
|
|
check:
|
|
|
|
len(logs) == 54
|
|
|
|
|
|
|
|
var i = 0
|
|
|
|
for l in logs:
|
|
|
|
check:
|
|
|
|
l.blockHash.isSome()
|
2023-12-08 09:35:50 +00:00
|
|
|
l.blockHash.unsafeGet() == w3Hash testHash
|
|
|
|
l.logIndex.unsafeGet() == w3Qty(i.uint64)
|
2022-06-29 15:44:08 +00:00
|
|
|
inc i
|
|
|
|
|
|
|
|
test "eth_getLogs by blockNumber, no filters":
|
|
|
|
let testHeader = getBlockHeader4514995()
|
|
|
|
let testHash = testHeader.blockHash
|
2023-12-08 09:35:50 +00:00
|
|
|
let fBlock = blockId(testHeader.blockNumber.truncate(uint64))
|
|
|
|
let tBlock = blockId(testHeader.blockNumber.truncate(uint64))
|
2022-06-29 15:44:08 +00:00
|
|
|
let filterOptions = FilterOptions(
|
|
|
|
fromBlock: some(fBlock),
|
|
|
|
toBlock: some(tBlock)
|
|
|
|
)
|
|
|
|
let logs = await client.eth_getLogs(filterOptions)
|
|
|
|
|
|
|
|
check:
|
|
|
|
len(logs) == 54
|
|
|
|
|
|
|
|
var i = 0
|
|
|
|
for l in logs:
|
|
|
|
check:
|
|
|
|
l.blockHash.isSome()
|
2023-12-08 09:35:50 +00:00
|
|
|
l.blockHash.unsafeGet() == w3Hash testHash
|
|
|
|
l.logIndex.unsafeGet() == w3Qty(i.uint64)
|
2022-06-29 15:44:08 +00:00
|
|
|
inc i
|
|
|
|
|
|
|
|
test "eth_getLogs by blockhash, filter logs at specific postions":
|
|
|
|
let testHeader = getBlockHeader4514995()
|
|
|
|
let testHash = testHeader.blockHash
|
|
|
|
|
2023-12-08 09:35:50 +00:00
|
|
|
let topic = w3Hash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef")
|
|
|
|
let topic1 = w3Hash("0x000000000000000000000000fdc183d01a793613736cd40a5a578f49add1772b")
|
2022-06-29 15:44:08 +00:00
|
|
|
|
|
|
|
let filterOptions = FilterOptions(
|
2023-12-08 09:35:50 +00:00
|
|
|
blockHash: some(w3Hash testHash),
|
|
|
|
topics: @[some(@[topic]), none[seq[Web3Hash]](), some(@[topic1])]
|
2022-06-29 15:44:08 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
let logs = await client.eth_getLogs(filterOptions)
|
|
|
|
|
|
|
|
check:
|
|
|
|
len(logs) == 1
|
|
|
|
|
|
|
|
|
|
|
|
test "eth_getLogs by blockhash, filter logs at specific postions with or options":
|
|
|
|
let testHeader = getBlockHeader4514995()
|
|
|
|
let testHash = testHeader.blockHash
|
|
|
|
|
2023-12-08 09:35:50 +00:00
|
|
|
let topic = w3Hash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef")
|
|
|
|
let topic1 = w3Hash("0xa64da754fccf55aa65a1f0128a648633fade3884b236e879ee9f64c78df5d5d7")
|
2022-06-29 15:44:08 +00:00
|
|
|
|
2023-12-08 09:35:50 +00:00
|
|
|
let topic2 = w3Hash("0x000000000000000000000000e16c02eac87920033ac72fc55ee1df3151c75786")
|
|
|
|
let topic3 = w3Hash("0x000000000000000000000000b626a5facc4de1c813f5293ec3be31979f1d1c78")
|
2022-06-29 15:44:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let filterOptions = FilterOptions(
|
2023-12-08 09:35:50 +00:00
|
|
|
blockHash: some(w3Hash testHash),
|
2022-06-29 15:44:08 +00:00
|
|
|
topics: @[
|
|
|
|
some(@[topic, topic1]),
|
|
|
|
some(@[topic2, topic3])
|
|
|
|
]
|
|
|
|
)
|
|
|
|
|
|
|
|
let logs = await client.eth_getLogs(filterOptions)
|
|
|
|
|
|
|
|
check:
|
|
|
|
len(logs) == 2
|
|
|
|
|
2021-06-22 01:32:32 +00:00
|
|
|
rpcServer.stop()
|
|
|
|
rpcServer.close()
|
|
|
|
|
|
|
|
when isMainModule:
|
|
|
|
rpcMain()
|