mirror of
https://github.com/luxfi/api.git
synced 2026-09-24 00:24:53 +00:00
zap: carry the Quasar EXPORT capability across the rpcchainvm boundary (wire)
Two-tier consensus v1.36 splits finality into Nova (local, reorgable accept tip) and Quasar (⅔-by-stake EXPORT-final). A VM's `finalized`/`safe` tags and its cross-chain (warp) export gate must resolve to the Quasar height. But the C-Chain EVM runs as a SEPARATE rpcchainvm plugin process, and nothing carried the export height across the ZAP boundary — so the whole export tier was dormant in the real deploy (finalized/safe stuck at genesis). Wire additions (OPTIONAL, capability-gated — generic VMs are unaffected): - MsgSetQuasarFinalized (60) / MsgQuasarHeight (61): the two export RPCs. Kept < 0x40 so the response/error flags OR in cleanly, grouped after Warp (50-59). - InitializeResponse.Capabilities (uint64) + CapQuasarExport bit: the plugin advertises the export capability in the handshake so the node wires the observer only for an export-capable VM. Appended to the struct codec (all four encode/decode sites go through the struct methods, so it stays consistent). - SetQuasarFinalizedRequest / QuasarHeightResponse message structs. Co-authored-by: Hanzo Dev <[email protected]>
This commit is contained in:
@@ -115,8 +115,25 @@ type InitializeResponse struct {
|
||||
Height uint64
|
||||
Bytes []byte
|
||||
Timestamp int64
|
||||
// Capabilities is a bitfield of OPTIONAL cross-boundary add-ons the VM
|
||||
// implements (see the Cap* constants). The node reads it once at handshake
|
||||
// to decide which add-ons to wire; an unset bit → the node treats that
|
||||
// capability as absent and stays on the generic path.
|
||||
Capabilities uint64
|
||||
}
|
||||
|
||||
// VM capability bits advertised in InitializeResponse.Capabilities. A VM sets a
|
||||
// bit to tell the node it implements the corresponding OPTIONAL add-on that is
|
||||
// NOT part of the generic ChainVM contract. Discovered at the handshake, never
|
||||
// braided into ChainVM — generic VMs leave every bit clear.
|
||||
const (
|
||||
// CapQuasarExport: the VM tracks a Quasar (⅔-by-stake) EXPORT-FINAL height
|
||||
// distinct from its reorgable local accept tip, and answers
|
||||
// MsgSetQuasarFinalized / MsgQuasarHeight. Set by the C-Chain EVM; the node
|
||||
// wires the consensus export-frontier observer only when this bit is set.
|
||||
CapQuasarExport uint64 = 1 << 0
|
||||
)
|
||||
|
||||
// Encode serializes InitializeResponse to the buffer
|
||||
func (m *InitializeResponse) Encode(buf *Buffer) {
|
||||
buf.WriteBytes(m.LastAcceptedID)
|
||||
@@ -124,6 +141,7 @@ func (m *InitializeResponse) Encode(buf *Buffer) {
|
||||
buf.WriteUint64(m.Height)
|
||||
buf.WriteBytes(m.Bytes)
|
||||
buf.WriteInt64(m.Timestamp)
|
||||
buf.WriteUint64(m.Capabilities)
|
||||
}
|
||||
|
||||
// Decode deserializes InitializeResponse from the reader
|
||||
@@ -141,7 +159,10 @@ func (m *InitializeResponse) Decode(r *Reader) error {
|
||||
if m.Bytes, err = r.ReadBytes(); err != nil {
|
||||
return err
|
||||
}
|
||||
m.Timestamp, err = r.ReadInt64()
|
||||
if m.Timestamp, err = r.ReadInt64(); err != nil {
|
||||
return err
|
||||
}
|
||||
m.Capabilities, err = r.ReadUint64()
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -850,3 +871,41 @@ func (m *NewHTTPHandlerResponse) Decode(r *Reader) error {
|
||||
m.ServerAddr, err = r.ReadString()
|
||||
return err
|
||||
}
|
||||
|
||||
// SetQuasarFinalizedRequest carries a new Quasar (⅔-by-stake) EXPORT-FINAL height
|
||||
// from the node's consensus export-frontier observer to the VM (MsgSetQuasarFinalized).
|
||||
// The VM persists it; the response is empty.
|
||||
type SetQuasarFinalizedRequest struct {
|
||||
Height uint64
|
||||
}
|
||||
|
||||
// Encode serializes SetQuasarFinalizedRequest to the buffer
|
||||
func (m *SetQuasarFinalizedRequest) Encode(buf *Buffer) {
|
||||
buf.WriteUint64(m.Height)
|
||||
}
|
||||
|
||||
// Decode deserializes SetQuasarFinalizedRequest from the reader
|
||||
func (m *SetQuasarFinalizedRequest) Decode(r *Reader) error {
|
||||
var err error
|
||||
m.Height, err = r.ReadUint64()
|
||||
return err
|
||||
}
|
||||
|
||||
// QuasarHeightResponse carries the VM's current accept-tip-CLAMPED Quasar
|
||||
// EXPORT-FINAL height (MsgQuasarHeight) — 0 before the first export forms. The
|
||||
// MsgQuasarHeight request has no fields (empty payload).
|
||||
type QuasarHeightResponse struct {
|
||||
Height uint64
|
||||
}
|
||||
|
||||
// Encode serializes QuasarHeightResponse to the buffer
|
||||
func (m *QuasarHeightResponse) Encode(buf *Buffer) {
|
||||
buf.WriteUint64(m.Height)
|
||||
}
|
||||
|
||||
// Decode deserializes QuasarHeightResponse from the reader
|
||||
func (m *QuasarHeightResponse) Decode(r *Reader) error {
|
||||
var err error
|
||||
m.Height, err = r.ReadUint64()
|
||||
return err
|
||||
}
|
||||
|
||||
+10
@@ -75,6 +75,16 @@ const (
|
||||
MsgWarpGetPublicKey MessageType = 51
|
||||
MsgWarpBatchSign MessageType = 52
|
||||
|
||||
// Quasar EXPORT methods (60-63): the two-tier consensus (v1.36) export
|
||||
// frontier — Quasar = ⅔-by-stake, the reorg-safe finality a VM's
|
||||
// `finalized`/`safe` tags and cross-chain (warp) export gate must resolve
|
||||
// to instead of the reorgable Nova accept tip — carried across the plugin
|
||||
// process boundary. OPTIONAL: only a VM that advertises CapQuasarExport in
|
||||
// the Initialize handshake (see vm.go) is ever sent these; a generic VM is
|
||||
// never asked. Kept < 0x40 so the response/error flags OR in cleanly.
|
||||
MsgSetQuasarFinalized MessageType = 60
|
||||
MsgQuasarHeight MessageType = 61
|
||||
|
||||
// Response flag - set on response messages (bit 7 / high bit).
|
||||
// All message types must be < 64 (0x40) to allow OR with this flag
|
||||
// AND with MsgErrorFlag below.
|
||||
|
||||
Reference in New Issue
Block a user