Repository navigation
Parse RGB 0.11.2-rc.1 (V1) consignments, expose globals, fix the archive CI - #5
Conversation
UTEXO moves to the RGB-Tools BFA release, whose consignments are V1 containers and whose BFA burn carries its amount and payout in globals (burnedAsset, burnReason) instead of metadata. - Pin rgb-ops =0.11.2-rc.1 (and the matching strict types / amplify). - Read TFR, CON, VTF and VCO containers; refuse V0 and SD2. - Expose transition and genesis globals (Globals, Global, GlobalOnce, ErrGlobalNotFound); GlobalOnce refuses a repeated type because the parser does not enforce the schema's NoneOrOnce. - Terminals list their seals (rc.1 terminals can be revealed) and each witness carries its bundle_id so a vout-only seal can be resolved. - Kit no longer exists in rc.1 and is removed. - Fixtures: the rc.1 BFA/IFA/CFA test vectors, a synthetic BFA mint and burn transfer, and a legacy V0 burn that must be rejected. Only the darwin_arm64 archive is rebuilt here; CI rebuilds the others
download-artifact does not truncate a file it overwrites. When a rebuilt
archive came out smaller than the committed one, the old tail stayed
behind and the linker refused it ("archive member invalid control
bits"): 2daf351 shipped broken darwin_arm64, linux_amd64 and linux_arm64
archives, and 27892b2 a broken darwin_amd64 one. commit-libs now removes
the archives before downloading and checks every ar member before it
commits. Workflow changes also trigger a rebuild, so this push rebuilds
all four.
The real cause of the broken archives: each libs runner uploaded all four rgbconsignment/lib/*/librgb_consignment.a, including the other platform's stale committed ones, and merge-multiple wrote both copies of the same path into one file. The new integrity check caught it on linux_amd64. libs now removes the committed archives before building, so an artifact holds only fresh archives.
Without a Rust change libs builds nothing, yet commit-libs still ran: it removed the archives, downloaded no artifact and, had the integrity check not failed, would have committed the deletion. libs now exports whether it built, and commit-libs runs only then.
dcorral
left a comment
There was a problem hiding this comment.
Approve. Nothing blocks the merge.
The minors are gaps in the new archive check in ci.yml and in the README and doc comments.
| pattern: libs-* | ||
| path: rgbconsignment/lib | ||
| merge-multiple: true | ||
| - name: Check the archives are intact |
There was a problem hiding this comment.
minor: The archive check only tests the ar structure. The archives reach the branch before any job links them: test has no needs: libs and uses the archives already in the checkout, and the commit message at L134 has [skip ci]. In libs, after the build and before the upload, run go test ./rgbconsignment against the native archive and link the cross-built one.
| run: | | ||
| python3 - rgbconsignment/lib/*/librgb_consignment.a <<'PY' | ||
| import sys | ||
| for path in sys.argv[1:]: |
There was a problem hiding this comment.
minor: Nothing checks that all four archives arrived. After the rm -f at L110, a missing artifact reaches the commit step as a deleted archive, and this loop passes on the rest. Fail unless all four rgbconsignment/lib/{darwin,linux}_{amd64,arm64}/librgb_consignment.a exist.
| assert off + 60 <= len(data) and data[off + 58:off + 60] == b"`\n", f"{path}: bad member header at {off}" | ||
| off += 60 + int(data[off + 48:off + 58].strip() or 0) | ||
| off += off % 2 | ||
| assert off in (len(data), len(data) + 1), f"{path}: member runs past the end" |
There was a problem hiding this comment.
minor: len(data) + 1 also accepts an archive that is one byte short when its last member has an even size. Each of the four committed archives passes with its last byte removed. Allow the extra byte only when the last member's size is odd.
| global state, terminals and witness transactions. | ||
|
|
||
| Built on RGB **0.11.2-rc.1** (`rgb-ops =0.11.2-rc.1`, `rgb-strict-types | ||
| =1.0.5`, `amplify =4.8.1`, the versions rgb-lib's `bfa` release uses). It |
There was a problem hiding this comment.
minor: "the versions rgb-lib's bfa release uses" is wrong. The bfa branch and -bfa tags of rgb-lib pin rgb-ops =0.11.1-rc.11 and rgb-strict-types =1.0.2. Name the rgb-lib ref that uses these versions, or remove the claim.
|
|
||
| A revealed seal without a `txid` points into its bundle's witness tx. For a | ||
| transition seal that is the enclosing `WitnessInfo`; for a terminal seal it is | ||
| the `WitnessInfo` whose `BundleID` equals the terminal's `BundleID`. |
There was a problem hiding this comment.
minor: More than one WitnessInfo can have the terminal's BundleID. The parser keeps every entry of bundles, and the bundle id does not depend on the witness tx. A transfer that repeats a bundle under two txs gives two matches. Say that unvalidated input can match more than once, or add a lookup that fails on a repeat, as GlobalOnce does for globals.
| env_logger = "0.11.3" | ||
| log = "0.4.21" | ||
| rgb-ops = { version = "0.11.1-rc.10", default-features = false, features = [ | ||
| # Exact pins: a caret requirement never moves onto a newer prerelease. |
There was a problem hiding this comment.
nit: The reason is wrong. A caret requirement does move to a newer prerelease of the same version: main asks for 0.11.1-rc.10 and its Cargo.lock resolves 0.11.1-rc.11. State the real reason for the exact pins.
| } | ||
|
|
||
| // Global returns the raw bytes of the first genesis value of globalType, if present. | ||
| func (g GenesisInfo) Global(globalType uint16) ([]byte, bool) { |
There was a problem hiding this comment.
nit: GenesisInfo has Global but no GlobalOnce. Code that reads a Once global such as bridgeLocation (README L60) silently gets the first of repeated values. Add GenesisInfo.GlobalOnce and use it in the README example.
| let location = format!("00{}{}", hex(&1u64.to_le_bytes()), "deadbeef".repeat(5)); | ||
| let entry = g.globals.iter().find(|e| e.global_type == 3008); | ||
| assert_eq!(entry.map(|e| e.value_hex.as_str()), Some(location.as_str())); | ||
| assert_eq!(g.globals.len() as u32, g.global_state_count); |
There was a problem hiding this comment.
nit: global_state_count counts global types (g.globals.len() on the genesis map at src/parse.rs:120), but globals has one entry per value. The two match here only because no type repeats in this fixture. Compare against the number of distinct global_type values.
| Ty::Enum(variants) => variants.tag_by_name(name), | ||
| _ => None, | ||
| } | ||
| fn meta_entries(metadata: &Metadata) -> Vec<MetaEntry> { |
There was a problem hiding this comment.
nit: meta_entries has one caller, transition_info at L195. Inline it there and remove Metadata from the import at L7.
| value.to_strict_serialized::<U16>().unwrap() | ||
| } | ||
|
|
||
| fn at(assignment_type: u16) -> AssignmentType { |
There was a problem hiding this comment.
nit: at only renames AssignmentType::with. Call AssignmentType::with at L134, L149 and L181, and delete the wrapper.
- README names the rgb-lib ref that locks these RGB versions (rgb-tools-devs/rgb-lib 3f571ac); our fork's bfa tags pin 0.11.1. - The terminal seal docs say a bundle can repeat under more than one witness tx in unvalidated input, so more than one WitnessInfo can match its BundleID. - The exact pins keep the RGB versions rgb-lib and the enclave decode with; a caret would move to a newer prerelease. - GenesisInfo.GlobalOnce refuses a repeated genesis global, as TransitionInfo.GlobalOnce does; the README bridgeLocation example uses it. - tests/fixtures.rs compares global_state_count with the distinct global types; meta_entries is inlined and the at() wrapper is gone.
What
Parser
rgb-ops =0.11.2-rc.1, with strict types 1.0.5 and amplify 4.8.1, matching the release lockfile.TFR,CON,VTFandVCOcontainers; refuse V0 andSD2. V1 carries no schema or type system, so asset metadata is decoded with the typed rgb-ops structs.Globals []GlobalEntry;Global(type);GlobalOnce(type), which refuses a repeated type, since the parser does not enforce the schema'sNoneOrOnce;ErrGlobalNotFound.bundle_id, so a vout-only seal resolves to its txid.Breaking changes
Kit(KindKit,IsKit,ConsignmentKind::Kit) is removed, because it no longer exists in rc.1. So arescript_countandtypes_count.TerminalInfo.SecretSealCountis replaced bySeals.versionis now 1.Fixtures