Skip to content
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

Fix for "Missing processor address" error #398

Merged
merged 2 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## Unreleased

- fixed: Missing `scriptPubkeyByPath` processor data from wallet data dump returned by `dumpData`
- fixed: Prevent wallet processor data corruption ("Missing processor address" error)

## 2.6.0 (2024-04-09)

- added: New fallback server engine info, starting with NOWNodes blockbook servers
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"@bitcoin-js/tiny-secp256k1-asmjs": "^2.2.3",
"altcoin-js": "^1.0.0",
"async-mutex": "^0.2.6",
"baselet": "^0.2.4",
"baselet": "^0.3.0",
"biggystring": "^4.1.3",
"bip32": "^2.0.5",
"bip32grs": "^2.0.5",
Expand Down Expand Up @@ -107,4 +107,4 @@
"typescript": "^4.1.2",
"wif": "^2.0.6"
}
}
}
86 changes: 60 additions & 26 deletions src/common/utxobased/db/Processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,12 +157,17 @@ export async function makeProcessor(
},

async dumpData(): Promise<DumpDataReturn[]> {
const allBases = Object.values(baselets.all)
type AllBases = typeof baselets.all
const allBases: Array<AllBases[keyof AllBases]> = Object.values(
baselets.all
)
return await Promise.all(
allBases.map(async base => ({
databaseName: base.databaseName,
data: (await base.dumpData('')) as unknown
}))
allBases.map(async base => {
return {
databaseName: base.databaseName,
data: (await base.dumpData()) as unknown
}
})
)
},

Expand Down Expand Up @@ -399,6 +404,15 @@ export async function makeProcessor(

async saveAddress(address: IAddress): Promise<void> {
await baselets.address(async tables => {
// This variable is used to update the scriptPubkeyByPath table.
// The path table must be written after the address table because the
// path table is an index of the address table.
// This variable acts as a catch for that update to be done after the
// address table is written.
let indexTableUpdate:
| { path: AddressPath; scriptPubkey: string }
| undefined

const [existingAddress] = await tables.addressByScriptPubkey.query('', [
address.scriptPubkey
])
Expand All @@ -415,14 +429,14 @@ export async function makeProcessor(
'Attempted to save address with an existing path, but different script pubkey'
)

await tables.scriptPubkeyByPath.insert(
addressPathToPrefix(address.path),
address.path.addressIndex,
address.scriptPubkey
)
indexTableUpdate = {
path: address.path,
scriptPubkey: address.scriptPubkey
}

// check if this address is used and if so, whether it has a higher last used index
if (address.used || (existingAddress?.used ?? false)) {
// check if this address is used and if so, whether it has a higher
// last used index
if (address.used || existingAddress?.used === true) {
let [lastUsed] = await tables.lastUsedByFormatPath.query('', [
addressPathToPrefix(address.path)
])
Expand All @@ -438,6 +452,7 @@ export async function makeProcessor(
}
}

// Update routine:
if (existingAddress != null) {
// Only update the lastQueriedBlockHeight on the address if one was given and is greater than the existing value
if (
Expand All @@ -463,16 +478,21 @@ export async function makeProcessor(
existingAddress.balance = address.balance
}

// Only update the path field if one was given and currently does not have one
// NOTE: Addresses can be stored in the db without a path due to the `EdgeCurrencyEngine.addGapLimitAddresses` function
// Once an address path is known, it should never be updated
/*
Only update the path field if one was given and the existing address
currently does not have one. We never update paths for addresses, only
insert paths when they're not present.

NOTE: Addresses can be stored in the db without a path due to the
`EdgeCurrencyEngine.addGapLimitAddresses` function. Once an address
path is known, it should never be updated
*/
if (address.path != null && existingAddress.path == null) {
existingAddress.path = address.path
await tables.scriptPubkeyByPath.insert(
addressPathToPrefix(address.path),
address.path.addressIndex,
address.scriptPubkey
)
indexTableUpdate = {
path: existingAddress.path,
scriptPubkey: existingAddress.scriptPubkey
}
}

// Only update the used flag if one was given and is true
Expand All @@ -495,18 +515,32 @@ export async function makeProcessor(
)
}
}

// Update the address table:
await tables.addressByScriptPubkey.insert(
'',
existingAddress.scriptPubkey,
existingAddress
)
return
}
await tables.addressByScriptPubkey.insert(
'',
address.scriptPubkey,
address
)

// Insert routine:
if (existingAddress == null) {
await tables.addressByScriptPubkey.insert(
'',
address.scriptPubkey,
address
)
}

// Insert the path into the index table:
if (indexTableUpdate != null) {
await tables.scriptPubkeyByPath.insert(
addressPathToPrefix(indexTableUpdate.path),
indexTableUpdate.path.addressIndex,
indexTableUpdate.scriptPubkey
)
}
})
},

Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1637,10 +1637,10 @@ base@^0.11.1:
mixin-deep "^1.2.0"
pascalcase "^0.1.1"

baselet@^0.2.4:
version "0.2.4"
resolved "https://registry.yarnpkg.com/baselet/-/baselet-0.2.4.tgz#11450ead06353d9c9971a983790655b93211c097"
integrity sha512-42EmWggEbg1XlOjUIuDkepKo5WQUF8b5r7R6avxCw+T8fW2YEl3YNRLKTDguJC+CXJuu478HkdZ/jiLzinxf7Q==
baselet@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/baselet/-/baselet-0.3.0.tgz#2cebf5ae5833711ce40dcbc0cf06a8732592a94e"
integrity sha512-GNwU6O9vkg1TOLzYepsPE7mP7+hXOJhxUHWE4MARXEiiTLG/RxCL7xpbbGAdnh9JvAlJsa5OSkATMloCWQOpMw==
dependencies:
disklet "^0.4.5"
memlet "^0.1.6"
Expand Down
Loading