Skip to content

Parse RGB 0.11.2-rc.1 (V1) consignments, expose globals, fix the archive CI - #5

Merged
nklyy merged 9 commits into
mainfrom
feat/rgb-0.11.2-rc1
Oct 16, 2026
Merged

nklyy merged 9 commits into
mainfrom
feat/rgb-0.11.2-rc1

Conversation

@nklyy

@nklyy nklyy commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

What

Parser

  • Pin rgb-ops =0.11.2-rc.1, with strict types 1.0.5 and amplify 4.8.1, matching the release lockfile.
  • Read the TFR, CON, VTF and VCO containers; refuse V0 and SD2. V1 carries no schema or type system, so asset metadata is decoded with the typed rgb-ops structs.
  • Expose transition and genesis globals:
    • Globals []GlobalEntry;
    • Global(type);
    • GlobalOnce(type), which refuses a repeated type, since the parser does not enforce the schema's NoneOrOnce;
    • ErrGlobalNotFound.
  • Terminals list their seals, because rc.1 terminals can be revealed. Each witness carries its 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 are script_count and types_count.
  • TerminalInfo.SecretSealCount is replaced by Seals.
  • version is now 1.

Fixtures

  • The rc.1 BFA, IFA and CFA test vectors.
  • A synthetic BFA mint and burn transfer. A Rust test fails if it drifts from its builder.
  • A legacy V0 BFA burn that must be rejected.

nklyy added 7 commits October 12, 2026 14:03
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.
@nklyy
nklyy marked this pull request as draft October 12, 2026 13:39
@nklyy
nklyy marked this pull request as ready for review October 16, 2026 06:26

@dcorral dcorral left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approve. Nothing blocks the merge.
The minors are gaps in the new archive check in ci.yml and in the README and doc comments.

Comment thread .github/workflows/ci.yml Outdated
pattern: libs-*
path: rgbconsignment/lib
merge-multiple: true
- name: Check the archives are intact

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Comment thread .github/workflows/ci.yml
run: |
python3 - rgbconsignment/lib/*/librgb_consignment.a <<'PY'
import sys
for path in sys.argv[1:]:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Comment thread .github/workflows/ci.yml Outdated
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"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Comment thread README.md Outdated
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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Comment thread README.md Outdated

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`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Comment thread Cargo.toml Outdated
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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Comment thread rgbconsignment/types.go
}

// Global returns the raw bytes of the first genesis value of globalType, if present.
func (g GenesisInfo) Global(globalType uint16) ([]byte, bool) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Comment thread tests/fixtures.rs Outdated
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);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Comment thread src/parse.rs Outdated
Ty::Enum(variants) => variants.tag_by_name(name),
_ => None,
}
fn meta_entries(metadata: &Metadata) -> Vec<MetaEntry> {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: meta_entries has one caller, transition_info at L195. Inline it there and remove Metadata from the import at L7.

Comment thread tests/synthetic/mod.rs Outdated
value.to_strict_serialized::<U16>().unwrap()
}

fn at(assignment_type: u16) -> AssignmentType {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: at only renames AssignmentType::with. Call AssignmentType::with at L134, L149 and L181, and delete the wrapper.

nklyy added 2 commits October 16, 2026 16:26
- 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.
@nklyy
nklyy merged commit 749a436 into main Oct 16, 2026
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.

2 participants