nim-ethers/testmodule/providers/jsonrpc/testConversions.nim

255 lines
13 KiB
Nim

import std/strutils
import std/unittest
import pkg/ethers/provider
import pkg/ethers/providers/jsonrpc/conversions
import pkg/questionable
import pkg/questionable/results
import pkg/serde
import pkg/stew/byteutils
func flatten(s: string): string =
s.replace(" ")
.replace("\n")
suite "JSON Conversions":
test "missing block number in Block isNone":
var json = %*{
"number": newJNull(),
"hash":"0x2d7d68c8f48b4213d232a1f12cab8c9fac6195166bb70a5fb21397984b9fe1c7",
"timestamp":"0x6285c293"
}
let blk1 = !Block.fromJson(json)
check blk1.number.isNone
json["number"] = newJString("")
let blk2 = !Block.fromJson(json)
check blk2.number.isNone
test "missing block hash in Block isNone":
var blkJson = %*{
"subscription": "0x20",
"result":{
"number": "0x1",
"hash": newJNull(),
"timestamp": "0x6285c293"
}
}
without blk =? Block.fromJson(blkJson["result"]):
unittest.fail
check blk.hash.isNone
test "missing block number in TransactionReceipt isNone":
var json = %*{
"from": newJNull(),
"to": "0x5fbdb2315678afecb367f032d93f642f64180aa3",
"contractAddress": newJNull(),
"transactionIndex": "0x0",
"gasUsed": "0x10db1",
"logsBloom": "0x00000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000840020000000000000000000800000000000000000000000010000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000042000000000000000000000000000000000000000000000000000020000000000000000000000000000000000001000000000000000000000000000000",
"blockHash": "0x7b00154e06fe4f27a87208eba220efb4dbc52f7429549a39a17bba2e0d98b960",
"transactionHash": "0xa64f07b370cbdcce381ec9bfb6c8004684341edfb6848fd418189969d4b9139c",
"logs": [
{
"data": "0x0000000000000000000000000000000000000000000000000000000000000064",
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0x00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8"
]
}
],
"blockNumber": newJNull(),
"cumulativeGasUsed": "0x10db1",
"status": "0x1",
"effectiveGasPrice": "0x3b9aca08",
"type": "0x0"
}
without receipt1 =? TransactionReceipt.fromJson(json):
unittest.fail
check receipt1.blockNumber.isNone
json["blockNumber"] = newJString("")
without receipt2 =? TransactionReceipt.fromJson(json):
unittest.fail
check receipt2.blockNumber.isNone
test "missing block hash in TransactionReceipt isNone":
let json = %*{
"from": newJNull(),
"to": "0x5fbdb2315678afecb367f032d93f642f64180aa3",
"contractAddress": newJNull(),
"transactionIndex": "0x0",
"gasUsed": "0x10db1",
"logsBloom": "0x00000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000840020000000000000000000800000000000000000000000010000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000042000000000000000000000000000000000000000000000000000020000000000000000000000000000000000001000000000000000000000000000000",
"blockHash": newJNull(),
"transactionHash": "0xa64f07b370cbdcce381ec9bfb6c8004684341edfb6848fd418189969d4b9139c",
"logs": [
{
"data": "0x0000000000000000000000000000000000000000000000000000000000000064",
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0x00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8"
]
}
],
"blockNumber": newJNull(),
"cumulativeGasUsed": "0x10db1",
"status": "0x1",
"effectiveGasPrice": "0x3b9aca08",
"type": "0x0"
}
without receipt =? TransactionReceipt.fromJson(json):
unittest.fail
check receipt.blockHash.isNone
test "correctly deserializes PastTransaction":
let json = %*{
"blockHash":"0x595bffbe897e025ea2df3213c4cc52c3f3d69bc04b49011d558f1b0e70038922",
"blockNumber":"0x22e",
"from":"0xe00b677c29ff8d8fe6068530e2bc36158c54dd34",
"gas":"0x4d4bb",
"gasPrice":"0x3b9aca07",
"hash":"0xa31608907c338d6497b0c6ec81049d845c7d409490ebf78171f35143897ca790",
"input":"0x6368a471d26ff5c7f835c1a8203235e88846ce1a196d6e79df0eaedd1b8ed3deec2ae5c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000012a00000000000000000000000000000000000000000000000000000000000000",
"nonce":"0x3",
"to":"0x92f09aa59dccb892a9f5406ddd9c0b98f02ea57e",
"transactionIndex":"0x3",
"value":"0x0",
"type":"0x0",
"chainId":"0xc0de4",
"v":"0x181bec",
"r":"0x57ba18460934526333b80b0fea08737c363f3cd5fbec4a25a8a25e3e8acb362a",
"s":"0x33aa50bc8bd719b6b17ad0bf52006bf8943999198f2bf731eb33c118091000f2"
}
without tx =? PastTransaction.fromJson(json):
unittest.fail
check tx.blockHash == BlockHash.fromHex("0x595bffbe897e025ea2df3213c4cc52c3f3d69bc04b49011d558f1b0e70038922")
check tx.blockNumber == 0x22e.u256
check tx.sender == Address.init("0xe00b677c29ff8d8fe6068530e2bc36158c54dd34").get
check tx.gas == 0x4d4bb.u256
check tx.gasPrice == 0x3b9aca07.u256
check tx.hash == TransactionHash(array[32, byte].fromHex("0xa31608907c338d6497b0c6ec81049d845c7d409490ebf78171f35143897ca790"))
check tx.input == hexToSeqByte("0x6368a471d26ff5c7f835c1a8203235e88846ce1a196d6e79df0eaedd1b8ed3deec2ae5c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000012a00000000000000000000000000000000000000000000000000000000000000")
check tx.nonce == 0x3.u256
check tx.to == Address.init("0x92f09aa59dccb892a9f5406ddd9c0b98f02ea57e").get
check tx.transactionIndex == 0x3.u256
check tx.value == 0.u256
check tx.transactionType == some TransactionType.Legacy
check tx.chainId == some 0xc0de4.u256
check tx.v == 0x181bec.u256
check tx.r == UInt256.fromBytesBE(hexToSeqByte("0x57ba18460934526333b80b0fea08737c363f3cd5fbec4a25a8a25e3e8acb362a"))
check tx.s == UInt256.fromBytesBE(hexToSeqByte("0x33aa50bc8bd719b6b17ad0bf52006bf8943999198f2bf731eb33c118091000f2"))
test "PastTransaction serializes correctly":
let tx = PastTransaction(
blockHash: BlockHash.fromHex("0x595bffbe897e025ea2df3213c4cc52c3f3d69bc04b49011d558f1b0e70038922"),
blockNumber: 0x22e.u256,
sender: Address.init("0xe00b677c29ff8d8fe6068530e2bc36158c54dd34").get,
gas: 0x4d4bb.u256,
gasPrice: 0x3b9aca07.u256,
hash: TransactionHash(array[32, byte].fromHex("0xa31608907c338d6497b0c6ec81049d845c7d409490ebf78171f35143897ca790")),
input: hexToSeqByte("0x6368a471d26ff5c7f835c1a8203235e88846ce1a196d6e79df0eaedd1b8ed3deec2ae5c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000012a00000000000000000000000000000000000000000000000000000000000000"),
nonce: 0x3.u256,
to: Address.init("0x92f09aa59dccb892a9f5406ddd9c0b98f02ea57e").get,
transactionIndex: 0x3.u256,
value: 0.u256,
v: 0x181bec.u256,
r: UInt256.fromBytesBE(hexToSeqByte("0x57ba18460934526333b80b0fea08737c363f3cd5fbec4a25a8a25e3e8acb362a")),
s: UInt256.fromBytesBE(hexToSeqByte("0x33aa50bc8bd719b6b17ad0bf52006bf8943999198f2bf731eb33c118091000f2")),
transactionType: some TransactionType.Legacy,
chainId: some 0xc0de4.u256
)
let expected = """
{
"blockHash":"0x595bffbe897e025ea2df3213c4cc52c3f3d69bc04b49011d558f1b0e70038922",
"blockNumber":"0x22e",
"from":"0xe00b677c29ff8d8fe6068530e2bc36158c54dd34",
"gas":"0x4d4bb",
"gasPrice":"0x3b9aca07",
"hash":"0xa31608907c338d6497b0c6ec81049d845c7d409490ebf78171f35143897ca790",
"input":"0x6368a471d26ff5c7f835c1a8203235e88846ce1a196d6e79df0eaedd1b8ed3deec2ae5c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000012a00000000000000000000000000000000000000000000000000000000000000",
"nonce":"0x3",
"to":"0x92f09aa59dccb892a9f5406ddd9c0b98f02ea57e",
"transactionIndex":"0x3",
"type":"0x0",
"chainId":"0xc0de4",
"value":"0x0",
"v":"0x181bec",
"r":"0x57ba18460934526333b80b0fea08737c363f3cd5fbec4a25a8a25e3e8acb362a",
"s":"0x33aa50bc8bd719b6b17ad0bf52006bf8943999198f2bf731eb33c118091000f2"
}""".flatten
check $(%tx) == expected
test "correctly converts PastTransaction to Transaction":
let json = %*{
"blockHash":"0x595bffbe897e025ea2df3213c4cc52c3f3d69bc04b49011d558f1b0e70038922",
"blockNumber":"0x22e",
"from":"0xe00b677c29ff8d8fe6068530e2bc36158c54dd34",
"gas":"0x52277",
"gasPrice":"0x3b9aca07",
"hash":"0xa31608907c338d6497b0c6ec81049d845c7d409490ebf78171f35143897ca790",
"input":"0x6368a471d26ff5c7f835c1a8203235e88846ce1a196d6e79df0eaedd1b8ed3deec2ae5c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000012a00000000000000000000000000000000000000000000000000000000000000",
"nonce":"0x3",
"to":"0x92f09aa59dccb892a9f5406ddd9c0b98f02ea57e",
"transactionIndex":"0x3",
"value":"0x0",
"type":"0x0",
"chainId":"0xc0de4",
"v":"0x181bec",
"r":"0x57ba18460934526333b80b0fea08737c363f3cd5fbec4a25a8a25e3e8acb362a",
"s":"0x33aa50bc8bd719b6b17ad0bf52006bf8943999198f2bf731eb33c118091000f2"
}
without past =? PastTransaction.fromJson(json):
unittest.fail
check %past.toTransaction == %*{
"to": !Address.init("0x92f09aa59dccb892a9f5406ddd9c0b98f02ea57e"),
"data": hexToSeqByte("0x6368a471d26ff5c7f835c1a8203235e88846ce1a196d6e79df0eaedd1b8ed3deec2ae5c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000012a00000000000000000000000000000000000000000000000000000000000000"),
"value": "0x0",
"from": !Address.init("0xe00b677c29ff8d8fe6068530e2bc36158c54dd34"),
"nonce": 0x3.u256,
"chainId": 0xc0de4.u256,
"gasPrice": 0x3b9aca07.u256,
"gas": 0x52277.u256
}
test "correctly deserializes BlockTag":
check !BlockTag.fromJson(newJString("earliest")) == BlockTag.earliest
check !BlockTag.fromJson(newJString("latest")) == BlockTag.latest
check !BlockTag.fromJson(newJString("pending")) == BlockTag.pending
check !BlockTag.fromJson(newJString("0x1")) == BlockTag.init(1.u256)
test "fails to deserialize BlockTag from an empty string":
let res = BlockTag.fromJson(newJString(""))
check res.error of SerializationError
check res.error.msg == "Failed to convert '\"\"' to BlockTag: must be one of 'earliest', 'latest', 'pending'"
test "correctly deserializes TransactionType":
check !TransactionType.fromJson(newJString("0x0")) == TransactionType.Legacy
check !TransactionType.fromJson(newJString("0x1")) == TransactionType.AccessList
check !TransactionType.fromJson(newJString("0x2")) == TransactionType.Dynamic
test "correctly serializes TransactionType":
check TransactionType.Legacy.toJson == "\"0x0\""
check TransactionType.AccessList.toJson == "\"0x1\""
check TransactionType.Dynamic.toJson == "\"0x2\""
test "correctly deserializes TransactionStatus":
check !TransactionStatus.fromJson(newJString("0x0")) == TransactionStatus.Failure
check !TransactionStatus.fromJson(newJString("0x1")) == TransactionStatus.Success
check !TransactionStatus.fromJson(newJString("0x2")) == TransactionStatus.Invalid
test "correctly serializes TransactionStatus":
check TransactionStatus.Failure.toJson == "\"0x0\""
check TransactionStatus.Success.toJson == "\"0x1\""
check TransactionStatus.Invalid.toJson == "\"0x2\""