Skip to content

Fix support for speculative execution response parsing - #172

Merged
davidatwhiletrue merged 3 commits into
masterfrom
spec-exec-casper2
Oct 1, 2026
Merged

davidatwhiletrue merged 3 commits into
masterfrom
spec-exec-casper2

Conversation

@davidatwhiletrue

Copy link
Copy Markdown
Member

Summary

The SpeculativeExecutionResult class failed to parse responses from Casper 2.0.0 nodes.
The Message class incorrectly contained a HashAddr property that must be EntityAddr property (changed in release-2.0.0-rc8`.

TODO

Checklist

  • Code is properly formatted
  • All commits are signed
  • Tests included/updated or not needed
  • Documentation (manuals or wiki) has been updated or is not required

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Update types.Message to map entity_addr to key.EntityAddr and add coverage for the producer address.

Review effort: Lite
Findings: 1 Medium severity

Open (1)
What changed in this PR

Adds Casper 1.x/2.x speculative execution response parsing with regression fixtures and tests.

Changes:

  • Adds Casper 2.x execution-result modeling and conversion.
  • Implements version-aware response unmarshalling.
  • Adds success and failure fixtures for both protocol versions.
  • Remaining issue: message producer addresses still use hash_addr instead of entity_addr.
File Summary
types/​execution_result.go Defines Casper 2.x execution results and conversion logic.
tests/​rpc/​speculative_exec_test.go Tests speculative execution parsing.
tests/​data/​rpc_response/​specexec_transfer_success_v158.json Casper 1.x success fixture.
tests/​data/​rpc_response/​specexec_transfer_failure_v200.json Casper 2.x failure fixture.
tests/​data/​rpc_response/​specexec_transfer_failure_v158.json Casper 1.x failure fixture.
tests/​data/​rpc_response/​specexec_cep18transfer_success_v200.json Casper 2.x success fixture.
rpc/​response.go Parses Casper 1.x and 2.x response shapes.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread rpc/response.go
ApiVersion string `json:"api_version"`
BlockHash key.Hash `json:"block_hash"`
ExecutionResult types.ExecutionResult `json:"execution_result"`
Messages []types.Message `json:"messages"`

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@copilot check again this.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Addressed in 4dbd5ed: types.Message now unmarshals entity_addr into key.EntityAddr, and the speculative execution test asserts the parsed producer address.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Btw, messages is nested inside execution_result, but the public Messages field is declared at the top level. So UnmarshalJSON handles reading correctly, but json.Marshal(SpeculativeExecResult) will produce a different structure: messages will be moved to the top level, is it expected? Should we overwrite MarshalJSON?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

You're right. I guess the same happens with BlockHash. Since SpeculativeExecResult is not a native type, I wouldn't overwrite MarshalJSON.

Comment thread types/message_topic.go
TopicNameHash key.Hash `json:"topic_name_hash"`
// The identity of the entity that produced the message.
HashAddr key.Hash `json:"hash_addr"`
EntityAddr key.EntityAddr `json:"entity_addr"`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Isn't it a breaking change?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@ZhmakAS ZhmakAS left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Overall, lgtm, only left couple of questions

Comment thread rpc/response.go
ApiVersion string `json:"api_version"`
BlockHash key.Hash `json:"block_hash"`
ExecutionResult types.ExecutionResult `json:"execution_result"`
Messages []types.Message `json:"messages"`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Btw, messages is nested inside execution_result, but the public Messages field is declared at the top level. So UnmarshalJSON handles reading correctly, but json.Marshal(SpeculativeExecResult) will produce a different structure: messages will be moved to the top level, is it expected? Should we overwrite MarshalJSON?

… nodes.

Signed-off-by: David Hernando <david.hernando@make.services>
…ease-2.0.0-rc8)

Signed-off-by: David Hernando <david.hernando@make.services>
@davidatwhiletrue
davidatwhiletrue merged commit 7dcca20 into master Oct 1, 2026
4 checks passed
Comp0te added a commit to casper-ecosystem/casper-js-sdk that referenced this pull request Oct 1, 2026
* Fix speculative exec and message parsing for Casper 2.0 nodes

Message read the pre-rc8 hash_addr field, which 2.0 nodes replaced with
entity_addr, so every message in a speculative result or a
TransactionProcessed event failed to parse. SpeculativeExecResult took
apiVersion from the JSON-RPC envelope and missed the 1.5 block hash,
which sits beside execution_result rather than inside it.

Ports make-software/casper-go-sdk#172, with its node responses as
fixtures. Moves the 5.2.0 release date to 2026-10-05.

* Move the Message.entityAddr changelog entry under Fixed

The rename exists only to make messages from a 2.x node parse, so it
reads as a fix. The release intro now points to Fixed for it.
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.

4 participants