Cleanup state network recursive gossip which was removed from the portal specs. (#2345)

This commit is contained in:
web3-developer 2024-06-13 13:53:49 +08:00 committed by GitHub
parent 060c759b01
commit f326ae2ee1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 71 additions and 54 deletions

View File

@ -65,23 +65,22 @@ func getParent(p: ProofWithPath): ProofWithPath =
func getParent*(offerWithKey: AccountTrieOfferWithKey): AccountTrieOfferWithKey = func getParent*(offerWithKey: AccountTrieOfferWithKey): AccountTrieOfferWithKey =
let let
(key, offer) = offerWithKey (key, offer) = offerWithKey
(parentPath, parentProof) = offer.proof.withPath(key.path).getParent() parent = offer.proof.withPath(key.path).getParent()
parentKey =
parentKey = AccountTrieNodeKey.init(parentPath, keccakHash(parentProof[^1].asSeq())) AccountTrieNodeKey.init(parent.path, keccakHash(parent.proof[^1].asSeq()))
parentOffer = AccountTrieNodeOffer.init(parentProof, offer.blockHash) parentOffer = AccountTrieNodeOffer.init(parent.proof, offer.blockHash)
parentOffer.withKey(parentKey) parentOffer.withKey(parentKey)
func getParent*(offerWithKey: ContractTrieOfferWithKey): ContractTrieOfferWithKey = func getParent*(offerWithKey: ContractTrieOfferWithKey): ContractTrieOfferWithKey =
let let
(key, offer) = offerWithKey (key, offer) = offerWithKey
(parentPath, parentProof) = offer.storageProof.withPath(key.path).getParent() parent = offer.storageProof.withPath(key.path).getParent()
parentKey = ContractTrieNodeKey.init( parentKey = ContractTrieNodeKey.init(
key.address, parentPath, keccakHash(parentProof[^1].asSeq()) key.address, parent.path, keccakHash(parent.proof[^1].asSeq())
) )
parentOffer = parentOffer =
ContractTrieNodeOffer.init(parentProof, offer.accountProof, offer.blockHash) ContractTrieNodeOffer.init(parent.proof, offer.accountProof, offer.blockHash)
parentOffer.withKey(parentKey) parentOffer.withKey(parentKey)
@ -98,21 +97,6 @@ proc gossipOffer*(
) )
info "Offered content gossipped successfully with peers", keyBytes, peers = req1Peers info "Offered content gossipped successfully with peers", keyBytes, peers = req1Peers
# root node, recursive gossip is finished
if key.path.unpackNibbles().len() == 0:
return
# continue the recursive gossip by sharing the parent offer with peers
let
(parentKey, parentOffer) = offer.withKey(key).getParent()
parentKeyBytes = parentKey.toContentKey().encode()
req2Peers = await p.neighborhoodGossip(
srcNodeId, ContentKeysList.init(@[parentKeyBytes]), @[parentOffer.encode()]
)
info "Offered content parent gossipped successfully with peers",
parentKeyBytes, peers = req2Peers
proc gossipOffer*( proc gossipOffer*(
p: PortalProtocol, p: PortalProtocol,
srcNodeId: Opt[NodeId], srcNodeId: Opt[NodeId],
@ -126,21 +110,6 @@ proc gossipOffer*(
) )
info "Offered content gossipped successfully with peers", keyBytes, peers = req1Peers info "Offered content gossipped successfully with peers", keyBytes, peers = req1Peers
# root node, recursive gossip is finished
if key.path.unpackNibbles().len() == 0:
return
# continue the recursive gossip by sharing the parent offer with peers
let
(parentKey, parentOffer) = offer.withKey(key).getParent()
parentKeyBytes = parentKey.toContentKey().encode()
req2Peers = await p.neighborhoodGossip(
srcNodeId, ContentKeysList.init(@[parentKeyBytes]), @[parentOffer.encode()]
)
info "Offered content parent gossipped successfully with peers",
parentKeyBytes, peers = req2Peers
proc gossipOffer*( proc gossipOffer*(
p: PortalProtocol, p: PortalProtocol,
srcNodeId: Opt[NodeId], srcNodeId: Opt[NodeId],
@ -153,3 +122,53 @@ proc gossipOffer*(
srcNodeId, ContentKeysList.init(@[keyBytes]), @[offerBytes] srcNodeId, ContentKeysList.init(@[keyBytes]), @[offerBytes]
) )
info "Offered content gossipped successfully with peers", keyBytes, peers info "Offered content gossipped successfully with peers", keyBytes, peers
# Currently only used for testing to gossip an entire account trie proof
# This may also be useful for the state network bridge
proc recursiveGossipOffer*(
p: PortalProtocol,
srcNodeId: Opt[NodeId],
keyBytes: ByteList,
offerBytes: seq[byte],
key: AccountTrieNodeKey,
offer: AccountTrieNodeOffer,
) {.async.} =
asyncSpawn gossipOffer(p, srcNodeId, keyBytes, offerBytes, key, offer)
# root node, recursive gossip is finished
if key.path.unpackNibbles().len() == 0:
return
# continue the recursive gossip by sharing the parent offer with peers
let
(parentKey, parentOffer) = offer.withKey(key).getParent()
parentKeyBytes = parentKey.toContentKey().encode()
asyncSpawn recursiveGossipOffer(
p, srcNodeId, parentKeyBytes, parentOffer.encode(), parentKey, parentOffer
)
# Currently only used for testing to gossip an entire contract trie proof
# This may also be useful for the state network bridge
proc recursiveGossipOffer*(
p: PortalProtocol,
srcNodeId: Opt[NodeId],
keyBytes: ByteList,
offerBytes: seq[byte],
key: ContractTrieNodeKey,
offer: ContractTrieNodeOffer,
) {.async.} =
asyncSpawn gossipOffer(p, srcNodeId, keyBytes, offerBytes, key, offer)
# root node, recursive gossip is finished
if key.path.unpackNibbles().len() == 0:
return
# continue the recursive gossip by sharing the parent offer with peers
let
(parentKey, parentOffer) = offer.withKey(key).getParent()
parentKeyBytes = parentKey.toContentKey().encode()
asyncSpawn recursiveGossipOffer(
p, srcNodeId, parentKeyBytes, parentOffer.encode(), parentKey, parentOffer
)

View File

@ -62,7 +62,7 @@ procSuite "State Endpoints":
stateNode2.mockBlockHashToStateRoot(contentValue.blockHash, stateRoot) stateNode2.mockBlockHashToStateRoot(contentValue.blockHash, stateRoot)
# offer the leaf node # offer the leaf node
await stateNode1.portalProtocol.gossipOffer( await stateNode1.portalProtocol.recursiveGossipOffer(
Opt.none(NodeId), Opt.none(NodeId),
contentKeyBytes, contentKeyBytes,
contentValueBytes, contentValueBytes,
@ -167,7 +167,7 @@ procSuite "State Endpoints":
stateNode2.mockBlockHashToStateRoot(contentValue.blockHash, stateRoot) stateNode2.mockBlockHashToStateRoot(contentValue.blockHash, stateRoot)
# offer the leaf node # offer the leaf node
await stateNode1.portalProtocol.gossipOffer( await stateNode1.portalProtocol.recursiveGossipOffer(
Opt.none(NodeId), Opt.none(NodeId),
contentKeyBytes, contentKeyBytes,
contentValueBytes, contentValueBytes,
@ -192,7 +192,7 @@ procSuite "State Endpoints":
stateNode2.mockBlockHashToStateRoot(contentValue.blockHash, stateRoot) stateNode2.mockBlockHashToStateRoot(contentValue.blockHash, stateRoot)
# offer the leaf node # offer the leaf node
await stateNode1.portalProtocol.gossipOffer( await stateNode1.portalProtocol.recursiveGossipOffer(
Opt.none(NodeId), Opt.none(NodeId),
contentKeyBytes, contentKeyBytes,
contentValueBytes, contentValueBytes,

View File

@ -80,7 +80,7 @@ procSuite "State Gossip - Gossip Offer":
await sleepAsync(1.milliseconds) await sleepAsync(1.milliseconds)
await sleepAsync(100.milliseconds) await sleepAsync(100.milliseconds)
# check that both the offer and parent were received by the second state instance # check that the offer was received by the second state instance
let res1 = let res1 =
await stateNode2.stateNetwork.getAccountTrieNode(contentKey.accountTrieNodeKey) await stateNode2.stateNetwork.getAccountTrieNode(contentKey.accountTrieNodeKey)
check: check:
@ -89,14 +89,13 @@ procSuite "State Gossip - Gossip Offer":
res1.get() == contentValue.toRetrievalValue() res1.get() == contentValue.toRetrievalValue()
res1.get().node == contentValue.toRetrievalValue().node res1.get().node == contentValue.toRetrievalValue().node
# check that the parent offer was not received by the second state instance
let res2 = await stateNode2.stateNetwork.getAccountTrieNode( let res2 = await stateNode2.stateNetwork.getAccountTrieNode(
parentContentKey.accountTrieNodeKey parentContentKey.accountTrieNodeKey
) )
check: check:
stateNode2.containsId(parentContentId) not stateNode2.containsId(parentContentId)
res2.isOk() res2.isNone()
res2.get() == parentContentValue.toRetrievalValue()
res2.get().node == parentContentValue.toRetrievalValue().node
await stateNode1.stop() await stateNode1.stop()
await stateNode2.stop() await stateNode2.stop()
@ -156,7 +155,7 @@ procSuite "State Gossip - Gossip Offer":
await sleepAsync(1.milliseconds) await sleepAsync(1.milliseconds)
await sleepAsync(100.milliseconds) await sleepAsync(100.milliseconds)
# check that both the offer and parent were received by the second state instance # check that the offer was received by the second state instance
let res1 = await stateNode2.stateNetwork.getContractTrieNode( let res1 = await stateNode2.stateNetwork.getContractTrieNode(
contentKey.contractTrieNodeKey contentKey.contractTrieNodeKey
) )
@ -166,14 +165,13 @@ procSuite "State Gossip - Gossip Offer":
res1.get() == contentValue.toRetrievalValue() res1.get() == contentValue.toRetrievalValue()
res1.get().node == contentValue.toRetrievalValue().node res1.get().node == contentValue.toRetrievalValue().node
# check that the offer parent was not received by the second state instance
let res2 = await stateNode2.stateNetwork.getContractTrieNode( let res2 = await stateNode2.stateNetwork.getContractTrieNode(
parentContentKey.contractTrieNodeKey parentContentKey.contractTrieNodeKey
) )
check: check:
stateNode2.containsId(parentContentId) not stateNode2.containsId(parentContentId)
res2.isOk() res2.isNone()
res2.get() == parentContentValue.toRetrievalValue()
res2.get().node == parentContentValue.toRetrievalValue().node
await stateNode1.stop() await stateNode1.stop()
await stateNode2.stop() await stateNode2.stop()
@ -222,7 +220,7 @@ procSuite "State Gossip - Gossip Offer":
await sleepAsync(1.milliseconds) await sleepAsync(1.milliseconds)
await sleepAsync(100.milliseconds) await sleepAsync(100.milliseconds)
# check that both the offer and parent were received by the second state instance # check that the offer was received by the second state instance
let res1 = let res1 =
await stateNode2.stateNetwork.getContractCode(contentKey.contractCodeKey) await stateNode2.stateNetwork.getContractCode(contentKey.contractCodeKey)
check: check:
@ -273,7 +271,7 @@ procSuite "State Gossip - Gossip Offer":
check not stateNode2.containsId(contentId) check not stateNode2.containsId(contentId)
# offer the leaf node # offer the leaf node
await stateNode1.portalProtocol.gossipOffer( await stateNode1.portalProtocol.recursiveGossipOffer(
Opt.none(NodeId), Opt.none(NodeId),
contentKeyBytes, contentKeyBytes,
contentValueBytes, contentValueBytes,
@ -350,7 +348,7 @@ procSuite "State Gossip - Gossip Offer":
check not stateNode2.containsId(contentId) check not stateNode2.containsId(contentId)
# offer the leaf node # offer the leaf node
await stateNode1.portalProtocol.gossipOffer( await stateNode1.portalProtocol.recursiveGossipOffer(
Opt.none(NodeId), Opt.none(NodeId),
contentKeyBytes, contentKeyBytes,
contentValueBytes, contentValueBytes,