fix: CONTRACT_NOT_FOUND for system contracts (0x1, 0x2)#3788
Conversation
|
Claude finished @thiagodeev's task in 3m 51s —— View job Review: PR #3788 — unify system contracts and fix related rpc logic
Overall this is a clean, well-scoped refactor. It consolidates the duplicated system-contract ( BlockerNone. ImportantNone. Nits
Nothing here blocks merge. Note: I couldn't execute |
CONTRACT_NOT_FOUND for system contracts (0x1, 0x2)
| if err != nil { | ||
| // getClassAt only returns CONTRACT_NOT_FOUND / BLOCK_NOT_FOUND per spec; | ||
| // a class-hash miss here means the contract is not properly deployed. | ||
| if err == rpccore.ErrClassHashNotFound { |
There was a problem hiding this comment.
Nit (consistency): this uses pointer equality err == rpccore.ErrClassHashNotFound, whereas the rest of the RPC code compares by code (e.g. err.Code == rpccore.ErrTransactionExecutionError.Code in estimate_fee.go). It's correct here because Class returns the singleton directly, but comparing .Code would be more robust if the error is ever cloned/wrapped in the future. Same applies to rpc/v8/class.go:166 and rpc/v9/class.go:150.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3788 +/- ##
==========================================
- Coverage 75.34% 75.14% -0.20%
==========================================
Files 438 438
Lines 39528 39664 +136
==========================================
+ Hits 29781 29806 +25
- Misses 7676 7787 +111
Partials 2071 2071 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
| // System contracts are protocol-level contracts (0x1, 0x2) that hold storage | ||
| // but have no Cairo class; their class hash is always zero. They are not part | ||
| // of StateDiff.DeployedContracts and are auto-created during state commit so | ||
| // their storage trie can exist. | ||
| var ( | ||
| SystemContract1Address = felt.One // block-hash storage contract | ||
| // https://community.starknet.io/t/starknet-v0-13-4-pre-release-notes/115257#p-2358763-stateful-compression-11 | ||
| SystemContract2Address = felt.FromUint64[felt.Felt](2) // global counter | ||
| SystemContractsClassHash = felt.Zero | ||
|
|
||
| SystemContracts = [...]felt.Felt{SystemContract1Address, SystemContract2Address} | ||
| ) | ||
|
|
||
| // IsSystemContract reports whether addr is a protocol system contract (0x1, 0x2) | ||
| // that has no Cairo class. | ||
| func IsSystemContract(addr *felt.Felt) bool { | ||
| return addr.Equal(&SystemContract1Address) || addr.Equal(&SystemContract2Address) | ||
| } |
There was a problem hiding this comment.
System contract seem to be state specific logic, why not have them implemented in the states? Maybe it can be in just one of them, while the other just imports it?
I don't think this holds true, system contracts are empty classes, empty class doesn't necessarily mean non-existent. I would agree with Juno behaviour in this case |
|
I am not sure our behaviour is wrong? Are we violating the specs in any way? |
|
The |
Fixes #3777. System contracts
0x1/0x2hold storage but have no Cairo class, so Juno returned0x0instead ofCONTRACT_NOT_FOUND.Fixes
getClassHashAt,getNonce:0x0>CONTRACT_NOT_FOUNDfor0x1/0x2getClassAt:CLASS_HASH_NOT_FOUND>CONTRACT_NOT_FOUND(invalid error per spec)Changes
core/class.go: new sharedSystemContractsvars +IsSystemContracthelper (consolidates identity duplicated across state packages)core/state+core/deprecatedstate: use thecoresymbols instead of local copiesrpc/v8,v9,v10: filter system contracts inClassHashAt/Nonce(after block resolution, soBLOCK_NOT_FOUNDkeeps priority);ClassAtconvertsCLASS_HASH_NOT_FOUNDtoCONTRACT_NOT_FOUND