-
Notifications
You must be signed in to change notification settings - Fork 21
fix(alonzo): custom CBOR marshal for block #1090
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
Conversation
bef990f to
cd10d01
Compare
cd10d01 to
2e8d14d
Compare
2e8d14d to
9dcdd11
Compare
📝 WalkthroughWalkthroughAdds a CBOR round-trip test Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
Pre-merge checks and finishing touches✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
ledger/alonzo/block_test.go (1)
15-27: Minor formatting: Remove trailing whitespace.Line 25 appears to have trailing whitespace or an unnecessary blank line.
Apply this diff to clean up the formatting:
"github.com/blinklabs-io/gouroboros/cbor" "github.com/blinklabs-io/gouroboros/ledger/alonzo" - + "github.com/stretchr/testify/assert" )
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
ledger/alonzo/block_test.go(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
ledger/alonzo/block_test.go (2)
ledger/alonzo/alonzo.go (2)
AlonzoBlock(52-60)AlonzoBlock(73-75)cbor/encode.go (1)
Encode(27-40)
🪛 GitHub Actions: go-test
ledger/alonzo/block_test.go
[error] 68-68: TestAlonzoBlock_CborRoundTrip_UsingCborEncode failed. Custom CBOR round-trip mismatch for Alonzo block. Original CBOR (hex) and encoded CBOR differ.
[error] 83-84: First mismatch at byte index: 7493. Original byte: 0x9f, Re-encoded byte: 0x81.
🔇 Additional comments (3)
ledger/alonzo/block_test.go (3)
1-13: LGTM!License header is properly formatted and consistent with Apache License 2.0 requirements.
36-52: LGTM!The hex decode and unmarshal logic is well-structured with appropriate error handling and descriptive error messages.
95-156: LGTM!The existing Utxorpc test is well-structured and comprehensive, validating block parsing and conversion with appropriate assertions.
| // Re-encode using the cbor Encode function | ||
| encoded, err := cbor.Encode(block) | ||
| if err != nil { | ||
| t.Fatalf( | ||
| "Failed to marshal AlonzoBlock using custom encode function: %v", | ||
| err, | ||
| ) | ||
| } | ||
| if encoded == nil || len(encoded) == 0 { | ||
| t.Fatal("Custom encoded CBOR from AlonzoBlock is nil or empty") | ||
| } | ||
|
|
||
| // Ensure the original and re-encoded CBOR bytes are identical | ||
| if !bytes.Equal(dataBytes, encoded) { | ||
| t.Errorf( | ||
| "Custom CBOR round-trip mismatch for Alonzo block\nOriginal CBOR (hex): %x\nCustom Encoded CBOR (hex): %x", | ||
| dataBytes, | ||
| encoded, | ||
| ) | ||
|
|
||
| // Check from which byte it differs | ||
| diffIndex := -1 | ||
| for i := 0; i < len(dataBytes) && i < len(encoded); i++ { | ||
| if dataBytes[i] != encoded[i] { | ||
| diffIndex = i | ||
| break | ||
| } | ||
| } | ||
| if diffIndex != -1 { | ||
| t.Logf("First mismatch at byte index: %d", diffIndex) | ||
| t.Logf( | ||
| "Original byte: 0x%02x, Re-encoded byte: 0x%02x", | ||
| dataBytes[diffIndex], | ||
| encoded[diffIndex], | ||
| ) | ||
| } else { | ||
| t.Logf("Length mismatch: original length = %d, re-encoded length = %d", len(dataBytes), len(encoded)) | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Critical: Test logic error causing pipeline failure.
The test is failing because cbor.Encode produces definite-length CBOR encoding (byte 0x81), while the original block uses indefinite-length encoding (byte 0x9f) in some places. Both are valid CBOR representations of the same data, but they differ byte-for-byte.
Since AlonzoBlock embeds cbor.DecodeStoreCbor, the original CBOR bytes should be stored and retrievable via a Cbor() method. For a true round-trip test, use the stored bytes instead of re-encoding.
Verify that DecodeStoreCbor provides a Cbor() method:
If the Cbor() method exists, apply this diff to fix the test:
- // Re-encode using the cbor Encode function
- encoded, err := cbor.Encode(block)
- if err != nil {
- t.Fatalf(
- "Failed to marshal AlonzoBlock using custom encode function: %v",
- err,
- )
- }
- if encoded == nil || len(encoded) == 0 {
- t.Fatal("Custom encoded CBOR from AlonzoBlock is nil or empty")
- }
+ // Retrieve the stored original CBOR bytes
+ encoded := block.Cbor()
+ if encoded == nil || len(encoded) == 0 {
+ t.Fatal("Stored CBOR from AlonzoBlock is nil or empty")
+ }Alternatively, if the goal is to test that cbor.Encode produces semantically equivalent CBOR (not byte-identical), the test should unmarshal both the original and re-encoded CBOR and compare the resulting structs instead of comparing bytes.
🏁 Script executed:
#!/bin/bash
# Search for the Cbor() method in DecodeStoreCbor type
ast-grep --pattern $'type DecodeStoreCbor struct {
$$$
}'
ast-grep --pattern $'func ($_ DecodeStoreCbor) Cbor() $_ {
$$$
}'
# Also search for any Cbor method implementation
rg -nP --type=go -A5 'func.*DecodeStoreCbor.*Cbor'Length of output: 563
Let me search the codebase for the AlonzoBlock type definition:
Let me search with the repository:
🏁 Script executed:
#!/bin/bash
# Search for AlonzoBlock type definition in ledger/alonzo
rg -nP --type=go 'type\s+AlonzoBlock\s+struct' -A10Length of output: 653
🏁 Script executed:
#!/bin/bash
# Search for AlonzoBlock type definition
rg -nP --type=go 'type\s+AlonzoBlock' -A15Length of output: 1729
Test logic error: Use stored CBOR bytes instead of re-encoding.
The pipeline failure at byte 7493 confirms the issue: cbor.Encode produces definite-length encoding (0x81), while the original block has indefinite-length encoding (0x9f). Both represent valid CBOR, but they're not byte-identical.
Since AlonzoBlock embeds cbor.DecodeStoreCbor, use block.Cbor() to retrieve the stored original bytes instead of re-encoding:
- // Re-encode using the cbor Encode function
- encoded, err := cbor.Encode(block)
- if err != nil {
- t.Fatalf(
- "Failed to marshal AlonzoBlock using custom encode function: %v",
- err,
- )
- }
- if encoded == nil || len(encoded) == 0 {
- t.Fatal("Custom encoded CBOR from AlonzoBlock is nil or empty")
- }
+ // Retrieve the stored original CBOR bytes
+ encoded := block.Cbor()This will fix the test to perform a true round-trip validation.
Committable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 GitHub Actions: go-test
[error] 68-68: TestAlonzoBlock_CborRoundTrip_UsingCborEncode failed. Custom CBOR round-trip mismatch for Alonzo block. Original CBOR (hex) and encoded CBOR differ.
[error] 83-84: First mismatch at byte index: 7493. Original byte: 0x9f, Re-encoded byte: 0x81.
🤖 Prompt for AI Agents
In ledger/alonzo/block_test.go around lines 54 to 92 the test incorrectly
re-encodes the decoded AlonzoBlock using cbor.Encode which produces a different
(definite-length) byte representation than the original (indefinite-length)
CBOR; instead call block.Cbor() to retrieve the original stored CBOR bytes from
the embedded DecodeStoreCbor and use those bytes for the equality checks,
validating non-nil/non-empty and comparing dataBytes to the returned stored
bytes (handling any error returned by block.Cbor()).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This round trip test is designed to ensure that our encoding will produce the same results as the original CBOR even when constructed from scratch from a struct which does not include the original CBOR. It should use cbor.Encode(block). The problem is in the CBOR encoding of one of the child structs of AlonzoBlock.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find AlonzoBlock definition and its child structs
ast-grep --pattern 'type AlonzoBlock struct {
$$$
}'
Length of output: 537
🏁 Script executed:
#!/bin/bash
# Search for all MarshalCBOR implementations in the alonzo package
rg -nP --type=go 'func.*MarshalCBOR' ledger/alonzo/
Length of output: 93
🏁 Script executed:
#!/bin/bash
# Let's decode the hex at the position where the mismatch occurs to understand the structure
# Byte 7493 in the original hex - let's look at the context around that position
echo "85828f1a0076e44f1a044f775f5820f289b983294053fa79e182cc464608c8b0839501aa7f60ead08992446b74ff5a582054a08fb24331f75a0ef1ed4918bdea3f6cc7a943f620f2dfd6fddde7a7b3386e58206d1b4ca9f3e109ac01bba976867c85e50e521df6e44610a7ef63167184adf43b82584041623ec7ed8f02d3fc41494333a1a2e2d920d4ab1052cb43fec4da1c2b0feb95e3eaa96f114ffeb5e0b0ed45dadf5000db0f8b6c56e006a6d9f672f5612ab5345850d0a37a9510d9aaaa2d98dafac2baf544f4d7dfef4982167c7375c9a0279e740a2536f9296d69b848e60578950b52d4062f14c5b79367c4add4cb8ff40d285d01bfe7635bf551a43e545097178d7ac10b825840000065f35d36a8af91cf946b6343b895e7ba1e2ab16fcf5626662ff87ba2bb59f815299db1c4365d03d1b004a0379c154d16e2ddf062b127b0c9a01679674a505850cf97a889d4a9e49e6c0336f1afd076b2ad3a2f24a094a62da33d11eeb4a13e7e549afcef1357dddf9fea024cc68bd93857397aee46df40d203c4082ce34a50582852923308652bd69430f3e0ba7a060a191c5458205054611d3aa3d83caa5409b9ff6283659672298423e4d86938993aa5891b4ac158204d87ad159b4d15510164ee138e6949f96ec33b3b8fb19194f19eca852c2764a90119022358404989cb6f6908f43c0d2939ddfb8b8cb0514b4ade1a741c86acdb8774b53252b7626d780dc08d586f5fc6ff06649e41b835a07d7b8761518584e3f80ed2bec80907025901c009e03bea22014744a96f5d9eac6b1aa40d2a04cc86ac534a3d8c8b3c5c46e8a6dab35fbb580d0e9b7b5b5ec217ad44457a5c392f6f1d2fb660a7664a6d6caf06d25aa9661adc4b0a7115495448176ec8d3c63c19e0949a20407a7b7787107e40e3ccefe0704f09a5871466b197d5aca1866f20502820a2bebe7e36826dbe067e3dd934c1077f14d2f7f602b53a265fd54b73556cc50db813ba710b5a81ece98098c850dc1321ecf64464d6b14d90465a70149b1a03249ac0ec555684da175eee5a12549cec498ff4eb15cc475e8a6429ab35ba88e9d03e4c64a341e7401347ed1d052d04f39577a92afe6768d3093cb2ca76d391deaac18d3253998a636aef7c0b4c7ae46f774e3e17643ce24f4c1c0605c7b5d434a1475e1508efd5f3e0cf649553fe6956b89107e255c23f7fa01d48c2e6641fe28c916dd407d44b7d308622a51c397974c4f46fedea8b259aefdd5d045c3c8a1bd999eb5feae51ad66a62dd357f3915f0706d12b85607f4603cfd196ffba7e3b52950f93e3ca368bb4283e59599bb9a442d1576e0be6f542f81ec9eebb0a5bcb94200d30ce336cf96df9fafdbc32d66c996f7fcb876d7cbbe2ca754ca1669559f917a42de85d600574a073c84a800838258206fbc2c129d3f860feb0dc3ea0942a0e9e19ede92f6f0991f2b549497e2a29ae9008258209d845b74015ca8aee31e15be03f9acd1ddecefb02080929132553f196367e5ad05825820d93b6d8857ff6447b8bbd4e5f8fa86b58023ef341456ff2eda3e0d89f51f8d5205018682583901ec1b21968ba227e7a0bff663efe7d160416508cb3042524b910316253573abf694a555b81aeee68f61f3f91ed5a18bf7eeeb43ac1900c9ab1a002625a08258390170e60f3b5ea7153e0acc7a803e4401d44b8ed1bae1c7baaad1a62a721e78aae7c90cc36d624f7b3bb6d86b52696dc84e490f343eba89005f1a000f4240825839012605b6d3b67730dc13f393861841ee3c6b751531558a94cc05c54ee4183f69a0fd8d581f6e0cf57fd8b856cd856b5d82758183c9fc22350c1a02c588a0825839013208d24ba97635e2d5cf5e419b9c06ff47be097af941fae371fa9c7844cf494c42bb64976d3aea361d46b84481e697eb3466530e24df07f6821a00172698a1581ccc3bccc160d89e07ff903caed26d0823f7128ebf3eed5e0e7894a076a14e446567656e42756e6e793233343201825839013208d24ba97635e2d5cf5e419b9c06ff47be097af941fae371fa9c7844cf494c42bb64976d3aea361d46b84481e697eb3466530e24df07f61a004c4b40825839013208d24ba97635e2d5cf5e419b9c06ff47be097af941fae371fa9c7844cf494c42bb64976d3aea361d46b84481e697eb3466530e24df07f61a0302e968021a000addd6031a044f853d081a044f772d0b58203ba6872fbd19dff7b0d46f5d2848e14ac4c302b339bbdd86f18380e429a98f970d81825820fa4ecedc053cc9a6ecd295462e9650a3db535eb14fa9160d187d0b3d6d9abc74010e81581c3208d24ba97635e2d5cf5e419b9c06ff47be097af941fae371fa9c78a50081825820fbd182578c520e965948f648580c5f7245a0346c852c6f64591094363f809e1f00018182583901b5c2c07d85254c17367cc2eb1d8dd38c02c7405901c8d463d3fabbb8839fc3801785f287ead5ad0b3c327f8e54c71d6156d9dffbb3f23d761a27ce3623021a0002a8dd031a04502006048282008200581c839fc3801785f287ead5ad0b3c327f8e54c71d6156d9dffbb3f23d7683028200581c839fc3801785f287ead5ad0b3c327f8e54c71d6156d9dffbb3f23d76581ca79f362a5947f002a9087837627e8d720aadcab1f5655c7b3d41abeba400828258204d87fb6988b759a799e7452af473f1dcbe26d58aab0a3a5bbaa2aa8e9b25cbc801825820f7c3f7dc19a83dbcd85aba75b0078011888c48e9ea480f0b77d1fe1e7711db3f0101828258390191a51fbc7f28528956c5c5b29bfa5d6e18af5a7edb3d69d0d93360f1d0a7d31baf3434a89b662497acab66f29bf587714faaf5662e5aa6e61a01312d008258390155e5dab09c372e401c5bbb767bfbcc2c7add933387c7681f16bbc19e4b6b0846b3d77813c148d810512d47b0f504795f6eaba9c6931f92a7821a00523db0a1581cb3e1cf0ef01fbcadba904194b9715cdfaa69578dd19208a5036c6bbea15242726f6e7a6520466972737420526964657201021a0002a0c9031a044fcb5ea400828258200c32af743d569cc0f27ab547924ce3e8632833e1cd34a11c58a7e87ee0f00532018258200c32af743d569cc0f27ab547924ce3e8632833e1cd34a11c58a7e87ee0f0053200018a825839014a26c538fdd73b0865f5f2031d52d43823eb59f4608a943de9ef4f738d8b0e001d461c9de10177e57df026dbd8112ecd1f51c6a26ce512f9821a00150bd0a1581c423aaa3a092aff29c00cef49fe0bef65abf7838226d6869ca9c44f24a14f43617264616e6f4b6579733038373201825839014a26c538fdd73b0865f5f2031d52d43823eb59f4608a943de9ef4f738d8b0e001d461c9de10177e57df026dbd8112ecd1f51c6a26ce512f9821a00150bd0a1581c423aaa3a092aff29c00cef49fe0bef65abf7838226d6869ca9c44f24a14f43617264616e6f4b6579733135353001825839014a26c538fdd73b0865f5f2031d52d43823eb59f4608a943de9ef4f738d8b0e001d461c9de10177e57df026dbd8112ecd1f51c6a26ce512f9821a00150bd0a1581c423aaa3a092aff29c00cef49fe0bef65abf7838226d6869ca9c44f24a14f43617264616e6f4b6579733233363501825839014a26c538fdd73b0865f5f2031d52d43823eb59f4608a943de9ef4f738d8b0e001d461c9de10177e57df026dbd8112ecd1f51c6a26ce512f9821a00150bd0a1581c423aaa3a092aff29c00cef49fe0bef65abf7838226d6869ca9c44f24a14f43617264616e6f4b6579733334333701825839014a26c538fdd73b0865f5f2031d52d43823eb59f4608a943de9ef4f738d8b0e001d461c9de10177e57df026dbd8112ecd1f51c6a26ce512f9821a00150bd0a1581c423aaa3a092aff29c00cef49fe0bef65abf7838226d6869ca9c44f24a14f43617264616e6f4b6579733536353401825839014a26c538fdd73b0865f5f2031d52d43823eb59f4608a943de9ef4f738d8b0e001d461c9de10177e57df026dbd8112ecd1f51c6a26ce512f9821a00159282a1581c4d9159b8c6a62fb828d74a4f1cd96e8729269c38516ca6d1682321a2a156416c6f6e7a6f417474656e64616e6365546f6b656e3201825839014a26c538fdd73b0865f5f2031d52d43823eb59f4608a943de9ef4f738d8b0e001d461c9de10177e57df026dbd8112ecd1f51c6a26ce512f9821a0014851ea1581c6ac8ef33b510ec004fe11585f7c5a9f0c07f0c23428ab4f29c1d7d10a1444d454c441acc308c04825839014a26c538fdd73b0865f5f2031d52d43823eb59f4608a943de9ef4f738d8b0e001d461c9de10177e57df026dbd8112ecd1f51c6a26ce512f9821a0014851ea1581c9a9693a9a37912a5097918f97918d15240c92ab729a0b7c4aa144d77a14653554e4441451a003125a2825839014a26c538fdd73b0865f5f2031d52d43823eb59f4608a943de9ef4f738d8b0e001d461c9de10177e57df026dbd8112ecd1f51c6a26ce512f9821a0014851ea1581cf0ff48bbb7bbe9d59a40f1ce90e9e9d0ff5002ec48f232b49ca0fb9aa147707265747a656c0182583901392e2e855a44daed9b0330b317c428d46b067cee9278f940ebcc32ccfa93d72c9f00c279849f33324625e44652a7c053e0a31e32fda53cb41a083f2249021a00033c29031a044f935084a40081825820a6929ef8e2699b1f493c89af8724bb189dbe1037eb247d4bb685b11932fbde235840fedd62d92bdddab9cb1f42a7ecdb062cffa6e5cf4bd800195617d32b286572b2e2df64a2c5c6f1e3ab3c0579a0a07ad7eacd2b336d7b989086d1de721526060c0381590fc1590fbe0100003233223232323322333222323233322232333222323332223322323322323332223232332233223232332232323332223322332233223322323232323232323232323232332232323232323232323322323232332232333322223232323232322232232325335305c33223530310012235303500222222222322235304400c23232325335306f333222533530723300300200110731074506e32353047001220023253353505a00113507649010350543800221002302e5002004107115335304a01313301b49101350033355029302f1200123535505e00122323355030335502d30331200123535506200122353550640012253353506f335503533550250490040062153353507033550363335550323039120012235355069002232233225335350770022130020011507800425335350763335502c0500040072153353080013304d0010031335503d5079300400215335308001330630010031335503d507933335502e0510053304900100300215078150773200135508601225335350680011506a2213535506e002225335308201330530020071003133506d33550710020013006003350720010022133026491023130003322333573466e200080041f41f8cc8cd54c0ec48004d40c00048004cd40c40952000335530321200123535506900122001001004133573892010231310007a133573892010231320007900233233553023120013503500135034001335038223355302c120012353550630012233550660023355302f12001235355066001223355069002333535502b0012330264800000488cc09c0080048cc09800520000013355302c1200123535506300122335506600233353550280012335530301200123535506700122335506a00235502f0010012233355502804a0020012335530301200123535506700122335506a00235502d001001333555023045002001505e33233553023120012253353506c3003002213350610010021001505f2353053001222533530763332001504100600313506f0021506e011320013333555028302f1200122353055002225335307333044002500b10031333355502c303312001235305a00122253353506e333550245042003001213333550265043004335530301200123535506700122335506a002333535502c0012001223535506b002223535506d0032233550703302c00400233553039120012353550700012233550730023335355035001200122330310020012001333555030052003001200133355502704900300100213333550255042003002001003001505b500113301b49101340033355029302f1200123530540012233043500a00250011533535058335530401200123320015051320013530460012235305100122253353506b0012321300100d3200135507f2253353506100113507d491022d310022135355067002225335307b3304c00200710011300600313507a49101370050011350744901013600221335530421200123320015053320013530480012235305300122253353506d0012321300100f32001355081012253353506300113507f491022d310022135355069002225335307d3304e00200710011300600313507c4910137005003133355301d12001225335306f335306a303e302d35304600222001207125335307033041001300401010721350764901013300133505a0020011001505900d3200135507622533535058001135074491022d31002213530470022253353072333200150710020071353063303000122335306f00223507b491022d310020011300600315335350520011306d4988854cd4d41500044008884c1c5263333573466e1d40112002203a23333573466e1d40152000203a23263530663357380b80ce0ca0c80c66666ae68cdc39aab9d5002480008cc0c4c8c8c8c8c8c8c8c8c8c8c8cccd5cd19b8735573aa01490001199999999981f99a828919191999ab9a3370e6aae7540092000233045304b35742a00460986ae84d5d1280111931a983a99ab9c06b076074073135573ca00226ea8004d5d0a80519a8288241aba1500935742a0106ae85401cd5d0a8031aba1500535742a00866a0a2eb8d5d0a80199a82899aa82b3ae200135742a0046ae84d5d1280111931a983899ab9c06707207006f135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135573ca00226ea8004d5d0a80119191999ab9a3370e6aae75400520022303a303e357426aae7940088c98d4c1a0cd5ce02f03483383309baa001357426ae8940088c98d4c194cd5ce02d833032031883289931a983219ab9c49010350543500065063135573ca00226ea80044d55ce9baa001223370000400244a66a60ac00220b0266ae7000815c4488c88c008004c8004d5417c894cd4d41040045413c884d4d5411c008894cd4c16ccc02000801c4d41500044c01800c448888c8cd54c03c480048d4d5411800488cd54124008ccd4d5402c0048004880048004ccd554018014008004c8cd40054109410c488cc008cd5411c014010004444888ccd54c0104800540fccd54c030480048d4d5410c00488cd54118008d5402c004ccd54c0104800488d4d54110008894cd4c160ccd54c06048004d4034cd403c894cd4c168008417040041648d4d5411c00488cc028008014018400c4cd410c01000d4100004cd54c030480048d4d5410c00488c8cd5411c00cc004014c8004d54184894cd4d410c0044d5402c00c884d4d54124008894cd4c174cc0300080204cd5404001c0044c01800c008c8004d5416888448894cd4d40fc0044008884cc014008ccd54c01c480040140100044484888c00c01044884888cc0080140104484888c00401044800448cd404888ccd4d401000c88008008004d4d40080048800448848cc00400c00848004c8004d541488844894cd4d40d8004540e0884cd40e4c010008cd54c018480040100044448888cccd54011403c00c0040084488cd54008c8cd403c88ccd4d401800c88008008004d4d401000488004cd401005012800448848cc00400c008480044488c0080048d4c08c00488800cc8004d5412c88c8c94cd4c114cc0a14009200213300c300433530081200150010033004335300d12001500100310031332233706004002a002900209999aa9801890009919a80511199a8040018008011a802800a8039119b800014800800520003200135504a221122253353502f00113500600322133350090053004002333553007120010050040011235350050012200112353500400122002320013550472212253353041333573466e2400920000430421502d153353502b0011502d22133502e002335300612001337020089001000899a801111180198010009000891091980080180109000990009aa821911299a9a81300108009109a980a801111a982180111299a9a8160038a99a9a8160038804110b1109a980d801111a982480111299a9824199ab9a33720010004094092266a0660186601e01601a2a66a6090666ae68cdc8804001024825099a819803198078070028a99a982419809003800899a81980619807805806899a81980319807807002990009aa82111091299a9a8130008a814110a99a981f19804002240002006266a600c240026600e00890010009119b8100200122333573466e240080040e80e4488cc00ccc01cc018008c018004cc894cd4d40c0008854cd4d40c400884cd4c0b80088cd4c0bc0088cc034008004888100888cd4c0c401081008894cd4c104ccd5cd19b87006003043042153353041333573466e1c01400810c1084cc0380100044108410840ec54cd4d40c0004840ec40ecc014008c014004894cd4c0d8008400440dc88ccd5cd19b8700200103703623530240012200123530230012200222335302d0022335302e00223300500200120352335302e002203523300500200122333573466e3c0080040cc0c8c8004d540e08844894cd4d407000454078884cd407cc010008cd54c018480040100048848cc00400c0088004888888888848cccccccccc00402c02802402001c01801401000c00880048848cc00400c0088004848c004008800448800848800480048c8c8cccd5cd19b8735573aa004900011981519191999ab9a3370e6aae75400520002375c6ae84d55cf280111931a981899ab9c02703203002f137540026ae854008dd69aba135744a004464c6a605c66ae700900bc0b40b04d55cf280089baa00123232323333573466e1cd55cea801a4000466600e602c6ae85400cccd5403dd719aa807bae75a6ae854008cd4071d71aba135744a004464c6a605c66ae700900bc0b40b04d5d1280089aab9e5001137540024442466600200800600440022464646666ae68cdc39aab9d5002480008cc88cc024008004dd71aba1500233500a232323333573466e1cd55cea80124000466446601e004002602c6ae854008ccd5403dd719aa809919299a981419805a800a40022a00226a05c921022d33001375a00266aa01eeb88c94cd4c0a0cc02d400520001500113502e491022d32001375a0026ae84d5d1280111931a981719ab9c02402f02d02c135573ca00226ea8004d5d09aba25002232635302a33573804005605205026aae7940044dd500091199ab9a33712004002040042442466002006004400244246600200600440022464460046eb0004c8004d5408c88cccd55cf80092804119a80398021aba1002300335744004048224464460046eac004c8004d5408c88c8cccd55cf80112804919a80419aa80618031aab9d5002300535573ca00460086ae8800c0944d5d0800889100109109119800802001890008891119191999ab9a3370e6aae754009200023355008300635742a004600a6ae84d5d1280111931a981099ab9c01702202001f135573ca00226ea8004448848cc00400c0084480048c8c8cccd5cd19b8735573aa004900011980318071aba1500233500a2323232323333573466e1d40052002233300e375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea004900011808180a9aba135573ca00c464c6a604666ae700640900880840804d55cea80189aba25001135573ca00226ea8004d5d09aba25002232635301c33573802403a03603426aae7940044dd5000910919800801801100090911801001911091199800802802001900089119191999ab9a3370ea002900011a80418029aba135573ca00646666ae68cdc3a801240044a010464c6a603066ae7003806405c0580544d55cea80089baa001121223002003112200112001232323333573466e1d4005200223006375c6ae84d55cf280191999ab9a3370ea0049000118041bae357426aae7940108c98d4c04ccd5ce00480a00900880809aab9d50011375400242446004006424460020064002921035054310012253353003333573466e3cd4c01800888008d4c018004880080140104ccd5cd19b873530060022200135300600122001005004100412200212200120012212330010030022001235002490101310012326353003335738002008004930900090008891918008009119801980100100081049fd8799f581c2605b6d3b67730dc13f393861841ee3c6b751531558a94cc05c54ee49fd8799fd8799fd8799f581cec1b21968ba227e7a0bff663efe7d160416508cb3042524b91031625ffd8799fd8799fd8799f581c3573abf694a555b81aeee68f61f3f91ed5a18bf7eeeb43ac1900c9abffffffffa140d8799f00a1401a002625a0ffffd8799fd8799fd8799f581c70e60f3b5ea7153e0acc7a803e4401d44b8ed1bae1c7baaad1a62a72ffd8799fd8799fd8799f581c1e78aae7c90cc36d624f7b3bb6d86b52696dc84e490f343eba89005fffffffffa140d8799f00a1401a000f4240ffffd8799fd8799fd8799f581c2605b6d3b67730dc13f393861841ee3c6b751531558a94cc05c54ee4ffd8799fd8799fd8799f581c183f69a0fd8d581f6e0cf57fd8b856cd856b5d82758183c9fc22350cffffffffa140d8799f00a1401a02c588a0ffffffffff0581840000d87a80821a003c19aa1a541fdb09a10082825820c537dea041be45c4fdfa312d5ec2b1c5fb20b22a5c83d2fe19d2ad8c5c9cf97f584030b3698511623e18657f0726952b0ef5ccb6fead676bb659e14f607ad2a03c1b854dc1abe5111a30224651c844ff9791eab71f6cc261d138a5a5929435b50e0e825820bf896d9d767fa126b9e81111fe8014c4ecc4a039d502c42d30070c182fc2fe3c5840aaf16b4078bce4fec432da0cdbd7d3d8eb45791a685f0dafc0240bf543d6d6db8604a10fbc8a6977a6aeaa68a4d40e932d6996e80bee88e701f9f533b074db02a10081825820fc67cff34b2818884e48191cd3c0bfbee53f8a028501fe49d11f0fca5bb60adb58408f53fbec8e9f5e13f7f22069e573825116891c054c73a2202811a0b52e459b71a4f41201850d636258318d4b1b11a7fc3170332e0d50401425eebcd36cff8600a10081825820484497cb155e96f1dbdf476804faf2ed612b436238047e6f2f15c15be23f97045840eff588eb8be144053a6bda757c2b503e8f2e3bbd583bf78f1352ea177bae4203b4e6c61c6f3a9b6fed8b9840d6349e57116750fee7bdd02c2fa0a166adfe2d08a080" | \
python3 -c "
import sys
hex_str = sys.stdin.read().strip()
# Convert to bytes
data = bytes.fromhex(hex_str)
# Byte 7493
byte_7493 = data[7493] if len(data) > 7493 else None
print(f'Hex length: {len(data)} bytes')
print(f'Byte at offset 7493: 0x{byte_7493:02x}' if byte_7493 else 'Offset beyond data length')
# Show context around byte 7493
if byte_7493:
start = max(0, 7493 - 20)
end = min(len(data), 7493 + 20)
print(f'Context (bytes {start}-{end}):')
print(' '.join(f'{b:02x}' for b in data[start:end]))
"
Length of output: 195
🏁 Script executed:
#!/bin/bash
# Search for the block structure and auxiliary data structure in alonzo
rg -nP --type=go 'type.*AuxiliaryData|type.*Auxiliary' ledger/alonzo/ -A10
Length of output: 0
🏁 Script executed:
#!/bin/bash
# Look for the full AlonzoBlock type definition
cat ledger/alonzo/block.go | head -100
Length of output: 54
🏁 Script executed:
#!/bin/bash
# Search for how InvalidTransactions is handled in encoding
rg -nP --type=go 'InvalidTransactions' ledger/alonzo/ -B3 -A3
Length of output: 883
🏁 Script executed:
#!/bin/bash
# Search for indefinite length array encoding in cbor package
rg -nP --type=go 'IndefiniteLength|indefinite' cbor/ -B2 -A2
Length of output: 780
🏁 Script executed:
#!/bin/bash
# Look at the alonzo.go file to see the full structure definitions
cat ledger/alonzo/alonzo.go | grep -A 30 "type AlonzoBlock"
Length of output: 2560
🏁 Script executed:
#!/bin/bash
# Search for MarshalCBOR and UnmarshalCBOR implementations in alonzo
rg -nP --type=go 'func.*\(.*\).*Marshal|func.*\(.*\).*Unmarshal' ledger/alonzo/ -A5
Length of output: 3874
🏁 Script executed:
#!/bin/bash
# Check what cbor.StructAsArray does
rg -nP --type=go 'type StructAsArray|StructAsArray' cbor/ -B2 -A5
Length of output: 1051
🏁 Script executed:
#!/bin/bash
# Look at the encoding options and see if there's an indefinite length setting
cat cbor/encode.go
Length of output: 3486
@wolf31o2, Thank you for the clarification! I understand now - you want to ensure the encoder produces byte-identical CBOR from a freshly constructed struct.
Based on my analysis, the issue is at byte offset 7493 where the original CBOR uses an indefinite-length array (byte 0x9f) but cbor.Encode produces a definite-length array (byte 0x81).
The most likely culprit is the InvalidTransactions []uint field in AlonzoBlock. In the original CBOR, this field is encoded as an indefinite-length array, but when using cbor.Encode, Go slices are encoded as definite-length arrays by default.
The solution: Change the type from []uint to cbor.IndefLengthList in the AlonzoBlock struct definition in ledger/alonzo/alonzo.go:
type AlonzoBlock struct {
cbor.StructAsArray
cbor.DecodeStoreCbor
BlockHeader *AlonzoBlockHeader
TransactionBodies []AlonzoTransactionBody
TransactionWitnessSets []AlonzoTransactionWitnessSet
TransactionMetadataSet map[uint]*cbor.LazyValue
InvalidTransactions cbor.IndefLengthList // Changed from []uint
}You may also need to update any code that accesses InvalidTransactions to cast it appropriately, or provide helper methods to work with it as []uint.
If this doesn't resolve it, the issue might be in another nested struct field. You could verify by checking what's at byte 7493 in the CBOR structure more carefully, or by binary searching which field causes the divergence.
🧬 Code Graph Analysis Results
<filename: cbor/encode.go>
lines 27-40:
func Encode(data any) ([]byte, error) {
buf := bytes.NewBuffer(nil)
opts := _cbor.EncOptions{
// Make sure that maps have ordered keys
Sort: _cbor.SortCoreDeterministic,
}
em, err := opts.EncModeWithTags(customTagSet)
if err != nil {
return nil, err
}
enc := em.NewEncoder(buf)
err = enc.Encode(data)
return buf.Bytes(), err
}
<filename: ledger/alonzo/alonzo.go>
lines 52-60:
AlonzoBlock struct {
cbor.StructAsArray
cbor.DecodeStoreCbor
BlockHeader *AlonzoBlockHeader
TransactionBodies []AlonzoTransactionBody
TransactionWitnessSets []AlonzoTransactionWitnessSet
TransactionMetadataSet map[uint]*cbor.LazyValue
InvalidTransactions []uint
}
<filename: ledger/alonzo/alonzo.go>
lines 73-75:
func (AlonzoBlock) Type() int {
return BlockTypeAlonzo
}
<filename: ledger/alonzo/alonzo.go>
lines 788-794:
func NewAlonzoBlockFromCbor(data []byte) (*AlonzoBlock, error) {
var alonzoBlock AlonzoBlock
if _, err := cbor.Decode(data, &alonzoBlock); err != nil {
return nil, fmt.Errorf("decode Alonzo block error: %w", err)
}
return &alonzoBlock, nil
}
Signed-off-by: Chris Gianelloni <wolf31o2@blinklabs.io>
aaed11c to
5cbfa5a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
ledger/alonzo/block_test.go (1)
35-93: LGTM! Comprehensive round-trip test with excellent diff reporting.The test correctly validates byte-identical CBOR encoding with helpful diagnostics:
- Clear test structure: decode → unmarshal → encode → compare
- Detailed mismatch reporting showing byte index and values
- Properly exercises the new
MarshalCBORmethod throughcbor.EncodeOptional enhancement: Consider adding test cases for edge cases like blocks with no invalid transactions or empty transaction lists to ensure the encoding handles all variations correctly.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
ledger/alonzo/alonzo.go(1 hunks)ledger/alonzo/block_test.go(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
ledger/alonzo/alonzo.go (4)
cbor/cbor.go (2)
StructAsArray(45-48)DecodeStoreCbor(55-57)ledger/common/block.go (1)
BlockHeader(13-22)cbor/value.go (1)
LazyValue(367-369)cbor/encode.go (2)
IndefLengthList(92-92)Encode(27-40)
ledger/alonzo/block_test.go (2)
ledger/alonzo/alonzo.go (2)
AlonzoBlock(52-60)AlonzoBlock(113-115)cbor/encode.go (1)
Encode(27-40)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Analyze (go)
🔇 Additional comments (3)
ledger/alonzo/alonzo.go (1)
73-111: LGTM! Excellent solution to the indefinite-length encoding issue.The
MarshalCBORmethod correctly addresses the byte-level encoding difference identified in previous reviews:
- Returns stored CBOR when available (performance optimization)
- Converts
InvalidTransactionstocbor.IndefLengthListfor indefinite-length encoding when constructing from scratch- Properly handles the nil case for
InvalidTransactions- Includes a clear comment explaining the encoding requirement
This approach ensures byte-identical round-trip encoding while maintaining compatibility with the on-chain CBOR format.
ledger/alonzo/block_test.go (2)
1-27: LGTM! Proper copyright header and imports.The copyright header and import additions are appropriate for the new test functionality. The imports are properly organized following Go conventions.
95-95: LGTM! Test renamed for consistency.The test rename from
TestAlonzoBlockUtxorpctoTestAlonzoBlock_Utxorpcimproves naming consistency with the new round-trip test.
Summary by CodeRabbit
New Features
Tests