ceremonyclient/node/execution/intrinsics/token/token_conversions.go
Cassandra Heart dbd95bd9e9
v2.1.0 (#439)
* v2.1.0 [omit consensus and adjacent] - this commit will be amended with the full release after the file copy is complete

* 2.1.0 main node rollup
2025-09-30 02:48:15 -05:00

918 lines
22 KiB
Go

package token
import (
"math/big"
"github.com/pkg/errors"
"source.quilibrium.com/quilibrium/monorepo/protobufs"
"source.quilibrium.com/quilibrium/monorepo/types/crypto"
"source.quilibrium.com/quilibrium/monorepo/types/tries"
)
// FromProtobuf converts a protobuf Authority to intrinsics Authority
func AuthorityFromProtobuf(pb *protobufs.Authority) (*Authority, error) {
if pb == nil {
return nil, nil
}
return &Authority{
KeyType: crypto.KeyType(pb.KeyType),
PublicKey: pb.PublicKey,
CanBurn: pb.CanBurn,
}, nil
}
// ToProtobuf converts an intrinsics Authority to protobuf Authority
func (a *Authority) ToProtobuf() *protobufs.Authority {
if a == nil {
return nil
}
return &protobufs.Authority{
KeyType: uint32(a.KeyType),
PublicKey: a.PublicKey,
CanBurn: a.CanBurn,
}
}
// FromProtobuf converts a protobuf FeeBasis to intrinsics FeeBasis
func FeeBasisFromProtobuf(pb *protobufs.FeeBasis) (*FeeBasis, error) {
if pb == nil {
return nil, nil
}
baseline := new(big.Int)
if len(pb.Baseline) > 0 {
baseline.SetBytes(pb.Baseline)
}
return &FeeBasis{
Type: FeeBasisType(pb.Type),
Baseline: baseline,
}, nil
}
// ToProtobuf converts an intrinsics FeeBasis to protobuf FeeBasis
func (f *FeeBasis) ToProtobuf() *protobufs.FeeBasis {
if f == nil {
return nil
}
var baseline []byte
if f.Baseline != nil {
baseline = f.Baseline.Bytes()
}
return &protobufs.FeeBasis{
Type: protobufs.FeeBasisType(f.Type),
Baseline: baseline,
}
}
// FromProtobuf converts a protobuf TokenMintStrategy to intrinsics
// TokenMintStrategy
func TokenMintStrategyFromProtobuf(pb *protobufs.TokenMintStrategy) (
*TokenMintStrategy,
error,
) {
if pb == nil {
return nil, nil
}
authority, err := AuthorityFromProtobuf(pb.Authority)
if err != nil {
return nil, errors.Wrap(err, "converting authority")
}
feeBasis, err := FeeBasisFromProtobuf(pb.FeeBasis)
if err != nil {
return nil, errors.Wrap(err, "converting fee basis")
}
return &TokenMintStrategy{
MintBehavior: TokenMintBehavior(pb.MintBehavior),
ProofBasis: ProofBasisType(pb.ProofBasis),
VerkleRoot: pb.VerkleRoot,
Authority: authority,
PaymentAddress: pb.PaymentAddress,
FeeBasis: feeBasis,
}, nil
}
// ToProtobuf converts an intrinsics TokenMintStrategy to protobuf
// TokenMintStrategy
func (t *TokenMintStrategy) ToProtobuf() *protobufs.TokenMintStrategy {
if t == nil {
return nil
}
return &protobufs.TokenMintStrategy{
MintBehavior: protobufs.TokenMintBehavior(t.MintBehavior),
ProofBasis: protobufs.ProofBasisType(t.ProofBasis),
VerkleRoot: t.VerkleRoot,
Authority: t.Authority.ToProtobuf(),
PaymentAddress: t.PaymentAddress,
FeeBasis: t.FeeBasis.ToProtobuf(),
}
}
// FromProtobuf converts a protobuf TokenDeploy to intrinsics TokenDeploy
func TokenDeployFromProtobuf(
pb *protobufs.TokenDeploy,
) (*TokenDeploy, error) {
if pb == nil {
return nil, nil
}
config, err := TokenConfigurationFromProtobuf(pb.Config)
if err != nil {
return nil, errors.Wrap(err, "token deploy from protobuf")
}
return &TokenDeploy{
Config: config,
RDFSchema: pb.RdfSchema,
}, nil
}
// ToProtobuf converts an intrinsics TokenDeploy to protobuf TokenDeploy
func (
t *TokenDeploy,
) ToProtobuf() *protobufs.TokenDeploy {
if t == nil {
return nil
}
return &protobufs.TokenDeploy{
Config: t.Config.ToProtobuf(),
RdfSchema: t.RDFSchema,
}
}
// FromProtobuf converts a protobuf TokenUpdate to intrinsics TokenUpdate
func TokenUpdateFromProtobuf(
pb *protobufs.TokenUpdate,
) (*TokenUpdate, error) {
if pb == nil {
return nil, nil
}
config, err := TokenConfigurationFromProtobuf(pb.Config)
if err != nil {
return nil, errors.Wrap(err, "token update from protobuf")
}
return &TokenUpdate{
Config: config,
RDFSchema: pb.RdfSchema,
OwnerSignature: pb.PublicKeySignatureBls48581,
}, nil
}
// ToProtobuf converts an intrinsics TokenUpdate to protobuf TokenUpdate
func (
t *TokenUpdate,
) ToProtobuf() *protobufs.TokenUpdate {
if t == nil {
return nil
}
return &protobufs.TokenUpdate{
Config: t.Config.ToProtobuf(),
RdfSchema: t.RDFSchema,
PublicKeySignatureBls48581: t.OwnerSignature,
}
}
// FromProtobuf converts a protobuf TokenConfiguration to intrinsics
// TokenIntrinsicConfiguration
func TokenConfigurationFromProtobuf(pb *protobufs.TokenConfiguration) (
*TokenIntrinsicConfiguration,
error,
) {
if pb == nil {
return nil, nil
}
mintStrategy, err := TokenMintStrategyFromProtobuf(pb.MintStrategy)
if err != nil {
return nil, errors.Wrap(err, "converting mint strategy")
}
var units *big.Int
if len(pb.Units) > 0 {
units = new(big.Int).SetBytes(pb.Units)
}
var supply *big.Int
if len(pb.Supply) > 0 {
supply = new(big.Int).SetBytes(pb.Supply)
}
// Convert AdditionalReference from [][]byte to [64]byte
var additionalRef [64]byte
if len(pb.AdditionalReference) > 0 && len(pb.AdditionalReference[0]) > 0 {
copy(additionalRef[:], pb.AdditionalReference[0])
}
return &TokenIntrinsicConfiguration{
Behavior: TokenIntrinsicBehavior(pb.Behavior),
MintStrategy: mintStrategy,
Units: units,
Supply: supply,
Name: pb.Name,
Symbol: pb.Symbol,
AdditionalReference: additionalRef,
}, nil
}
// ToProtobuf converts an intrinsics TokenIntrinsicConfiguration to protobuf
// TokenConfiguration
func (
t *TokenIntrinsicConfiguration,
) ToProtobuf() *protobufs.TokenConfiguration {
if t == nil {
return nil
}
var units []byte
if t.Units != nil {
units = t.Units.Bytes()
}
var supply []byte
if t.Supply != nil {
supply = t.Supply.Bytes()
}
return &protobufs.TokenConfiguration{
Behavior: uint32(t.Behavior),
MintStrategy: t.MintStrategy.ToProtobuf(),
Units: units,
Supply: supply,
Name: t.Name,
Symbol: t.Symbol,
AdditionalReference: [][]byte{t.AdditionalReference[:]},
}
}
// FromProtobuf converts a protobuf RecipientBundle to intrinsics
// RecipientBundle
func RecipientBundleFromProtobuf(pb *protobufs.RecipientBundle) (
*RecipientBundle,
error,
) {
if pb == nil {
return nil, nil
}
// Validate field lengths
if len(pb.OneTimeKey) != 56 {
return nil, errors.Errorf(
"invalid OneTimeKey length: expected 56, got %d",
len(pb.OneTimeKey),
)
}
if len(pb.VerificationKey) != 56 {
return nil, errors.Errorf(
"invalid VerificationKey length: expected 56, got %d",
len(pb.VerificationKey),
)
}
if len(pb.CoinBalance) != 56 {
return nil, errors.Errorf(
"invalid CoinBalance length: expected 56, got %d",
len(pb.CoinBalance),
)
}
if len(pb.Mask) != 56 {
return nil, errors.Errorf(
"invalid Mask length: expected 56, got %d",
len(pb.Mask),
)
}
if len(pb.AdditionalReference) != 0 && len(pb.AdditionalReference) != 64 {
return nil, errors.Errorf(
"invalid AdditionalReference length: expected 0 or 64, got %d",
len(pb.AdditionalReference),
)
}
if len(pb.AdditionalReferenceKey) != 0 && len(pb.AdditionalReferenceKey) != 56 {
return nil, errors.Errorf(
"invalid AdditionalReferenceKey length: expected 0 or 56, got %d",
len(pb.AdditionalReferenceKey),
)
}
return &RecipientBundle{
OneTimeKey: pb.OneTimeKey,
VerificationKey: pb.VerificationKey,
CoinBalance: pb.CoinBalance,
Mask: pb.Mask,
AdditionalReference: pb.AdditionalReference,
AdditionalReferenceKey: pb.AdditionalReferenceKey,
}, nil
}
// ToProtobuf converts an intrinsics RecipientBundle to protobuf RecipientBundle
func (r *RecipientBundle) ToProtobuf() *protobufs.RecipientBundle {
if r == nil {
return nil
}
return &protobufs.RecipientBundle{
OneTimeKey: r.OneTimeKey,
VerificationKey: r.VerificationKey,
CoinBalance: r.CoinBalance,
Mask: r.Mask,
AdditionalReference: r.AdditionalReference,
AdditionalReferenceKey: r.AdditionalReferenceKey,
}
}
// FromProtobuf converts a protobuf TransactionInput to intrinsics
// TransactionInput
func TransactionInputFromProtobuf(pb *protobufs.TransactionInput) (
*TransactionInput,
error,
) {
if pb == nil {
return nil, nil
}
return &TransactionInput{
Commitment: pb.Commitment,
Signature: pb.Signature,
Proofs: pb.Proofs,
}, nil
}
// ToProtobuf converts an intrinsics TransactionInput to protobuf
// TransactionInput
func (t *TransactionInput) ToProtobuf() *protobufs.TransactionInput {
if t == nil {
return nil
}
return &protobufs.TransactionInput{
Commitment: t.Commitment,
Signature: t.Signature,
Proofs: t.Proofs,
}
}
// FromProtobuf converts a protobuf TransactionOutput to intrinsics
// TransactionOutput
func TransactionOutputFromProtobuf(pb *protobufs.TransactionOutput) (
*TransactionOutput,
error,
) {
if pb == nil {
return nil, nil
}
recipientOutput, err := RecipientBundleFromProtobuf(pb.RecipientOutput)
if err != nil {
return nil, errors.Wrap(err, "converting recipient output")
}
return &TransactionOutput{
FrameNumber: pb.FrameNumber,
Commitment: pb.Commitment,
RecipientOutput: *recipientOutput,
}, nil
}
// ToProtobuf converts an intrinsics TransactionOutput to protobuf
// TransactionOutput
func (t *TransactionOutput) ToProtobuf() *protobufs.TransactionOutput {
if t == nil {
return nil
}
return &protobufs.TransactionOutput{
FrameNumber: t.FrameNumber,
Commitment: t.Commitment,
RecipientOutput: t.RecipientOutput.ToProtobuf(),
}
}
// FromProtobuf converts a protobuf Transaction to intrinsics Transaction
func TransactionFromProtobuf(pb *protobufs.Transaction) (*Transaction, error) {
if pb == nil {
return nil, nil
}
// Convert domain from slice to array
var domain [32]byte
copy(domain[:], pb.Domain)
// Convert inputs
inputs := make([]*TransactionInput, len(pb.Inputs))
for i, input := range pb.Inputs {
converted, err := TransactionInputFromProtobuf(input)
if err != nil {
return nil, errors.Wrapf(err, "converting input %d", i)
}
inputs[i] = converted
}
// Convert outputs
outputs := make([]*TransactionOutput, len(pb.Outputs))
for i, output := range pb.Outputs {
converted, err := TransactionOutputFromProtobuf(output)
if err != nil {
return nil, errors.Wrapf(err, "converting output %d", i)
}
outputs[i] = converted
}
// Convert fees from [][]byte to []*big.Int
fees := make([]*big.Int, len(pb.Fees))
for i, fee := range pb.Fees {
fees[i] = new(big.Int).SetBytes(fee)
}
return &Transaction{
Domain: domain,
Inputs: inputs,
Outputs: outputs,
Fees: fees,
RangeProof: pb.RangeProof,
// Runtime dependencies will be injected separately
}, nil
}
// ToProtobuf converts an intrinsics Transaction to protobuf Transaction
func (t *Transaction) ToProtobuf() *protobufs.Transaction {
if t == nil {
return nil
}
// Convert inputs
inputs := make([]*protobufs.TransactionInput, len(t.Inputs))
for i, input := range t.Inputs {
inputs[i] = input.ToProtobuf()
}
// Convert outputs
outputs := make([]*protobufs.TransactionOutput, len(t.Outputs))
for i, output := range t.Outputs {
outputs[i] = output.ToProtobuf()
}
// Convert fees from []*big.Int to [][]byte
fees := make([][]byte, len(t.Fees))
for i, fee := range t.Fees {
if fee != nil {
fees[i] = fee.Bytes()
}
}
// Convert TraversalProof if present
var traversalProof *protobufs.TraversalProof
if t.TraversalProof != nil {
// Convert qcrypto.TraversalProof to protobufs.TraversalProof
traversalProof = TraversalProofToProtobuf(t.TraversalProof)
}
return &protobufs.Transaction{
Domain: t.Domain[:],
Inputs: inputs,
Outputs: outputs,
Fees: fees,
RangeProof: t.RangeProof,
TraversalProof: traversalProof,
}
}
// FromProtobuf converts a protobuf PendingTransactionInput to intrinsics
// PendingTransactionInput
func PendingTransactionInputFromProtobuf(
pb *protobufs.PendingTransactionInput,
) (*PendingTransactionInput, error) {
if pb == nil {
return nil, nil
}
return &PendingTransactionInput{
Commitment: pb.Commitment,
Signature: pb.Signature,
Proofs: pb.Proofs,
}, nil
}
// ToProtobuf converts an intrinsics PendingTransactionInput to protobuf
// PendingTransactionInput
func (
p *PendingTransactionInput,
) ToProtobuf() *protobufs.PendingTransactionInput {
if p == nil {
return nil
}
return &protobufs.PendingTransactionInput{
Commitment: p.Commitment,
Signature: p.Signature,
Proofs: p.Proofs,
}
}
// FromProtobuf converts a protobuf PendingTransactionOutput to intrinsics
// PendingTransactionOutput
func PendingTransactionOutputFromProtobuf(
pb *protobufs.PendingTransactionOutput,
) (*PendingTransactionOutput, error) {
if pb == nil {
return nil, nil
}
toOutput, err := RecipientBundleFromProtobuf(pb.To)
if err != nil {
return nil, errors.Wrap(err, "converting to output")
}
refundOutput, err := RecipientBundleFromProtobuf(pb.Refund)
if err != nil {
return nil, errors.Wrap(err, "converting refund output")
}
return &PendingTransactionOutput{
FrameNumber: pb.FrameNumber,
Commitment: pb.Commitment,
ToOutput: *toOutput,
RefundOutput: *refundOutput,
Expiration: pb.Expiration,
}, nil
}
// ToProtobuf converts an intrinsics PendingTransactionOutput to protobuf
// PendingTransactionOutput
func (
p *PendingTransactionOutput,
) ToProtobuf() *protobufs.PendingTransactionOutput {
if p == nil {
return nil
}
return &protobufs.PendingTransactionOutput{
FrameNumber: p.FrameNumber,
Commitment: p.Commitment,
To: p.ToOutput.ToProtobuf(),
Refund: p.RefundOutput.ToProtobuf(),
Expiration: p.Expiration,
}
}
// FromProtobuf converts a protobuf PendingTransaction to intrinsics
// PendingTransaction
func PendingTransactionFromProtobuf(pb *protobufs.PendingTransaction) (
*PendingTransaction,
error,
) {
if pb == nil {
return nil, nil
}
// Convert domain from slice to array
var domain [32]byte
copy(domain[:], pb.Domain)
// Convert inputs
inputs := make([]*PendingTransactionInput, len(pb.Inputs))
for i, input := range pb.Inputs {
converted, err := PendingTransactionInputFromProtobuf(input)
if err != nil {
return nil, errors.Wrapf(err, "converting input %d", i)
}
inputs[i] = converted
}
// Convert outputs
outputs := make([]*PendingTransactionOutput, len(pb.Outputs))
for i, output := range pb.Outputs {
converted, err := PendingTransactionOutputFromProtobuf(output)
if err != nil {
return nil, errors.Wrapf(err, "converting output %d", i)
}
outputs[i] = converted
}
// Convert fees from [][]byte to []*big.Int
fees := make([]*big.Int, len(pb.Fees))
for i, fee := range pb.Fees {
fees[i] = new(big.Int).SetBytes(fee)
}
return &PendingTransaction{
Domain: domain,
Inputs: inputs,
Outputs: outputs,
Fees: fees,
RangeProof: pb.RangeProof,
// Runtime dependencies will be injected separately
}, nil
}
// ToProtobuf converts an intrinsics PendingTransaction to protobuf
// PendingTransaction
func (p *PendingTransaction) ToProtobuf() *protobufs.PendingTransaction {
if p == nil {
return nil
}
// Convert inputs
inputs := make([]*protobufs.PendingTransactionInput, len(p.Inputs))
for i, input := range p.Inputs {
inputs[i] = input.ToProtobuf()
}
// Convert outputs
outputs := make([]*protobufs.PendingTransactionOutput, len(p.Outputs))
for i, output := range p.Outputs {
outputs[i] = output.ToProtobuf()
}
// Convert fees from []*big.Int to [][]byte
fees := make([][]byte, len(p.Fees))
for i, fee := range p.Fees {
if fee != nil {
fees[i] = fee.FillBytes(make([]byte, 32))
}
}
// Convert TraversalProof if present
var traversalProof *protobufs.TraversalProof
if p.TraversalProof != nil {
traversalProof = TraversalProofToProtobuf(p.TraversalProof)
}
return &protobufs.PendingTransaction{
Domain: p.Domain[:],
Inputs: inputs,
Outputs: outputs,
Fees: fees,
RangeProof: p.RangeProof,
TraversalProof: traversalProof,
}
}
// FromProtobuf converts a protobuf MintTransactionInput to intrinsics
// MintTransactionInput
func MintTransactionInputFromProtobuf(pb *protobufs.MintTransactionInput) (
*MintTransactionInput,
error,
) {
if pb == nil {
return nil, nil
}
// Convert value from bytes to big.Int
value := new(big.Int)
if len(pb.Value) > 0 {
value.SetBytes(pb.Value)
}
return &MintTransactionInput{
Value: value,
Commitment: pb.Commitment,
Signature: pb.Signature,
Proofs: pb.Proofs,
AdditionalReference: pb.AdditionalReference,
AdditionalReferenceKey: pb.AdditionalReferenceKey,
}, nil
}
// ToProtobuf converts an intrinsics MintTransactionInput to protobuf
// MintTransactionInput
func (m *MintTransactionInput) ToProtobuf() *protobufs.MintTransactionInput {
if m == nil {
return nil
}
var valueBytes []byte
if m.Value != nil {
valueBytes = m.Value.Bytes()
}
return &protobufs.MintTransactionInput{
Value: valueBytes,
Commitment: m.Commitment,
Signature: m.Signature,
Proofs: m.Proofs,
AdditionalReference: m.AdditionalReference,
AdditionalReferenceKey: m.AdditionalReferenceKey,
}
}
// FromProtobuf converts a protobuf MintTransactionOutput to intrinsics
// MintTransactionOutput
func MintTransactionOutputFromProtobuf(pb *protobufs.MintTransactionOutput) (
*MintTransactionOutput,
error,
) {
if pb == nil {
return nil, nil
}
recipientOutput, err := RecipientBundleFromProtobuf(pb.RecipientOutput)
if err != nil {
return nil, errors.Wrap(err, "converting recipient output")
}
return &MintTransactionOutput{
FrameNumber: pb.FrameNumber,
Commitment: pb.Commitment,
RecipientOutput: *recipientOutput,
}, nil
}
// ToProtobuf converts an intrinsics MintTransactionOutput to protobuf
// MintTransactionOutput
func (m *MintTransactionOutput) ToProtobuf() *protobufs.MintTransactionOutput {
if m == nil {
return nil
}
return &protobufs.MintTransactionOutput{
FrameNumber: m.FrameNumber,
Commitment: m.Commitment,
RecipientOutput: m.RecipientOutput.ToProtobuf(),
}
}
// FromProtobuf converts a protobuf MintTransaction to intrinsics
// MintTransaction
func MintTransactionFromProtobuf(pb *protobufs.MintTransaction) (
*MintTransaction,
error,
) {
if pb == nil {
return nil, nil
}
// Convert domain from slice to array
var domain [32]byte
copy(domain[:], pb.Domain)
// Convert inputs
inputs := make([]*MintTransactionInput, len(pb.Inputs))
for i, input := range pb.Inputs {
converted, err := MintTransactionInputFromProtobuf(input)
if err != nil {
return nil, errors.Wrapf(err, "converting input %d", i)
}
inputs[i] = converted
}
// Convert outputs
outputs := make([]*MintTransactionOutput, len(pb.Outputs))
for i, output := range pb.Outputs {
converted, err := MintTransactionOutputFromProtobuf(output)
if err != nil {
return nil, errors.Wrapf(err, "converting output %d", i)
}
outputs[i] = converted
}
// Convert fees from [][]byte to []*big.Int
fees := make([]*big.Int, len(pb.Fees))
for i, fee := range pb.Fees {
fees[i] = new(big.Int).SetBytes(fee)
}
return &MintTransaction{
Domain: domain,
Inputs: inputs,
Outputs: outputs,
Fees: fees,
RangeProof: pb.RangeProof,
// Runtime dependencies will be injected separately
}, nil
}
// ToProtobuf converts an intrinsics MintTransaction to protobuf MintTransaction
func (m *MintTransaction) ToProtobuf() *protobufs.MintTransaction {
if m == nil {
return nil
}
// Convert inputs
inputs := make([]*protobufs.MintTransactionInput, len(m.Inputs))
for i, input := range m.Inputs {
inputs[i] = input.ToProtobuf()
}
// Convert outputs
outputs := make([]*protobufs.MintTransactionOutput, len(m.Outputs))
for i, output := range m.Outputs {
outputs[i] = output.ToProtobuf()
}
// Convert fees from []*big.Int to [][]byte
fees := make([][]byte, len(m.Fees))
for i, fee := range m.Fees {
if fee != nil {
fees[i] = fee.Bytes()
}
}
return &protobufs.MintTransaction{
Domain: m.Domain[:],
Inputs: inputs,
Outputs: outputs,
Fees: fees,
RangeProof: m.RangeProof,
// Note: MintProof is not available in intrinsics structure
}
}
// TraversalProofToProtobuf converts qcrypto.TraversalProof to
// protobufs.TraversalProof
func TraversalProofToProtobuf(
tp *tries.TraversalProof,
) *protobufs.TraversalProof {
if tp == nil {
return nil
}
// Convert Multiproof
var multiproof *protobufs.Multiproof
if tp.Multiproof != nil {
multiproofBytes, _ := tp.Multiproof.ToBytes()
// Split the bytes - assuming first part is multicommitment, rest is proof
// This needs to match how the Multiproof is serialized
if len(multiproofBytes) > 0 {
multiproof = &protobufs.Multiproof{
Multicommitment: multiproofBytes[:min(74, len(multiproofBytes))],
Proof: multiproofBytes[min(74, len(multiproofBytes)):],
}
}
}
// Convert SubProofs
var subProofs []*protobufs.TraversalSubProof
for _, sp := range tp.SubProofs {
// Convert paths from [][]uint64 to []*protobufs.Path
var paths []*protobufs.Path
for _, path := range sp.Paths {
paths = append(paths, &protobufs.Path{
Indices: path,
})
}
subProofs = append(subProofs, &protobufs.TraversalSubProof{
Commits: sp.Commits,
Ys: sp.Ys,
Paths: paths,
})
}
return &protobufs.TraversalProof{
Multiproof: multiproof,
SubProofs: subProofs,
}
}
// TraversalProofFromProtobuf converts protobufs.TraversalProof to
// qcrypto.TraversalProof
func TraversalProofFromProtobuf(
pb *protobufs.TraversalProof,
inclusionProver crypto.InclusionProver,
) (*tries.TraversalProof, error) {
if pb == nil {
return nil, nil
}
tp := &tries.TraversalProof{}
// Convert Multiproof if present
if pb.Multiproof != nil && inclusionProver != nil {
mp := inclusionProver.NewMultiproof()
// Reconstruct the multiproof from its components
multiproofBytes := append(
pb.Multiproof.Multicommitment,
pb.Multiproof.Proof...,
)
if err := mp.FromBytes(multiproofBytes); err != nil {
return nil, errors.Wrap(err, "deserializing multiproof")
}
tp.Multiproof = mp
}
// Convert SubProofs
for _, pbSubProof := range pb.SubProofs {
// Convert paths from []*protobufs.Path to [][]uint64
var paths [][]uint64
for _, path := range pbSubProof.Paths {
paths = append(paths, path.Indices)
}
tp.SubProofs = append(tp.SubProofs, tries.TraversalSubProof{
Commits: pbSubProof.Commits,
Ys: pbSubProof.Ys,
Paths: paths,
})
}
return tp, nil
}