Skip to content

Commit

Permalink
sets chainProcessor sequence on wallet load (#3660)
Browse files Browse the repository at this point in the history
* sets chainProcessor sequence on wallet load

the chainProcessor tracks the head of the chain using both the hash and sequence
of a block. when the wallet loads we currently only set the has of the
chainProcessor equal to the latest headd hash from among the accounts in the
wallet.

one consequence of not setting the sequence at load time is that if a user
creates an account while the node is offline, the chainProcessor is not fully
initialized and the newly created account has its head set to null instead of
set equal to the latest head in the wallet. the new account then needs to scan
the whole chain  to sync, even though it was just created and won't have any
transactions earlier in the chain.

- defines getLatestHead to load the latest head (hash and sequence) from among
  all accounts
- sets both the hash and sequence of the chainProcessor from the latest head

* fixes error message for no latest head found
  • Loading branch information
hughy authored Mar 20, 2023
1 parent ee69829 commit 67c76f1
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 5 deletions.
39 changes: 39 additions & 0 deletions ironfish/src/wallet/__fixtures__/wallet.test.ts.fixture
Original file line number Diff line number Diff line change
Expand Up @@ -4805,5 +4805,44 @@
}
]
}
],
"Accounts load should set chainProcessor hash and sequence": [
{
"version": 1,
"id": "5a0f6c36-eb30-4954-8e93-2ee3fb6441c2",
"name": "a",
"spendingKey": "80ce5280992f330a119f76b98568996856b0ae036e22b5e61988a2fbfc033836",
"viewKey": "961c223f5d18d655b359e81f695d0300e0b82e254e404759bdd3794aa996d46098e4363f0f3cb787be322ff9f6c2b189de916cbe5e756e3e5f375233faff3de5",
"incomingViewKey": "ccac35aece670fddfc49e3fd6f2b0c9eb6e9b3b653c256a9b7cf2a1368e78a05",
"outgoingViewKey": "52d430794a580b4ccc4dd29be7ce6edc5c7c1ac6d33891fbfd12497b217159b2",
"publicAddress": "897d84fe317088b528515004ae5975e04a12e263874673512307ac6770a4b943",
"createdAt": "2023-03-17T00:41:00.361Z"
},
{
"header": {
"sequence": 2,
"previousBlockHash": "AD35193FA159CFD7440A3DFDFBE7ACB720CB4A44A441AB933071E2B9EF5DE90B",
"noteCommitment": {
"type": "Buffer",
"data": "base64:BXQPxm10K1CnTXx1YkhHI0HOjkSwW/8SNDAYXVRjNgk="
},
"transactionCommitment": {
"type": "Buffer",
"data": "base64:Uf8fGt3BY0bTn4E+jSmsOgADemFrCW/udvPJsfDd8/s="
},
"target": "883423532389192164791648750371459257913741948437809479060803100646309888",
"randomness": "0",
"timestamp": 1679013660859,
"graffiti": "0000000000000000000000000000000000000000000000000000000000000000",
"noteSize": 4,
"work": "0"
},
"transactions": [
{
"type": "Buffer",
"data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAbkFdvrnCz09UWwR+a1RsaG14TSUCX068ZaE0bu7jZh6Genn3SiwrQ3Ep3zVMs8sgwqwhvi4eFOYE0ufmwDNQU1JO4Khj7xwKSaohyC26CTamArjQR5SrIFAFg40rkYK98QVRBuiwiZdxkFfRubEb4fC2jhPzWgPKeSixAGZ0cxUMI3z6eXpY7Cv0vuTMFAoiMGmD6+Oo+netVZ6YYIoDI9GkRutC5ICVjkf7VU5gi7OQMywf7Xyy95qrft6q7gQAiWnRnIPqx3rEIHQEHrA/r6JsEevrT+0mYNT9/fhkyoyxncueCMoDo7SSbhejB5iedPr7vd7NIl/ZW/TiVA0fWGsvMbziOgcn5DNBIShmtX5XJfCmRWooy08e/BFay/VGyNL2XRHlHgreyrxYqh7XJcKSl/E8idPjffiSlIU1Cm+D3GiUiMLih2PeHah3fhjpceUj1a3MAN2CjG7nqnk75but0Lkvy6Mu9UHKru7I0MIyruYgV1P8fFgmt/fvwaW2fEHdocuNTYFhvITRsD556/bXA5igKYPY3CETNhQEgP4Jm3K2MjWdyq1xR4Bs0xQLLyjr8n65a+F7YPr9BAQc2EDBs51FDZfysrU22nmYuty4cgzLfipqeElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwtDUx9ia4xV/sAhtYVxCNjB0rOQGjKjOoHasuQcbvXbu6QgU5BmFduFwp2Db6S0rrDvmwU9JbbiwSwTLKRzNvDg=="
}
]
}
]
}
25 changes: 25 additions & 0 deletions ironfish/src/wallet/wallet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2300,4 +2300,29 @@ describe('Accounts', () => {
)
})
})

describe('load', () => {
it('should set chainProcessor hash and sequence', async () => {
const { node } = await nodeTest.createSetup()

const accountA = await useAccountFixture(node.wallet, 'a')

const blockA1 = await useMinerBlockFixture(node.chain, undefined, accountA, node.wallet)
await expect(node.chain).toAddBlock(blockA1)
await node.wallet.updateHead()

expect(node.wallet.chainProcessor.hash).toEqualHash(blockA1.header.hash)
expect(node.wallet.chainProcessor.sequence).toEqual(blockA1.header.sequence)

node.wallet['unload']()

expect(node.wallet.chainProcessor.hash).toBeNull()
expect(node.wallet.chainProcessor.sequence).toBeNull()

await node.wallet['load']()

expect(node.wallet.chainProcessor.hash).toEqualHash(blockA1.header.hash)
expect(node.wallet.chainProcessor.sequence).toEqual(blockA1.header.sequence)
})
})
})
23 changes: 18 additions & 5 deletions ironfish/src/wallet/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import { validateAccount } from './validator'
import { AccountValue } from './walletdb/accountValue'
import { AssetValue } from './walletdb/assetValue'
import { DecryptedNoteValue } from './walletdb/decryptedNoteValue'
import { HeadValue } from './walletdb/headValue'
import { TransactionValue } from './walletdb/transactionValue'
import { WalletDB } from './walletdb/walletdb'

Expand Down Expand Up @@ -203,14 +204,19 @@ export class Wallet {
const meta = await this.walletDb.loadAccountsMeta()
this.defaultAccount = meta.defaultAccountId

this.chainProcessor.hash = await this.getLatestHeadHash()
const latestHead = await this.getLatestHead()
if (latestHead) {
this.chainProcessor.hash = latestHead.hash
this.chainProcessor.sequence = latestHead.sequence
}
}

private unload(): void {
this.accounts.clear()

this.defaultAccount = null
this.chainProcessor.hash = null
this.chainProcessor.sequence = null
}

async close(): Promise<void> {
Expand Down Expand Up @@ -592,10 +598,11 @@ export class Wallet {
}

if (this.chainProcessor.hash === null) {
const latestHeadHash = await this.getLatestHeadHash()
Assert.isNotNull(latestHeadHash, `scanTransactions: No latest head hash found`)
const latestHead = await this.getLatestHead()
Assert.isNotNull(latestHead, `scanTransactions: No latest head found`)

this.chainProcessor.hash = latestHeadHash
this.chainProcessor.hash = latestHead.hash
this.chainProcessor.sequence = latestHead.sequence
}

this.logger.info(
Expand Down Expand Up @@ -1476,7 +1483,7 @@ export class Wallet {
return earliestHead ? earliestHead.hash : null
}

async getLatestHeadHash(): Promise<Buffer | null> {
async getLatestHead(): Promise<HeadValue | null> {
let latestHead = null

for (const account of this.accounts.values()) {
Expand All @@ -1491,6 +1498,12 @@ export class Wallet {
}
}

return latestHead
}

async getLatestHeadHash(): Promise<Buffer | null> {
const latestHead = await this.getLatestHead()

return latestHead ? latestHead.hash : null
}

Expand Down

0 comments on commit 67c76f1

Please sign in to comment.