mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-12 21:34:33 +00:00
Updates to Fluffy to support hive tests. (#2333)
* Updates to Fluffy book for hive tests. * Add support to disable state root checks for state content from the command line. * Update portal_stateStore endpoint to support decoding offer and storing retrieval value.
This commit is contained in:
parent
eb041abba7
commit
9c26fa3298
@ -299,6 +299,13 @@ type
|
|||||||
name: "disable-poke"
|
name: "disable-poke"
|
||||||
.}: bool
|
.}: bool
|
||||||
|
|
||||||
|
disableStateRootValidation* {.
|
||||||
|
hidden,
|
||||||
|
desc: "Disables state root validation for content received by the state network.",
|
||||||
|
defaultValue: false,
|
||||||
|
name: "disable-state-root-validation"
|
||||||
|
.}: bool
|
||||||
|
|
||||||
case cmd* {.command, defaultValue: noCommand.}: PortalCmd
|
case cmd* {.command, defaultValue: noCommand.}: PortalCmd
|
||||||
of noCommand:
|
of noCommand:
|
||||||
discard
|
discard
|
||||||
|
@ -1,27 +1,27 @@
|
|||||||
# Fluffy with Portal-hive
|
# Fluffy with Portal-hive
|
||||||
|
|
||||||
Fluffy is one of the Portal clients that is being tested with [portal-hive](https://github.com/ethereum/portal-hive).
|
Fluffy is one of the Portal clients that is being tested with [hive](https://github.com/ethereum/hive).
|
||||||
|
|
||||||
To see the status of the tests for the current version you can access [https://portal-hive.ethdevops.io/](https://portal-hive.ethdevops.io/).
|
To see the status of the tests for the current version you can access [https://portal-hive.ethdevops.io/](https://portal-hive.ethdevops.io/).
|
||||||
|
|
||||||
## Run the hive tests locally
|
## Run the hive tests locally
|
||||||
|
|
||||||
Build portal-hive:
|
Build hive:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
git clone https://github.com/ethereum/portal-hive.git
|
git clone https://github.com/ethereum/hive.git
|
||||||
cd ./portal-hive
|
cd ./hive
|
||||||
go build .
|
go build .
|
||||||
```
|
```
|
||||||
|
|
||||||
Example commands for running test suites:
|
Example commands for running test suites:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# Run the rpc-compat tests with the 3 different clients
|
# Run the history tests with the 3 different clients
|
||||||
./hive --sim rpc-compat --client fluffy,trin,ultralight
|
./hive --sim history --client fluffy,trin,ultralight
|
||||||
|
|
||||||
# Run the portal-interop tests with only the fluffy client
|
# Run the state tests with only the fluffy client
|
||||||
./hive --sim portal-interop --client fluffy
|
./hive --sim state --client fluffy
|
||||||
|
|
||||||
# Access results through web-ui:
|
# Access results through web-ui:
|
||||||
```sh
|
```sh
|
||||||
@ -30,7 +30,7 @@ go build ./cmd/hiveview
|
|||||||
```
|
```
|
||||||
|
|
||||||
!!! note
|
!!! note
|
||||||
You can see all the implemented simulators in [https://github.com/ethereum/portal-hive/tree/main/simulators](https://github.com/ethereum/portal-hive/tree/main/simulators)
|
You can see all the implemented simulators in [https://github.com/ethereum/hive/tree/master/simulators](https://github.com/ethereum/hive/tree/master/simulators)
|
||||||
|
|
||||||
## Build a local development Docker image for portal-hive
|
## Build a local development Docker image for portal-hive
|
||||||
|
|
||||||
@ -55,4 +55,3 @@ docker build --tag fluffy-dev --file ./fluffy/tools/docker/Dockerfile.portalhive
|
|||||||
The `./vendors` dir is dockerignored and cached. If you have to make local
|
The `./vendors` dir is dockerignored and cached. If you have to make local
|
||||||
changes to one of the dependencies in that directory you will have to remove
|
changes to one of the dependencies in that directory you will have to remove
|
||||||
`vendors/` from `./fluffy/tools/docker/Dockerfile.portalhive.dockerignore`.
|
`vendors/` from `./fluffy/tools/docker/Dockerfile.portalhive.dockerignore`.
|
||||||
|
|
||||||
|
@ -234,6 +234,7 @@ proc run(config: PortalConf) {.raises: [CatchableError].} =
|
|||||||
bootstrapRecords = bootstrapRecords,
|
bootstrapRecords = bootstrapRecords,
|
||||||
portalConfig = portalConfig,
|
portalConfig = portalConfig,
|
||||||
historyNetwork = historyNetwork,
|
historyNetwork = historyNetwork,
|
||||||
|
not config.disableStateRootValidation,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
@ -32,6 +32,7 @@ type StateNetwork* = ref object
|
|||||||
contentQueue*: AsyncQueue[(Opt[NodeId], ContentKeysList, seq[seq[byte]])]
|
contentQueue*: AsyncQueue[(Opt[NodeId], ContentKeysList, seq[seq[byte]])]
|
||||||
processContentLoop: Future[void]
|
processContentLoop: Future[void]
|
||||||
historyNetwork: Opt[HistoryNetwork]
|
historyNetwork: Opt[HistoryNetwork]
|
||||||
|
validateStateIsCanonical: bool
|
||||||
|
|
||||||
func toContentIdHandler(contentKey: ByteList): results.Opt[ContentId] =
|
func toContentIdHandler(contentKey: ByteList): results.Opt[ContentId] =
|
||||||
ok(toContentId(contentKey))
|
ok(toContentId(contentKey))
|
||||||
@ -44,6 +45,7 @@ proc new*(
|
|||||||
bootstrapRecords: openArray[Record] = [],
|
bootstrapRecords: openArray[Record] = [],
|
||||||
portalConfig: PortalProtocolConfig = defaultPortalProtocolConfig,
|
portalConfig: PortalProtocolConfig = defaultPortalProtocolConfig,
|
||||||
historyNetwork = Opt.none(HistoryNetwork),
|
historyNetwork = Opt.none(HistoryNetwork),
|
||||||
|
validateStateIsCanonical = true,
|
||||||
): T =
|
): T =
|
||||||
let cq = newAsyncQueue[(Opt[NodeId], ContentKeysList, seq[seq[byte]])](50)
|
let cq = newAsyncQueue[(Opt[NodeId], ContentKeysList, seq[seq[byte]])](50)
|
||||||
|
|
||||||
@ -67,6 +69,7 @@ proc new*(
|
|||||||
contentDB: contentDB,
|
contentDB: contentDB,
|
||||||
contentQueue: cq,
|
contentQueue: cq,
|
||||||
historyNetwork: historyNetwork,
|
historyNetwork: historyNetwork,
|
||||||
|
validateStateIsCanonical: validateStateIsCanonical,
|
||||||
)
|
)
|
||||||
|
|
||||||
proc getContent(
|
proc getContent(
|
||||||
@ -146,10 +149,15 @@ proc processOffer*(
|
|||||||
let contentValue = V.decode(contentValueBytes).valueOr:
|
let contentValue = V.decode(contentValueBytes).valueOr:
|
||||||
return err("Unable to decode offered content value")
|
return err("Unable to decode offered content value")
|
||||||
|
|
||||||
|
let res =
|
||||||
|
if n.validateStateIsCanonical:
|
||||||
let stateRoot = (await n.getStateRootByBlockHash(contentValue.blockHash)).valueOr:
|
let stateRoot = (await n.getStateRootByBlockHash(contentValue.blockHash)).valueOr:
|
||||||
return err("Failed to get state root by block hash")
|
return err("Failed to get state root by block hash")
|
||||||
|
validateOffer(Opt.some(stateRoot), contentKey, contentValue)
|
||||||
|
else:
|
||||||
|
# Skip state root validation
|
||||||
|
validateOffer(Opt.none(KeccakHash), contentKey, contentValue)
|
||||||
|
|
||||||
let res = validateOffer(stateRoot, contentKey, contentValue)
|
|
||||||
if res.isErr():
|
if res.isErr():
|
||||||
return err("Offered content failed validation: " & res.error())
|
return err("Offered content failed validation: " & res.error())
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ proc isValidNextNode(thisNodeRlp: Rlp, rlpIdx: int, nextNode: TrieNode): bool =
|
|||||||
nextNode.hashEquals(nextHash)
|
nextNode.hashEquals(nextHash)
|
||||||
|
|
||||||
proc validateTrieProof*(
|
proc validateTrieProof*(
|
||||||
expectedRootHash: KeccakHash,
|
expectedRootHash: Opt[KeccakHash],
|
||||||
path: Nibbles,
|
path: Nibbles,
|
||||||
proof: TrieProof,
|
proof: TrieProof,
|
||||||
allowKeyEndInPathForLeafs = false,
|
allowKeyEndInPathForLeafs = false,
|
||||||
@ -38,7 +38,9 @@ proc validateTrieProof*(
|
|||||||
if proof.len() == 0:
|
if proof.len() == 0:
|
||||||
return err("proof is empty")
|
return err("proof is empty")
|
||||||
|
|
||||||
if not proof[0].hashEquals(expectedRootHash):
|
# TODO: Remove this once the hive tests support passing in state roots from the history network
|
||||||
|
if expectedRootHash.isSome():
|
||||||
|
if not proof[0].hashEquals(expectedRootHash.get()):
|
||||||
return err("hash of proof root node doesn't match the expected root hash")
|
return err("hash of proof root node doesn't match the expected root hash")
|
||||||
|
|
||||||
let nibbles = path.unpackNibbles()
|
let nibbles = path.unpackNibbles()
|
||||||
@ -131,14 +133,18 @@ proc validateRetrieval*(
|
|||||||
err("hash of bytecode doesn't match the expected code hash")
|
err("hash of bytecode doesn't match the expected code hash")
|
||||||
|
|
||||||
proc validateOffer*(
|
proc validateOffer*(
|
||||||
trustedStateRoot: KeccakHash, key: AccountTrieNodeKey, offer: AccountTrieNodeOffer
|
trustedStateRoot: Opt[KeccakHash],
|
||||||
|
key: AccountTrieNodeKey,
|
||||||
|
offer: AccountTrieNodeOffer,
|
||||||
): Result[void, string] =
|
): Result[void, string] =
|
||||||
?validateTrieProof(trustedStateRoot, key.path, offer.proof)
|
?validateTrieProof(trustedStateRoot, key.path, offer.proof)
|
||||||
|
|
||||||
validateRetrieval(key, offer.toRetrievalValue())
|
validateRetrieval(key, offer.toRetrievalValue())
|
||||||
|
|
||||||
proc validateOffer*(
|
proc validateOffer*(
|
||||||
trustedStateRoot: KeccakHash, key: ContractTrieNodeKey, offer: ContractTrieNodeOffer
|
trustedStateRoot: Opt[KeccakHash],
|
||||||
|
key: ContractTrieNodeKey,
|
||||||
|
offer: ContractTrieNodeOffer,
|
||||||
): Result[void, string] =
|
): Result[void, string] =
|
||||||
?validateTrieProof(
|
?validateTrieProof(
|
||||||
trustedStateRoot,
|
trustedStateRoot,
|
||||||
@ -149,12 +155,12 @@ proc validateOffer*(
|
|||||||
|
|
||||||
let account = ?offer.accountProof.toAccount()
|
let account = ?offer.accountProof.toAccount()
|
||||||
|
|
||||||
?validateTrieProof(account.storageRoot, key.path, offer.storageProof)
|
?validateTrieProof(Opt.some(account.storageRoot), key.path, offer.storageProof)
|
||||||
|
|
||||||
validateRetrieval(key, offer.toRetrievalValue())
|
validateRetrieval(key, offer.toRetrievalValue())
|
||||||
|
|
||||||
proc validateOffer*(
|
proc validateOffer*(
|
||||||
trustedStateRoot: KeccakHash, key: ContractCodeKey, offer: ContractCodeOffer
|
trustedStateRoot: Opt[KeccakHash], key: ContractCodeKey, offer: ContractCodeOffer
|
||||||
): Result[void, string] =
|
): Result[void, string] =
|
||||||
?validateTrieProof(
|
?validateTrieProof(
|
||||||
trustedStateRoot,
|
trustedStateRoot,
|
||||||
|
@ -13,6 +13,7 @@ import
|
|||||||
json_serialization/std/tables,
|
json_serialization/std/tables,
|
||||||
stew/byteutils,
|
stew/byteutils,
|
||||||
../network/wire/portal_protocol,
|
../network/wire/portal_protocol,
|
||||||
|
../network/state/state_content,
|
||||||
./rpc_types
|
./rpc_types
|
||||||
|
|
||||||
{.warning[UnusedImport]: off.}
|
{.warning[UnusedImport]: off.}
|
||||||
@ -42,6 +43,12 @@ TraceResponse.useDefaultSerializationIn JrpcConv
|
|||||||
proc installPortalApiHandlers*(
|
proc installPortalApiHandlers*(
|
||||||
rpcServer: RpcServer | RpcProxy, p: PortalProtocol, network: static string
|
rpcServer: RpcServer | RpcProxy, p: PortalProtocol, network: static string
|
||||||
) =
|
) =
|
||||||
|
let
|
||||||
|
invalidKeyErr =
|
||||||
|
(ref errors.InvalidRequest)(code: -32602, msg: "Invalid content key")
|
||||||
|
invalidValueErr =
|
||||||
|
(ref errors.InvalidRequest)(code: -32602, msg: "Invalid content value")
|
||||||
|
|
||||||
rpcServer.rpc("portal_" & network & "NodeInfo") do() -> NodeInfo:
|
rpcServer.rpc("portal_" & network & "NodeInfo") do() -> NodeInfo:
|
||||||
return p.routingTable.getNodeInfo()
|
return p.routingTable.getNodeInfo()
|
||||||
|
|
||||||
@ -212,14 +219,39 @@ proc installPortalApiHandlers*(
|
|||||||
rpcServer.rpc("portal_" & network & "Store") do(
|
rpcServer.rpc("portal_" & network & "Store") do(
|
||||||
contentKey: string, contentValue: string
|
contentKey: string, contentValue: string
|
||||||
) -> bool:
|
) -> bool:
|
||||||
let key = ByteList.init(hexToSeqByte(contentKey))
|
let
|
||||||
let contentId = p.toContentId(key)
|
key = ByteList.init(hexToSeqByte(contentKey))
|
||||||
|
contentValueBytes = hexToSeqByte(contentValue)
|
||||||
|
|
||||||
|
let valueToStore =
|
||||||
|
if network == "state":
|
||||||
|
let decodedKey = ContentKey.decode(key).valueOr:
|
||||||
|
raise invalidKeyErr
|
||||||
|
|
||||||
|
case decodedKey.contentType
|
||||||
|
of unused:
|
||||||
|
raise invalidKeyErr
|
||||||
|
of accountTrieNode:
|
||||||
|
let offerValue = AccountTrieNodeOffer.decode(contentValueBytes).valueOr:
|
||||||
|
raise invalidValueErr
|
||||||
|
offerValue.toRetrievalValue.encode()
|
||||||
|
of contractTrieNode:
|
||||||
|
let offerValue = ContractTrieNodeOffer.decode(contentValueBytes).valueOr:
|
||||||
|
raise invalidValueErr
|
||||||
|
offerValue.toRetrievalValue.encode()
|
||||||
|
of contractCode:
|
||||||
|
let offerValue = ContractCodeOffer.decode(contentValueBytes).valueOr:
|
||||||
|
raise invalidValueErr
|
||||||
|
offerValue.toRetrievalValue.encode()
|
||||||
|
else:
|
||||||
|
contentValueBytes
|
||||||
|
|
||||||
|
let contentId = p.toContentId(key)
|
||||||
if contentId.isSome():
|
if contentId.isSome():
|
||||||
p.storeContent(key, contentId.get(), hexToSeqByte(contentValue))
|
p.storeContent(key, contentId.get(), valueToStore)
|
||||||
return true
|
return true
|
||||||
else:
|
else:
|
||||||
raise (ref errors.InvalidRequest)(code: -32602, msg: "Invalid content key")
|
raise invalidKeyErr
|
||||||
|
|
||||||
rpcServer.rpc("portal_" & network & "LocalContent") do(contentKey: string) -> string:
|
rpcServer.rpc("portal_" & network & "LocalContent") do(contentKey: string) -> string:
|
||||||
let
|
let
|
||||||
|
@ -42,12 +42,16 @@ suite "State Gossip getParent - Genesis JSON Files":
|
|||||||
|
|
||||||
# validate each parent offer until getting to the root node
|
# validate each parent offer until getting to the root node
|
||||||
var parent = offer.withKey(key).getParent()
|
var parent = offer.withKey(key).getParent()
|
||||||
check validateOffer(accountState.rootHash(), parent.key, parent.offer).isOk()
|
check validateOffer(Opt.some(accountState.rootHash()), parent.key, parent.offer)
|
||||||
|
.isOk()
|
||||||
db.put(parent.key.nodeHash.data, parent.offer.toRetrievalValue().node.asSeq())
|
db.put(parent.key.nodeHash.data, parent.offer.toRetrievalValue().node.asSeq())
|
||||||
|
|
||||||
for i in proof.low ..< proof.high - 1:
|
for i in proof.low ..< proof.high - 1:
|
||||||
parent = parent.getParent()
|
parent = parent.getParent()
|
||||||
check validateOffer(accountState.rootHash(), parent.key, parent.offer).isOk()
|
check validateOffer(
|
||||||
|
Opt.some(accountState.rootHash()), parent.key, parent.offer
|
||||||
|
)
|
||||||
|
.isOk()
|
||||||
db.put(parent.key.nodeHash.data, parent.offer.toRetrievalValue().node.asSeq())
|
db.put(parent.key.nodeHash.data, parent.offer.toRetrievalValue().node.asSeq())
|
||||||
|
|
||||||
# after putting all parent nodes into the trie, verify can lookup the leaf
|
# after putting all parent nodes into the trie, verify can lookup the leaf
|
||||||
@ -89,14 +93,19 @@ suite "State Gossip getParent - Genesis JSON Files":
|
|||||||
|
|
||||||
# validate each parent offer until getting to the root node
|
# validate each parent offer until getting to the root node
|
||||||
var parent = offer.withKey(key).getParent()
|
var parent = offer.withKey(key).getParent()
|
||||||
check validateOffer(accountState.rootHash(), parent.key, parent.offer).isOk()
|
check validateOffer(
|
||||||
|
Opt.some(accountState.rootHash()), parent.key, parent.offer
|
||||||
|
)
|
||||||
|
.isOk()
|
||||||
db.put(
|
db.put(
|
||||||
parent.key.nodeHash.data, parent.offer.toRetrievalValue().node.asSeq()
|
parent.key.nodeHash.data, parent.offer.toRetrievalValue().node.asSeq()
|
||||||
)
|
)
|
||||||
|
|
||||||
for i in storageProof.low ..< storageProof.high - 1:
|
for i in storageProof.low ..< storageProof.high - 1:
|
||||||
parent = parent.getParent()
|
parent = parent.getParent()
|
||||||
check validateOffer(accountState.rootHash(), parent.key, parent.offer)
|
check validateOffer(
|
||||||
|
Opt.some(accountState.rootHash()), parent.key, parent.offer
|
||||||
|
)
|
||||||
.isOk()
|
.isOk()
|
||||||
db.put(
|
db.put(
|
||||||
parent.key.nodeHash.data, parent.offer.toRetrievalValue().node.asSeq()
|
parent.key.nodeHash.data, parent.offer.toRetrievalValue().node.asSeq()
|
||||||
|
@ -34,15 +34,17 @@ template checkValidProofsForExistingLeafs(
|
|||||||
path: accountPath, nodeHash: keccakHash(accountProof[^1].asSeq())
|
path: accountPath, nodeHash: keccakHash(accountProof[^1].asSeq())
|
||||||
)
|
)
|
||||||
accountTrieOffer = AccountTrieNodeOffer(proof: accountProof)
|
accountTrieOffer = AccountTrieNodeOffer(proof: accountProof)
|
||||||
proofResult =
|
proofResult = validateOffer(
|
||||||
validateOffer(accountState.rootHash(), accountTrieNodeKey, accountTrieOffer)
|
Opt.some(accountState.rootHash()), accountTrieNodeKey, accountTrieOffer
|
||||||
|
)
|
||||||
check proofResult.isOk()
|
check proofResult.isOk()
|
||||||
|
|
||||||
let
|
let
|
||||||
contractCodeKey = ContractCodeKey(address: address, codeHash: acc.codeHash)
|
contractCodeKey = ContractCodeKey(address: address, codeHash: acc.codeHash)
|
||||||
contractCode =
|
contractCode =
|
||||||
ContractCodeOffer(code: Bytecode.init(account.code), accountProof: accountProof)
|
ContractCodeOffer(code: Bytecode.init(account.code), accountProof: accountProof)
|
||||||
codeResult = validateOffer(accountState.rootHash(), contractCodeKey, contractCode)
|
codeResult =
|
||||||
|
validateOffer(Opt.some(accountState.rootHash()), contractCodeKey, contractCode)
|
||||||
check codeResult.isOk()
|
check codeResult.isOk()
|
||||||
|
|
||||||
if account.code.len() > 0:
|
if account.code.len() > 0:
|
||||||
@ -64,7 +66,7 @@ template checkValidProofsForExistingLeafs(
|
|||||||
storageProof: storageProof, accountProof: accountProof
|
storageProof: storageProof, accountProof: accountProof
|
||||||
)
|
)
|
||||||
proofResult = validateOffer(
|
proofResult = validateOffer(
|
||||||
accountState.rootHash(), contractTrieNodeKey, contractTrieOffer
|
Opt.some(accountState.rootHash()), contractTrieNodeKey, contractTrieOffer
|
||||||
)
|
)
|
||||||
check proofResult.isOk()
|
check proofResult.isOk()
|
||||||
|
|
||||||
@ -88,8 +90,9 @@ template checkInvalidProofsWithBadValue(
|
|||||||
accountProof[^1][^1] += 1 # bad account leaf value
|
accountProof[^1][^1] += 1 # bad account leaf value
|
||||||
let
|
let
|
||||||
accountTrieOffer = AccountTrieNodeOffer(proof: accountProof)
|
accountTrieOffer = AccountTrieNodeOffer(proof: accountProof)
|
||||||
proofResult =
|
proofResult = validateOffer(
|
||||||
validateOffer(accountState.rootHash(), accountTrieNodeKey, accountTrieOffer)
|
Opt.some(accountState.rootHash()), accountTrieNodeKey, accountTrieOffer
|
||||||
|
)
|
||||||
check proofResult.isErr()
|
check proofResult.isErr()
|
||||||
|
|
||||||
let
|
let
|
||||||
@ -98,7 +101,8 @@ template checkInvalidProofsWithBadValue(
|
|||||||
code: Bytecode.init(@[1u8, 2, 3]), # bad code value
|
code: Bytecode.init(@[1u8, 2, 3]), # bad code value
|
||||||
accountProof: accountProof,
|
accountProof: accountProof,
|
||||||
)
|
)
|
||||||
codeResult = validateOffer(accountState.rootHash(), contractCodeKey, contractCode)
|
codeResult =
|
||||||
|
validateOffer(Opt.some(accountState.rootHash()), contractCodeKey, contractCode)
|
||||||
check codeResult.isErr()
|
check codeResult.isErr()
|
||||||
|
|
||||||
if account.code.len() > 0:
|
if account.code.len() > 0:
|
||||||
@ -122,7 +126,7 @@ template checkInvalidProofsWithBadValue(
|
|||||||
storageProof: storageProof, accountProof: accountProof
|
storageProof: storageProof, accountProof: accountProof
|
||||||
)
|
)
|
||||||
proofResult = validateOffer(
|
proofResult = validateOffer(
|
||||||
accountState.rootHash(), contractTrieNodeKey, contractTrieOffer
|
Opt.some(accountState.rootHash()), contractTrieNodeKey, contractTrieOffer
|
||||||
)
|
)
|
||||||
check proofResult.isErr()
|
check proofResult.isErr()
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ suite "State Validation - validateTrieProof":
|
|||||||
let
|
let
|
||||||
kv = getKeyBytes(i)
|
kv = getKeyBytes(i)
|
||||||
proof = trie.getTrieProof(kv)
|
proof = trie.getTrieProof(kv)
|
||||||
res = validateTrieProof(rootHash, kv.asNibbles(), proof, true)
|
res = validateTrieProof(Opt.some(rootHash), kv.asNibbles(), proof, true)
|
||||||
|
|
||||||
check:
|
check:
|
||||||
res.isOk()
|
res.isOk()
|
||||||
@ -55,7 +55,7 @@ suite "State Validation - validateTrieProof":
|
|||||||
rootHash = trie.rootHash()
|
rootHash = trie.rootHash()
|
||||||
key = getKeyBytes(numValues + 1)
|
key = getKeyBytes(numValues + 1)
|
||||||
proof = trie.getTrieProof(key)
|
proof = trie.getTrieProof(key)
|
||||||
res = validateTrieProof(rootHash, key.asNibbles(), proof, true)
|
res = validateTrieProof(Opt.some(rootHash), key.asNibbles(), proof, true)
|
||||||
|
|
||||||
check:
|
check:
|
||||||
res.isErr()
|
res.isErr()
|
||||||
@ -68,7 +68,7 @@ suite "State Validation - validateTrieProof":
|
|||||||
rootHash = trie.rootHash()
|
rootHash = trie.rootHash()
|
||||||
key = "not-exist".toBytes
|
key = "not-exist".toBytes
|
||||||
proof = trie.getTrieProof(key)
|
proof = trie.getTrieProof(key)
|
||||||
res = validateTrieProof(rootHash, key.asNibbles(), proof, true)
|
res = validateTrieProof(Opt.some(rootHash), key.asNibbles(), proof, true)
|
||||||
|
|
||||||
check:
|
check:
|
||||||
res.isErr()
|
res.isErr()
|
||||||
@ -83,7 +83,7 @@ suite "State Validation - validateTrieProof":
|
|||||||
let
|
let
|
||||||
rootHash = trie.rootHash
|
rootHash = trie.rootHash
|
||||||
proof = trie.getTrieProof(key)
|
proof = trie.getTrieProof(key)
|
||||||
res = validateTrieProof(rootHash, key.asNibbles(), proof, true)
|
res = validateTrieProof(Opt.some(rootHash), key.asNibbles(), proof, true)
|
||||||
|
|
||||||
check:
|
check:
|
||||||
res.isOk()
|
res.isOk()
|
||||||
@ -101,25 +101,25 @@ suite "State Validation - validateTrieProof":
|
|||||||
let
|
let
|
||||||
key = "doe".toBytes
|
key = "doe".toBytes
|
||||||
proof = trie.getTrieProof(key)
|
proof = trie.getTrieProof(key)
|
||||||
check validateTrieProof(rootHash, key.asNibbles(), proof, true).isOk()
|
check validateTrieProof(Opt.some(rootHash), key.asNibbles(), proof, true).isOk()
|
||||||
|
|
||||||
block:
|
block:
|
||||||
let
|
let
|
||||||
key = "dog".toBytes
|
key = "dog".toBytes
|
||||||
proof = trie.getTrieProof(key)
|
proof = trie.getTrieProof(key)
|
||||||
check validateTrieProof(rootHash, key.asNibbles(), proof, true).isOk()
|
check validateTrieProof(Opt.some(rootHash), key.asNibbles(), proof, true).isOk()
|
||||||
|
|
||||||
block:
|
block:
|
||||||
let
|
let
|
||||||
key = "dogglesworth".toBytes
|
key = "dogglesworth".toBytes
|
||||||
proof = trie.getTrieProof(key)
|
proof = trie.getTrieProof(key)
|
||||||
check validateTrieProof(rootHash, key.asNibbles(), proof, true).isOk()
|
check validateTrieProof(Opt.some(rootHash), key.asNibbles(), proof, true).isOk()
|
||||||
|
|
||||||
block:
|
block:
|
||||||
let
|
let
|
||||||
key = "dogg".toBytes
|
key = "dogg".toBytes
|
||||||
proof = trie.getTrieProof(key)
|
proof = trie.getTrieProof(key)
|
||||||
res = validateTrieProof(rootHash, key.asNibbles(), proof, true)
|
res = validateTrieProof(Opt.some(rootHash), key.asNibbles(), proof, true)
|
||||||
check:
|
check:
|
||||||
res.isErr()
|
res.isErr()
|
||||||
res.error() == "not enough nibbles to validate node prefix"
|
res.error() == "not enough nibbles to validate node prefix"
|
||||||
@ -128,7 +128,7 @@ suite "State Validation - validateTrieProof":
|
|||||||
let
|
let
|
||||||
key = "dogz".toBytes
|
key = "dogz".toBytes
|
||||||
proof = trie.getTrieProof(key)
|
proof = trie.getTrieProof(key)
|
||||||
res = validateTrieProof(rootHash, key.asNibbles(), proof, true)
|
res = validateTrieProof(Opt.some(rootHash), key.asNibbles(), proof, true)
|
||||||
check:
|
check:
|
||||||
res.isErr()
|
res.isErr()
|
||||||
res.error() == "path contains more nibbles than expected for proof"
|
res.error() == "path contains more nibbles than expected for proof"
|
||||||
@ -137,7 +137,7 @@ suite "State Validation - validateTrieProof":
|
|||||||
let
|
let
|
||||||
key = "doe".toBytes
|
key = "doe".toBytes
|
||||||
proof = newSeq[seq[byte]]().asTrieProof()
|
proof = newSeq[seq[byte]]().asTrieProof()
|
||||||
res = validateTrieProof(rootHash, key.asNibbles(), proof, true)
|
res = validateTrieProof(Opt.some(rootHash), key.asNibbles(), proof, true)
|
||||||
check:
|
check:
|
||||||
res.isErr()
|
res.isErr()
|
||||||
res.error() == "proof is empty"
|
res.error() == "proof is empty"
|
||||||
@ -146,7 +146,7 @@ suite "State Validation - validateTrieProof":
|
|||||||
let
|
let
|
||||||
key = "doe".toBytes
|
key = "doe".toBytes
|
||||||
proof = @["aaa".toBytes, "ccc".toBytes].asTrieProof()
|
proof = @["aaa".toBytes, "ccc".toBytes].asTrieProof()
|
||||||
res = validateTrieProof(rootHash, key.asNibbles(), proof, true)
|
res = validateTrieProof(Opt.some(rootHash), key.asNibbles(), proof, true)
|
||||||
check:
|
check:
|
||||||
res.isErr()
|
res.isErr()
|
||||||
res.error() == "hash of proof root node doesn't match the expected root hash"
|
res.error() == "hash of proof root node doesn't match the expected root hash"
|
||||||
@ -185,23 +185,59 @@ suite "State Validation - validateTrieProof":
|
|||||||
let rootHash = trie.rootHash
|
let rootHash = trie.rootHash
|
||||||
|
|
||||||
check:
|
check:
|
||||||
validateTrieProof(rootHash, kv1.asNibbles(), trie.getTrieProof(kv1), true).isOk()
|
validateTrieProof(
|
||||||
validateTrieProof(rootHash, kv2.asNibbles(), trie.getTrieProof(kv2), false).isOk()
|
Opt.some(rootHash), kv1.asNibbles(), trie.getTrieProof(kv1), true
|
||||||
validateTrieProof(rootHash, kv3.asNibbles(), trie.getTrieProof(kv3), true).isOk()
|
)
|
||||||
validateTrieProof(rootHash, kv4.asNibbles(), trie.getTrieProof(kv4), false).isOk()
|
.isOk()
|
||||||
validateTrieProof(rootHash, kv5.asNibbles(), trie.getTrieProof(kv5)).isOk()
|
|
||||||
validateTrieProof(rootHash, kv6.asNibbles(), trie.getTrieProof(kv6)).isOk()
|
|
||||||
validateTrieProof(rootHash, kv7.asNibbles(), trie.getTrieProof(kv7)).isOk()
|
|
||||||
validateTrieProof(rootHash, kv8.asNibbles(), trie.getTrieProof(kv8)).isOk()
|
|
||||||
|
|
||||||
validateTrieProof(rootHash, kv9.asNibbles(), trie.getTrieProof(kv9)).isErr()
|
validateTrieProof(
|
||||||
validateTrieProof(rootHash, kv10.asNibbles(), trie.getTrieProof(kv10)).isErr()
|
Opt.some(rootHash), kv2.asNibbles(), trie.getTrieProof(kv2), false
|
||||||
validateTrieProof(rootHash, kv11.asNibbles(), trie.getTrieProof(kv11)).isErr()
|
)
|
||||||
validateTrieProof(rootHash, kv12.asNibbles(), trie.getTrieProof(kv12)).isErr()
|
.isOk()
|
||||||
validateTrieProof(rootHash, kv13.asNibbles(), trie.getTrieProof(kv13)).isErr()
|
|
||||||
|
|
||||||
validateTrieProof(rootHash, kv14.asNibbles(), trie.getTrieProof(kv14), false)
|
validateTrieProof(
|
||||||
|
Opt.some(rootHash), kv3.asNibbles(), trie.getTrieProof(kv3), true
|
||||||
|
)
|
||||||
|
.isOk()
|
||||||
|
|
||||||
|
validateTrieProof(
|
||||||
|
Opt.some(rootHash), kv4.asNibbles(), trie.getTrieProof(kv4), false
|
||||||
|
)
|
||||||
|
.isOk()
|
||||||
|
|
||||||
|
validateTrieProof(Opt.some(rootHash), kv5.asNibbles(), trie.getTrieProof(kv5))
|
||||||
|
.isOk()
|
||||||
|
|
||||||
|
validateTrieProof(Opt.some(rootHash), kv6.asNibbles(), trie.getTrieProof(kv6))
|
||||||
|
.isOk()
|
||||||
|
|
||||||
|
validateTrieProof(Opt.some(rootHash), kv7.asNibbles(), trie.getTrieProof(kv7))
|
||||||
|
.isOk()
|
||||||
|
|
||||||
|
validateTrieProof(Opt.some(rootHash), kv8.asNibbles(), trie.getTrieProof(kv8))
|
||||||
|
.isOk()
|
||||||
|
|
||||||
|
validateTrieProof(Opt.some(rootHash), kv9.asNibbles(), trie.getTrieProof(kv9))
|
||||||
.isErr()
|
.isErr()
|
||||||
|
|
||||||
validateTrieProof(rootHash, kv15.asNibbles(), trie.getTrieProof(kv15), false)
|
validateTrieProof(Opt.some(rootHash), kv10.asNibbles(), trie.getTrieProof(kv10))
|
||||||
|
.isErr()
|
||||||
|
|
||||||
|
validateTrieProof(Opt.some(rootHash), kv11.asNibbles(), trie.getTrieProof(kv11))
|
||||||
|
.isErr()
|
||||||
|
|
||||||
|
validateTrieProof(Opt.some(rootHash), kv12.asNibbles(), trie.getTrieProof(kv12))
|
||||||
|
.isErr()
|
||||||
|
|
||||||
|
validateTrieProof(Opt.some(rootHash), kv13.asNibbles(), trie.getTrieProof(kv13))
|
||||||
|
.isErr()
|
||||||
|
|
||||||
|
validateTrieProof(
|
||||||
|
Opt.some(rootHash), kv14.asNibbles(), trie.getTrieProof(kv14), false
|
||||||
|
)
|
||||||
|
.isErr()
|
||||||
|
|
||||||
|
validateTrieProof(
|
||||||
|
Opt.some(rootHash), kv15.asNibbles(), trie.getTrieProof(kv15), false
|
||||||
|
)
|
||||||
.isErr()
|
.isErr()
|
||||||
|
@ -144,7 +144,9 @@ suite "State Validation - Test Vectors":
|
|||||||
AccountTrieNodeOffer.decode(testData.content_value_offer.hexToSeqByte()).get()
|
AccountTrieNodeOffer.decode(testData.content_value_offer.hexToSeqByte()).get()
|
||||||
|
|
||||||
check:
|
check:
|
||||||
validateOffer(stateRoot, contentKey.accountTrieNodeKey, contentValueOffer)
|
validateOffer(
|
||||||
|
Opt.some(stateRoot), contentKey.accountTrieNodeKey, contentValueOffer
|
||||||
|
)
|
||||||
.isOk()
|
.isOk()
|
||||||
|
|
||||||
if i == 1:
|
if i == 1:
|
||||||
@ -158,7 +160,10 @@ suite "State Validation - Test Vectors":
|
|||||||
.get()
|
.get()
|
||||||
|
|
||||||
check:
|
check:
|
||||||
validateOffer(stateRoot, contentKey.accountTrieNodeKey, contentValueOffer).isOk()
|
validateOffer(
|
||||||
|
Opt.some(stateRoot), contentKey.accountTrieNodeKey, contentValueOffer
|
||||||
|
)
|
||||||
|
.isOk()
|
||||||
|
|
||||||
test "Validate invalid AccountTrieNodeOffer nodes - bad state roots":
|
test "Validate invalid AccountTrieNodeOffer nodes - bad state roots":
|
||||||
const file = testVectorDir / "account_trie_node.yaml"
|
const file = testVectorDir / "account_trie_node.yaml"
|
||||||
@ -179,8 +184,9 @@ suite "State Validation - Test Vectors":
|
|||||||
let contentValueOffer =
|
let contentValueOffer =
|
||||||
AccountTrieNodeOffer.decode(testData.content_value_offer.hexToSeqByte()).get()
|
AccountTrieNodeOffer.decode(testData.content_value_offer.hexToSeqByte()).get()
|
||||||
|
|
||||||
let res =
|
let res = validateOffer(
|
||||||
validateOffer(stateRoot, contentKey.accountTrieNodeKey, contentValueOffer)
|
Opt.some(stateRoot), contentKey.accountTrieNodeKey, contentValueOffer
|
||||||
|
)
|
||||||
check:
|
check:
|
||||||
res.isErr()
|
res.isErr()
|
||||||
res.error() == "hash of proof root node doesn't match the expected root hash"
|
res.error() == "hash of proof root node doesn't match the expected root hash"
|
||||||
@ -201,8 +207,9 @@ suite "State Validation - Test Vectors":
|
|||||||
|
|
||||||
contentValueOffer.proof[0][0] += 1.byte
|
contentValueOffer.proof[0][0] += 1.byte
|
||||||
|
|
||||||
let res =
|
let res = validateOffer(
|
||||||
validateOffer(stateRoot, contentKey.accountTrieNodeKey, contentValueOffer)
|
Opt.some(stateRoot), contentKey.accountTrieNodeKey, contentValueOffer
|
||||||
|
)
|
||||||
check:
|
check:
|
||||||
res.isErr()
|
res.isErr()
|
||||||
res.error() == "hash of proof root node doesn't match the expected root hash"
|
res.error() == "hash of proof root node doesn't match the expected root hash"
|
||||||
@ -219,8 +226,9 @@ suite "State Validation - Test Vectors":
|
|||||||
|
|
||||||
contentValueOffer.proof[^2][^2] += 1.byte
|
contentValueOffer.proof[^2][^2] += 1.byte
|
||||||
|
|
||||||
let res =
|
let res = validateOffer(
|
||||||
validateOffer(stateRoot, contentKey.accountTrieNodeKey, contentValueOffer)
|
Opt.some(stateRoot), contentKey.accountTrieNodeKey, contentValueOffer
|
||||||
|
)
|
||||||
check:
|
check:
|
||||||
res.isErr()
|
res.isErr()
|
||||||
"hash of next node doesn't match the expected" in res.error()
|
"hash of next node doesn't match the expected" in res.error()
|
||||||
@ -235,8 +243,9 @@ suite "State Validation - Test Vectors":
|
|||||||
|
|
||||||
contentValueOffer.proof[^1][^1] += 1.byte
|
contentValueOffer.proof[^1][^1] += 1.byte
|
||||||
|
|
||||||
let res =
|
let res = validateOffer(
|
||||||
validateOffer(stateRoot, contentKey.accountTrieNodeKey, contentValueOffer)
|
Opt.some(stateRoot), contentKey.accountTrieNodeKey, contentValueOffer
|
||||||
|
)
|
||||||
check:
|
check:
|
||||||
res.isErr()
|
res.isErr()
|
||||||
|
|
||||||
@ -259,7 +268,9 @@ suite "State Validation - Test Vectors":
|
|||||||
.get()
|
.get()
|
||||||
|
|
||||||
check:
|
check:
|
||||||
validateOffer(stateRoot, contentKey.contractTrieNodeKey, contentValueOffer)
|
validateOffer(
|
||||||
|
Opt.some(stateRoot), contentKey.contractTrieNodeKey, contentValueOffer
|
||||||
|
)
|
||||||
.isOk()
|
.isOk()
|
||||||
|
|
||||||
if i == 1:
|
if i == 1:
|
||||||
@ -273,7 +284,10 @@ suite "State Validation - Test Vectors":
|
|||||||
.get()
|
.get()
|
||||||
|
|
||||||
check:
|
check:
|
||||||
validateOffer(stateRoot, contentKey.contractTrieNodeKey, contentValueOffer).isOk()
|
validateOffer(
|
||||||
|
Opt.some(stateRoot), contentKey.contractTrieNodeKey, contentValueOffer
|
||||||
|
)
|
||||||
|
.isOk()
|
||||||
|
|
||||||
test "Validate invalid ContractTrieNodeOffer nodes - bad state roots":
|
test "Validate invalid ContractTrieNodeOffer nodes - bad state roots":
|
||||||
const file = testVectorDir / "contract_storage_trie_node.yaml"
|
const file = testVectorDir / "contract_storage_trie_node.yaml"
|
||||||
@ -293,8 +307,9 @@ suite "State Validation - Test Vectors":
|
|||||||
let contentValueOffer =
|
let contentValueOffer =
|
||||||
ContractTrieNodeOffer.decode(testData.content_value_offer.hexToSeqByte()).get()
|
ContractTrieNodeOffer.decode(testData.content_value_offer.hexToSeqByte()).get()
|
||||||
|
|
||||||
let res =
|
let res = validateOffer(
|
||||||
validateOffer(stateRoot, contentKey.contractTrieNodeKey, contentValueOffer)
|
Opt.some(stateRoot), contentKey.contractTrieNodeKey, contentValueOffer
|
||||||
|
)
|
||||||
check:
|
check:
|
||||||
res.isErr()
|
res.isErr()
|
||||||
res.error() == "hash of proof root node doesn't match the expected root hash"
|
res.error() == "hash of proof root node doesn't match the expected root hash"
|
||||||
@ -317,8 +332,9 @@ suite "State Validation - Test Vectors":
|
|||||||
|
|
||||||
contentValueOffer.accountProof[0][0] += 1.byte
|
contentValueOffer.accountProof[0][0] += 1.byte
|
||||||
|
|
||||||
let res =
|
let res = validateOffer(
|
||||||
validateOffer(stateRoot, contentKey.contractTrieNodeKey, contentValueOffer)
|
Opt.some(stateRoot), contentKey.contractTrieNodeKey, contentValueOffer
|
||||||
|
)
|
||||||
check:
|
check:
|
||||||
res.isErr()
|
res.isErr()
|
||||||
res.error() == "hash of proof root node doesn't match the expected root hash"
|
res.error() == "hash of proof root node doesn't match the expected root hash"
|
||||||
@ -332,8 +348,9 @@ suite "State Validation - Test Vectors":
|
|||||||
|
|
||||||
contentValueOffer.storageProof[0][0] += 1.byte
|
contentValueOffer.storageProof[0][0] += 1.byte
|
||||||
|
|
||||||
let res =
|
let res = validateOffer(
|
||||||
validateOffer(stateRoot, contentKey.contractTrieNodeKey, contentValueOffer)
|
Opt.some(stateRoot), contentKey.contractTrieNodeKey, contentValueOffer
|
||||||
|
)
|
||||||
check:
|
check:
|
||||||
res.isErr()
|
res.isErr()
|
||||||
res.error() == "hash of proof root node doesn't match the expected root hash"
|
res.error() == "hash of proof root node doesn't match the expected root hash"
|
||||||
@ -348,7 +365,9 @@ suite "State Validation - Test Vectors":
|
|||||||
contentValueOffer.accountProof[^1][^1] += 1.byte
|
contentValueOffer.accountProof[^1][^1] += 1.byte
|
||||||
|
|
||||||
check:
|
check:
|
||||||
validateOffer(stateRoot, contentKey.contractTrieNodeKey, contentValueOffer)
|
validateOffer(
|
||||||
|
Opt.some(stateRoot), contentKey.contractTrieNodeKey, contentValueOffer
|
||||||
|
)
|
||||||
.isErr()
|
.isErr()
|
||||||
|
|
||||||
block:
|
block:
|
||||||
@ -361,7 +380,9 @@ suite "State Validation - Test Vectors":
|
|||||||
contentValueOffer.storageProof[^1][^1] += 1.byte
|
contentValueOffer.storageProof[^1][^1] += 1.byte
|
||||||
|
|
||||||
check:
|
check:
|
||||||
validateOffer(stateRoot, contentKey.contractTrieNodeKey, contentValueOffer)
|
validateOffer(
|
||||||
|
Opt.some(stateRoot), contentKey.contractTrieNodeKey, contentValueOffer
|
||||||
|
)
|
||||||
.isErr()
|
.isErr()
|
||||||
|
|
||||||
block:
|
block:
|
||||||
@ -374,7 +395,9 @@ suite "State Validation - Test Vectors":
|
|||||||
contentValueOffer.accountProof[^2][^2] += 1.byte
|
contentValueOffer.accountProof[^2][^2] += 1.byte
|
||||||
|
|
||||||
check:
|
check:
|
||||||
validateOffer(stateRoot, contentKey.contractTrieNodeKey, contentValueOffer)
|
validateOffer(
|
||||||
|
Opt.some(stateRoot), contentKey.contractTrieNodeKey, contentValueOffer
|
||||||
|
)
|
||||||
.isErr()
|
.isErr()
|
||||||
|
|
||||||
# Contract bytecode offer validation tests
|
# Contract bytecode offer validation tests
|
||||||
@ -394,7 +417,10 @@ suite "State Validation - Test Vectors":
|
|||||||
ContractCodeOffer.decode(testData.content_value_offer.hexToSeqByte()).get()
|
ContractCodeOffer.decode(testData.content_value_offer.hexToSeqByte()).get()
|
||||||
|
|
||||||
check:
|
check:
|
||||||
validateOffer(stateRoot, contentKey.contractCodeKey, contentValueOffer).isOk()
|
validateOffer(
|
||||||
|
Opt.some(stateRoot), contentKey.contractCodeKey, contentValueOffer
|
||||||
|
)
|
||||||
|
.isOk()
|
||||||
|
|
||||||
test "Validate invalid ContractCodeOffer nodes - bad state root":
|
test "Validate invalid ContractCodeOffer nodes - bad state root":
|
||||||
const file = testVectorDir / "contract_bytecode.yaml"
|
const file = testVectorDir / "contract_bytecode.yaml"
|
||||||
@ -412,7 +438,9 @@ suite "State Validation - Test Vectors":
|
|||||||
let contentValueOffer =
|
let contentValueOffer =
|
||||||
ContractCodeOffer.decode(testData.content_value_offer.hexToSeqByte()).get()
|
ContractCodeOffer.decode(testData.content_value_offer.hexToSeqByte()).get()
|
||||||
|
|
||||||
let res = validateOffer(stateRoot, contentKey.contractCodeKey, contentValueOffer)
|
let res = validateOffer(
|
||||||
|
Opt.some(stateRoot), contentKey.contractCodeKey, contentValueOffer
|
||||||
|
)
|
||||||
check:
|
check:
|
||||||
res.isErr()
|
res.isErr()
|
||||||
res.error() == "hash of proof root node doesn't match the expected root hash"
|
res.error() == "hash of proof root node doesn't match the expected root hash"
|
||||||
@ -434,8 +462,9 @@ suite "State Validation - Test Vectors":
|
|||||||
|
|
||||||
contentValueOffer.accountProof[0][0] += 1.byte
|
contentValueOffer.accountProof[0][0] += 1.byte
|
||||||
|
|
||||||
let res =
|
let res = validateOffer(
|
||||||
validateOffer(stateRoot, contentKey.contractCodeKey, contentValueOffer)
|
Opt.some(stateRoot), contentKey.contractCodeKey, contentValueOffer
|
||||||
|
)
|
||||||
check:
|
check:
|
||||||
res.isErr()
|
res.isErr()
|
||||||
res.error() == "hash of proof root node doesn't match the expected root hash"
|
res.error() == "hash of proof root node doesn't match the expected root hash"
|
||||||
@ -448,8 +477,9 @@ suite "State Validation - Test Vectors":
|
|||||||
|
|
||||||
contentValueOffer.code[0] += 1.byte
|
contentValueOffer.code[0] += 1.byte
|
||||||
|
|
||||||
let res =
|
let res = validateOffer(
|
||||||
validateOffer(stateRoot, contentKey.contractCodeKey, contentValueOffer)
|
Opt.some(stateRoot), contentKey.contractCodeKey, contentValueOffer
|
||||||
|
)
|
||||||
check:
|
check:
|
||||||
res.isErr()
|
res.isErr()
|
||||||
res.error() ==
|
res.error() ==
|
||||||
@ -464,7 +494,10 @@ suite "State Validation - Test Vectors":
|
|||||||
contentValueOffer.accountProof[^1][^1] += 1.byte
|
contentValueOffer.accountProof[^1][^1] += 1.byte
|
||||||
|
|
||||||
check:
|
check:
|
||||||
validateOffer(stateRoot, contentKey.contractCodeKey, contentValueOffer).isErr()
|
validateOffer(
|
||||||
|
Opt.some(stateRoot), contentKey.contractCodeKey, contentValueOffer
|
||||||
|
)
|
||||||
|
.isErr()
|
||||||
|
|
||||||
block:
|
block:
|
||||||
let contentKey =
|
let contentKey =
|
||||||
@ -474,8 +507,9 @@ suite "State Validation - Test Vectors":
|
|||||||
|
|
||||||
contentValueOffer.code[^1] += 1.byte
|
contentValueOffer.code[^1] += 1.byte
|
||||||
|
|
||||||
let res =
|
let res = validateOffer(
|
||||||
validateOffer(stateRoot, contentKey.contractCodeKey, contentValueOffer)
|
Opt.some(stateRoot), contentKey.contractCodeKey, contentValueOffer
|
||||||
|
)
|
||||||
check:
|
check:
|
||||||
res.isErr()
|
res.isErr()
|
||||||
res.error() ==
|
res.error() ==
|
||||||
@ -506,7 +540,9 @@ suite "State Validation - Test Vectors":
|
|||||||
AccountTrieNodeOffer.decode(kv.content_value.hexToSeqByte()).get()
|
AccountTrieNodeOffer.decode(kv.content_value.hexToSeqByte()).get()
|
||||||
|
|
||||||
check:
|
check:
|
||||||
validateOffer(stateRoot, contentKey.accountTrieNodeKey, contentValueOffer)
|
validateOffer(
|
||||||
|
Opt.some(stateRoot), contentKey.accountTrieNodeKey, contentValueOffer
|
||||||
|
)
|
||||||
.isOk()
|
.isOk()
|
||||||
|
|
||||||
test "Validate valid ContractTrieNodeOffer recursive gossip nodes":
|
test "Validate valid ContractTrieNodeOffer recursive gossip nodes":
|
||||||
@ -527,5 +563,7 @@ suite "State Validation - Test Vectors":
|
|||||||
ContractTrieNodeOffer.decode(kv.content_value.hexToSeqByte()).get()
|
ContractTrieNodeOffer.decode(kv.content_value.hexToSeqByte()).get()
|
||||||
|
|
||||||
check:
|
check:
|
||||||
validateOffer(stateRoot, contentKey.contractTrieNodeKey, contentValueOffer)
|
validateOffer(
|
||||||
|
Opt.some(stateRoot), contentKey.contractTrieNodeKey, contentValueOffer
|
||||||
|
)
|
||||||
.isOk()
|
.isOk()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user