-
Notifications
You must be signed in to change notification settings - Fork 760
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Snap sync moving root/healing implementation #3332
base: master
Are you sure you want to change the base?
Changes from 43 commits
ff41a35
6c00e9c
74f0adc
8990b1f
dd21e73
9932c21
628135e
19adeea
1e1b1cc
92ecef8
8077f4d
6a2b266
4dd9bf8
e268f9a
b053277
72a28d1
f29c3c6
6ea23b0
fabf53c
ccf9366
4cd01aa
5777c42
9ea28d8
9a6ae27
5c42d73
9e60a09
d6c2a6c
58cb2b4
c53fa4b
20bf36f
fe9a4ec
0117083
694211e
d8028eb
52d1f6e
2f88a6b
560de58
9eb92a8
a1da2e6
d469538
6488935
87ee2aa
d678d20
50fb30b
b6c02c4
1cd9315
591762e
9c8495f
20db364
edd0866
dca3e3f
3e8a1e4
9a3b14c
9395829
a73b659
4058a27
98808b5
e26989f
b5ede5e
b2f471a
15f8906
a17fe93
c3946da
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -100,6 +100,7 @@ export class AccountFetcher extends Fetcher<JobTask, AccountData[], AccountData> | |
this.accountTrie = this.stateManager['_getAccountTrie']() | ||
|
||
this.debug = createDebugLogger('client:AccountFetcher') | ||
this.debug('dbg101') | ||
|
||
this.storageFetcher = new StorageFetcher({ | ||
config: this.config, | ||
|
@@ -276,6 +277,8 @@ export class AccountFetcher extends Fetcher<JobTask, AccountData[], AccountData> | |
} | ||
break | ||
case TrieNodeFetcher: | ||
// TODO update to check if heal phase completed successfully and then continue with next | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this function with this case would/should anyway be called when heal phase completed successfully |
||
// healing phase | ||
fetcherDoneFlags.trieNodeFetcher.done = true | ||
break | ||
} | ||
|
@@ -585,6 +588,11 @@ export class AccountFetcher extends Fetcher<JobTask, AccountData[], AccountData> | |
|
||
updateStateRoot(stateRoot: Uint8Array) { | ||
this.root = stateRoot | ||
|
||
this.storageFetcher.updateStateRoot(stateRoot) | ||
|
||
// TODO trieNodeFetcher needs to be constantly healing while other fetchers work | ||
this.trieNodeFetcher.updateStateRoot(stateRoot) | ||
} | ||
|
||
nextTasks(): void { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -61,6 +61,7 @@ type FetchedNodeData = { | |
} | ||
|
||
type NodeRequestData = { | ||
requested: boolean | ||
nodeHash: string | ||
nodeParentHash: string | ||
parentAccountHash?: string // for leaf account nodes that contain a storage component | ||
|
@@ -117,6 +118,7 @@ export class TrieNodeFetcher extends Fetcher<JobTask, Uint8Array[], Uint8Array> | |
|
||
// will always start with root node as first set of node requests | ||
this.pathToNodeRequestData.setElement('', { | ||
requested: false, | ||
nodeHash: bytesToHex(this.root), | ||
nodeParentHash: '', // root node does not have a parent | ||
} as NodeRequestData) | ||
|
@@ -263,6 +265,7 @@ export class TrieNodeFetcher extends Fetcher<JobTask, Uint8Array[], Uint8Array> | |
storagePath, | ||
].join('/') | ||
this.pathToNodeRequestData.setElement(syncPath, { | ||
requested: false, | ||
nodeHash: bytesToHex(storageRoot), | ||
nodeParentHash: nodeHash, | ||
parentAccountHash: nodeHash, | ||
|
@@ -299,6 +302,7 @@ export class TrieNodeFetcher extends Fetcher<JobTask, Uint8Array[], Uint8Array> | |
pathString | ||
) as NodeRequestData | ||
this.pathToNodeRequestData.setElement(childNode.path, { | ||
requested: false, | ||
nodeHash: bytesToHex(childNode.nodeHash as Uint8Array), | ||
nodeParentHash: nodeHash, // TODO root node does not have a parent, so handle that in the leaf callback when checking if dependencies are met recursively | ||
parentAccountHash, | ||
|
@@ -411,17 +415,25 @@ export class TrieNodeFetcher extends Fetcher<JobTask, Uint8Array[], Uint8Array> | |
if (this.pathToNodeRequestData.size() > 0) { | ||
let { pathStrings } = this.getSortedPathStrings() // TODO pass in number of paths to return | ||
while (tasks.length < maxTasks && pathStrings.length > 0) { | ||
const requestedPathStrings = pathStrings.slice(0, max) | ||
const pendingPathStrings = pathStrings.slice(0, max) | ||
pathStrings = pathStrings.slice(max + 1) | ||
for (const pathString of requestedPathStrings) { | ||
const nodeHash = this.pathToNodeRequestData.getElementByKey(pathString)?.nodeHash // TODO return node set too from sorted function and avoid lookups here | ||
if (nodeHash === undefined) throw Error('Path should exist') | ||
this.requestedNodeToPath.set(nodeHash as unknown as string, pathString) | ||
const neededPathStrings = [] | ||
for (const pathString of pendingPathStrings) { | ||
const requestData = this.pathToNodeRequestData.getElementByKey(pathString) // TODO return node set too from sorted function and avoid lookups here | ||
if (requestData === undefined) throw Error('Path should exist') | ||
if (requestData.requested === false) { | ||
this.requestedNodeToPath.set(requestData.nodeHash as unknown as string, pathString) | ||
this.pathToNodeRequestData.setElement(pathString, { | ||
...requestData, | ||
requested: true, | ||
}) | ||
neededPathStrings.push(pathString) | ||
} | ||
} | ||
this.debug('At start of mergeAndFormatPaths') | ||
const paths = mergeAndFormatKeyPaths(requestedPathStrings) as unknown as Uint8Array[][] | ||
const paths = mergeAndFormatKeyPaths(neededPathStrings) as unknown as Uint8Array[][] | ||
tasks.push({ | ||
pathStrings: requestedPathStrings, | ||
pathStrings: neededPathStrings, | ||
paths, | ||
}) | ||
this.debug(`Created new tasks num=${tasks.length}`) | ||
|
@@ -435,6 +447,10 @@ export class TrieNodeFetcher extends Fetcher<JobTask, Uint8Array[], Uint8Array> | |
return tasks | ||
} | ||
|
||
updateStateRoot(stateRoot: Uint8Array) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. need to see that the root is not continually updated. so the thing is: you start trie node fetcher with latest root, keep requesting data till peers give you, if they start replying with empty, then we restart the entire fetcher with the new root. so this is to be implemented as a while loop in the account fetcher's fetch where we start and run the trie node fetcher (either fetcher resolves or errors with error "out of range root", which will cause account fetcher to spin a new trie node fetcher with new root) |
||
this.root = stateRoot | ||
} | ||
|
||
nextTasks(): void { | ||
try { | ||
if (this.in.length === 0) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no we don't need stateroot from peer, we already have latest stateroot coming in from CL
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought #3354 was for tracking and accessing the latest root/height from the peer
latest
function. Are you suggesting passing down the latest root from FCU calls?