Skip to content

core: arweave state reader#991

Merged
attente merged 12 commits intomasterfrom
arweave
Apr 15, 2026
Merged

core: arweave state reader#991
attente merged 12 commits intomasterfrom
arweave

Conversation

@attente
Copy link
Copy Markdown
Contributor

@attente attente commented Apr 15, 2026

No description provided.

@attente attente requested review from a team as code owners April 15, 2026 13:34
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 32e440a944

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/wallet/core/src/state/arweave/arweave.ts Outdated
Comment on lines +718 to +719
if (best && candidate.checkpoint <= best.checkpoint) {
continue
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep earliest valid hop when allUpdates is requested

With allUpdates: true, candidates are sorted by ascending checkpoint, but this condition still allows every later valid candidate to replace best, so intermediate updates are skipped. If two valid updates exist from the same starting config (e.g., checkpoints 10 and 20), the method returns only 20 instead of the full path, which violates the intent of returning all updates. The allUpdates mode should stop on the first valid candidate (smallest checkpoint) before recursing.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fd5c86f047

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +530 to +533
const payloadPromise = payloads.get(subdigest) ?? this.getPayload(subdigest)
payloads.set(subdigest, payloadPromise)
const payload = await payloadPromise

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Verify subdigest matches payload wallet before accepting witness

This path trusts the signature record’s Subdigest and immediately uses the fetched payload without validating that it belongs to the same wallet (or that the subdigest is actually hash(wallet, chainId, payload)). A malformed or spoofed Arweave signature item can therefore make getWallets (and the similar getWitnessGeneric flow) return a witness for wallet A that actually points to wallet B’s payload, producing incorrect wallet associations and invalid update/signature chains downstream.

Useful? React with 👍 / 👎.

Comment thread packages/wallet/core/src/state/arweave/arweave.ts Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5c25b88ec6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +689 to +693
const candidate = candidates.get(nextImageHash) ?? {
nextImageHash,
checkpoint,
signatureEntries: new Map<string, ItemEntry>(),
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Group config-update signatures by subdigest

getConfigurationUpdates buckets candidate signatures only by To-Config, then aggregates one signature per signer across that bucket. This lets signatures from different subdigests (for example, the same target image hash signed under different chain IDs or payload contexts) be combined to satisfy threshold even though no single update payload has quorum. In that case the reader can return an update step that is not actually executable/valid for any real subdigest, corrupting the computed update path.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b7690d76c4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

for (const entry of await this.findEntries({ Type: 'config update', Wallet: normalizedWallet })) {
const { tags } = entry
const nextImageHash = normalizeHex(tags['To-Config'] as Hex.Hex)
const checkpoint = BigInt(tags['To-Checkpoint'] as string)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Derive update checkpoint from resolved target config

getConfigurationUpdates ranks and filters candidates using the unverified 'To-Checkpoint' tag from each signature record instead of the checkpoint from the actual target configuration. If that tag is stale or malformed, the method can pick the wrong hop (or recurse incorrectly) even when the underlying config data disagrees. This reader already has getConfiguration(nextImageHash) available, so candidate ordering/validation should use the resolved config checkpoint to avoid returning an invalid update path.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3d519dba91

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

let configuration: Config.Config | undefined

for (const record of await Promise.all(configEntries.map((entry) => this.loadRecord<ArweaveConfigRecord>(entry)))) {
configuration = mergeConfigurations(configuration, fromConfigCarrier(record))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Validate config content against requested image hash

getConfiguration merges records solely based on Arweave tags and never checks that the decoded configuration actually hashes to the imageHash being requested. If a malformed or mis-tagged record is the only match, this can return an unrelated configuration and corrupt signer/update resolution for that wallet. Recompute Config.hashConfiguration(...) for each loaded record and reject records whose content hash does not match the requested hash.

Useful? React with 👍 / 👎.

Comment on lines +796 to +800
return {
chainId: Number(record['Chain-ID']),
payload: fromPayloadRecord(record),
wallet: normalizeAddress(record.Address),
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Verify payload digest before returning from getPayload

getPayload trusts the Payload tag and returns the decoded body without recomputing the digest from (wallet, chainId, payload). When a record has an incorrect/stale tag, callers can receive a payload for a different subdigest, and downstream flows that consume this helper can associate signatures with the wrong operation. Compute the expected digest and skip or reject mismatched records.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c57769889a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +359 to +365
if ('Context-Factory' in record) {
return {
factory: normalizeAddress(record['Context-Factory']),
stage1: normalizeAddress(record['Context-Stage-1']),
stage2: normalizeAddress(record['Context-Stage-2']),
creationCode: normalizeHex(record['Context-Creation-Code']),
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Verify custom deploy context matches requested wallet

When custom context tags are present, inferContext returns them directly without checking that SequenceAddress.from(Deploy-Config, context) equals record.Wallet. A malformed wallet record can therefore make getDeploy(wallet) return an image hash/context pair that does not actually derive that wallet, which breaks counterfactual-address assumptions and can cause callers to act on the wrong deployment metadata.

Useful? React with 👍 / 👎.

Tree: normalizeHex(imageHash),
})

return record ? fromTreeData(record.data) : undefined
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Validate returned tree against requested root hash

getTree trusts the Tree tag and returns decoded content without recomputing its root hash. If a record is mis-tagged or corrupted, this returns a tree for a different root while callers believe it matches the requested imageHash, which can corrupt downstream tree/proof resolution.

Useful? React with 👍 / 👎.

Comment on lines +951 to +953
const topology = toRecoveredLikeTopology(minimalTopology)
const { weight } = Config.getWeight(topology, () => false)
if (weight < currentConfig.threshold) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Recover signatures before counting update quorum

This quorum check counts leaves as signed based on signature presence, but it never verifies that those signatures are valid for the config-update subdigest. Because toRecoveredLikeTopology marks provided leaves as signed and Config.getWeight then credits full weight, malformed or forged signature records can be accepted as a valid update path.

Useful? React with 👍 / 👎.

@attente attente merged commit 92f48c9 into master Apr 15, 2026
6 checks passed
@attente attente deleted the arweave branch April 15, 2026 16:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant