wire: export AppendTransferable{Out,In} + TransferableXFromObject

So node ExportTx/ImportTx nest their extra outs/ins as native object-ptr lists
the SAME way XVMBaseTx does — one way to nest a transferable, no standalone
envelope. XVMBaseTx switched to the exported names internally.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
This commit is contained in:
zeekay
2026-07-14 06:35:46 -07:00
co-authored by Hanzo Dev
parent b1055294a2
commit 40d500f6dd
2 changed files with 23 additions and 7 deletions
+21 -5
View File
@@ -47,6 +47,15 @@ func transferableOutAt(msg *zap.Message, obj zap.Object) TransferableOut {
return TransferableOut{msg: msg, obj: obj}
}
// TransferableOutFromObject wraps a nested TransferableOut object reached from
// a parent AddObjectPtr list slot (e.g. ExportTx's ExportedOuts list). msg is
// the parent message (obj.Message()); obj is the list element from
// List.ObjectPtr. This is the exported reader every native-nested carrier of
// TransferableOut objects uses — one way to read a nested transferable.
func TransferableOutFromObject(msg *zap.Message, obj zap.Object) TransferableOut {
return TransferableOut{msg: msg, obj: obj}
}
// AssetID returns the asset identifier this output moves.
func (t TransferableOut) AssetID() ids.ID {
return ids.ID(t.obj.BytesFixedSlice(OffsetTransferableOut_AssetID, 32))
@@ -98,6 +107,12 @@ func transferableInAt(msg *zap.Message, obj zap.Object) TransferableIn {
return TransferableIn{msg: msg, obj: obj}
}
// TransferableInFromObject wraps a nested TransferableIn object reached from a
// parent AddObjectPtr list slot (e.g. ImportTx's ImportedIns list).
func TransferableInFromObject(msg *zap.Message, obj zap.Object) TransferableIn {
return TransferableIn{msg: msg, obj: obj}
}
// TxID returns the spent UTXO's tx id.
func (t TransferableIn) TxID() ids.ID {
return ids.ID(t.obj.BytesFixedSlice(OffsetTransferableIn_TxID, 32))
@@ -136,19 +151,20 @@ func (t TransferableIn) IsZero() bool { return t.msg == nil }
// ---- inline builders (write a Transferable object into an open builder) ----
// appendTransferableOut writes a TransferableOut object into b and returns its
// AppendTransferableOut writes a TransferableOut object into b and returns its
// offset (for an AddObjectPtr slot). The inner fx Output envelope bytes are
// stored zero-copy in the Output field.
func appendTransferableOut(b *zap.Builder, assetID ids.ID, innerEnvelope []byte) int {
// stored zero-copy in the Output field. Exported so any native-nested carrier
// (XVMBaseTx here, ExportTx in node) nests a transferable ONE way.
func AppendTransferableOut(b *zap.Builder, assetID ids.ID, innerEnvelope []byte) int {
ob := b.StartObject(SizeTransferableOut)
ob.SetBytesFixed(OffsetTransferableOut_AssetID, assetID[:])
ob.SetBytes(OffsetTransferableOut_Output, innerEnvelope)
return ob.Finish()
}
// appendTransferableIn writes a TransferableIn object into b and returns its
// AppendTransferableIn writes a TransferableIn object into b and returns its
// offset.
func appendTransferableIn(b *zap.Builder, txID ids.ID, outputIndex uint32, assetID ids.ID, innerEnvelope []byte) int {
func AppendTransferableIn(b *zap.Builder, txID ids.ID, outputIndex uint32, assetID ids.ID, innerEnvelope []byte) int {
ob := b.StartObject(SizeTransferableIn)
ob.SetBytesFixed(OffsetTransferableIn_TxID, txID[:])
ob.SetUint32(OffsetTransferableIn_OutputIndex, outputIndex)
+2 -2
View File
@@ -160,11 +160,11 @@ func NewXVMBaseTx(in XVMBaseTxInput) []byte {
// 1. tail each Transferable object; collect absolute offsets.
outOffs := make([]int, len(in.Outs))
for i := range in.Outs {
outOffs[i] = appendTransferableOut(b, in.Outs[i].AssetID, in.Outs[i].Output)
outOffs[i] = AppendTransferableOut(b, in.Outs[i].AssetID, in.Outs[i].Output)
}
inOffs := make([]int, len(in.Ins))
for i := range in.Ins {
inOffs[i] = appendTransferableIn(b, in.Ins[i].TxID, in.Ins[i].OutputIndex, in.Ins[i].AssetID, in.Ins[i].Input)
inOffs[i] = AppendTransferableIn(b, in.Ins[i].TxID, in.Ins[i].OutputIndex, in.Ins[i].AssetID, in.Ins[i].Input)
}
// 2. object-ptr lists over those offsets.