Documentation
¶
Overview ¶
Package adopt is the register of networks Lux did not create.
A network normally reaches the P-chain by being made: a chain is created, a validator set is assigned, it produces blocks. That path assumes the network does not exist yet. Ethereum, Bitcoin, Solana and Base all exist, and none of it is Lux's to create or validate.
Adoption records a BELIEF about such a network — that it is the one named, reachable where stated, and that messages attributed to it can be trusted on a stated basis. It confers nothing on the adopted network, which has agreed to nothing, and it grants Lux no authority over it.
The register is here rather than in a contract because every subsystem needs to read it before acting: the bridge before releasing, the oracle before attesting, the custody chain before signing. A P-chain record is the one thing all of them can already see.
See LP-1021.
Index ¶
- Variables
- type Anchor
- type Holding
- type Record
- type Registry
- func (g *Registry) Adopt(r Record) error
- func (g *Registry) Get(id ids.ID) (Record, bool)
- func (g *Registry) Len() int
- func (g *Registry) MayHold(id ids.ID) bool
- func (g *Registry) Release(id ids.ID) error
- func (g *Registry) Revise(r Record) error
- func (g *Registry) Weaken(id ids.ID, to Anchor) error
Constants ¶
This section is empty.
Variables ¶
var ( ErrNoChainID = errors.New("adopt: chain id required") ErrNoIdentity = errors.New("adopt: identity commitment required") ErrBadAnchor = errors.New("adopt: unknown anchor") ErrBadHolding = errors.New("adopt: unknown holding") ErrNoEndpoints = errors.New("adopt: at least one endpoint required") ErrSelfParent = errors.New("adopt: a network cannot take security from itself") ErrCustodyUnheld = errors.New("adopt: a declared anchor may not carry custody") ErrNoCustody = errors.New("adopt: an anchor that holds value needs a custody key") )
var ( ErrAlreadyAdopted = errors.New("adopt: already adopted") ErrNotAdopted = errors.New("adopt: not adopted") ErrNoParent = errors.New("adopt: the network it takes security from is not adopted") ErrParentHeld = errors.New("adopt: a network still takes security from this one") ErrWeakerAnchor = errors.New("adopt: weakening an anchor is a separate act") )
Functions ¶
This section is empty.
Types ¶
type Anchor ¶
type Anchor uint8
Anchor is the basis for believing a message attributed to an adopted network. It is the whole security boundary: everything downstream inherits exactly this and nothing more.
const ( // Declared: governance asserted the network is what it says it is. // Proves the estate agreed and nothing else. Enough to list a network, // open markets against it and issue assets — never enough to hold value, // because signing a transfer on a chain nobody has verified is custody // without evidence. Declared Anchor = iota + 1 // Attested: t+1 of the validator set independently observed the network // and threshold-signed what they saw. Proves they read the same thing; // leaves open whether they read it correctly, which is why finality depth // belongs in the record. This is the level at which value may cross. Attested // Proven: the network's own consensus is verified — a light client, a sync // committee signature, a validity proof. Proves the message is in a block // the network's own validators finalised. Proven )
func (Anchor) Custodial ¶
Custodial reports whether value may be held under this anchor.
The line sits between Declared and Attested and is the reason adoption can be permissionless: paying a fee buys a record, and a record is not a trust decision. Attestation cannot be bought, because what it requires is the committee actually observing the network.
type Holding ¶
type Holding uint8
Holding is how value is held on the adopted network.
const ( // Gateway: a contract or program holds the position and a release is a // call to it. Every EVM, Solana, TON. Gateway Holding = iota + 1 // Address: there is nowhere to put a contract, so the custody address IS // the gateway — a deposit is the lock and a signed spend is the release. // Bitcoin. Everything a contract would have enforced moves into the // attestation, which makes the anchor matter more here, not less. Address )
type Record ¶
type Record struct {
// ChainID is the network's own chain id — 1 for Ethereum, 8453 for Base.
ChainID uint64
// Identity commits to WHICH chain bears that id: a genesis hash, or an
// equivalent. A chain id alone is not an identity. Ids collide across
// testnets, and a fork inherits the id of the chain it left, so without
// this a split is invisible to the register.
Identity ids.ID
// Parent is the adopted network this one takes its security from, or the
// empty ID when the network is sovereign. Base names Ethereum; Ethereum
// names nothing.
Parent ids.ID
// Anchor is why Lux believes messages attributed to this network.
Anchor Anchor
// Holding is how value is held there.
Holding Holding
// Custody is the M-Chain key that signs for this network. Empty while the
// anchor is Declared, because a declared anchor may not hold value.
Custody string
// Endpoints is where the network is reachable.
Endpoints []string
// Depth is how many blocks of the adopted network must pass before its
// state is attested. A committee that reads a reorged chain attests a
// reorged chain, so this is the register's own statement of how much
// reorg it is willing to tolerate.
Depth uint64
}
Record is one adopted network.
func (Record) Key ¶
Key identifies a record. The identity commitment rather than the chain id, so a fork does not silently overwrite the chain it left.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry holds the adopted networks.
func NewRegistry ¶
func NewRegistry() *Registry
func (*Registry) Adopt ¶
Adopt records a network.
The rule with teeth: a network that takes its security from another may not be adopted before that other one. It is not bookkeeping. A Base state root is meaningful because it is posted to Ethereum and challengeable there — so adopting Base alone records a belief whose entire basis is a chain the register has never heard of, and the anchor cites a proof nobody can check. Ethereum first, then Base against it.
func (*Registry) MayHold ¶
MayHold reports whether value may cross to this network — the single question a bridge asks before releasing.
Unadopted answers no. That is the difference this register exists to make: before it, a bridge trusted a config file and nothing on chain said the estate had ever sanctioned it.
func (*Registry) Release ¶
Release ends an adoption.
Refused while another adopted network takes its security from this one: the survivor's anchor is a claim about the released chain, and releasing the chain it cites makes that claim unreadable. This is the adoption ordering running backwards, and it is the same rule.
Release is not a delete of history. Positions attested before release remain attested, because they were: what release ends is new crossings, not the evidence for old ones.
func (*Registry) Revise ¶
Revise changes a record in place.
An anchor may be strengthened freely: it costs nobody anything and every consumer is relying on less than it now gets. Weakening one is refused here and needs its own act, because a bridge, an indexer or an interface deciding what to show a user all read the anchor to know what a message is worth — and weakening it changes what every one of them is trusting without any of them being asked.
A record's identity and its parent do not change. A network that forks is a different network and gets its own record; a network that changes where its security comes from has become something else.