mirror of
https://github.com/QuilibriumNetwork/ceremonyclient.git
synced 2026-02-21 18:37:26 +08:00
* v2.1.0.2 * restore tweaks to simlibp2p * fix: nil ref on size calc * fix: panic should induce shutdown from event_distributor * fix: friendlier initialization that requires less manual kickstarting for test/devnets * fix: fewer available shards than provers should choose shard length * fix: update stored worker registry, improve logging for debug mode * fix: shut the fuck up, peer log * qol: log value should be snake cased * fix:non-archive snap sync issues * fix: separate X448/Decaf448 signed keys, add onion key to registry * fix: overflow arithmetic on frame number comparison * fix: worker registration should be idempotent if inputs are same, otherwise permit updated records * fix: remove global prover state from size calculation * fix: divide by zero case * fix: eager prover * fix: broadcast listener default * qol: diagnostic data for peer authenticator * fix: master/worker connectivity issue in sparse networks tight coupling of peer and workers can sometimes interfere if mesh is sparse, so give workers a pseudoidentity but publish messages with the proper peer key * fix: reorder steps of join creation * fix: join verify frame source + ensure domain is properly padded (unnecessary but good for consistency) * fix: add delegate to protobuf <-> reified join conversion * fix: preempt prover from planning with no workers * fix: use the unallocated workers to generate a proof * qol: underflow causes join fail in first ten frames on test/devnets * qol: small logging tweaks for easier log correlation in debug mode * qol: use fisher-yates shuffle to ensure prover allocations are evenly distributed when scores are equal * qol: separate decisional logic on post-enrollment confirmation into consensus engine, proposer, and worker manager where relevant, refactor out scoring * reuse shard descriptors for both join planning and confirm/reject decisions * fix: add missing interface method and amend test blossomsub to use new peer id basis * fix: only check allocations if they exist * fix: pomw mint proof data needs to be hierarchically under global intrinsic domain * staging temporary state under diagnostics * fix: first phase of distributed lock refactoring * fix: compute intrinsic locking * fix: hypergraph intrinsic locking * fix: token intrinsic locking * fix: update execution engines to support new locking model * fix: adjust tests with new execution shape * fix: weave in lock/unlock semantics to liveness provider * fix lock fallthrough, add missing allocation update * qol: additional logging for diagnostics, also testnet/devnet handling for confirmations * fix: establish grace period on halt scenario to permit recovery * fix: support test/devnet defaults for coverage scenarios * fix: nil ref on consensus halts for non-archive nodes * fix: remove unnecessary prefix from prover ref * add test coverage for fork choice behaviors and replay – once passing, blocker (2) is resolved * fix: no fork replay on repeat for non-archive nodes, snap now behaves correctly * rollup of pre-liveness check lock interactions * ahead of tests, get the protobuf/metrics-related changes out so teams can prepare * add test coverage for distributed lock behaviors – once passing, blocker (3) is resolved * fix: blocker (3) * Dev docs improvements (#445) * Make install deps script more robust * Improve testing instructions * Worker node should stop upon OS SIGINT/SIGTERM signal (#447) * move pebble close to Stop() * move deferred Stop() to Start() * add core id to worker stop log message * create done os signal channel and stop worker upon message to it --------- Co-authored-by: Cassandra Heart <7929478+CassOnMars@users.noreply.github.com> --------- Co-authored-by: Daz <daz_the_corgi@proton.me> Co-authored-by: Black Swan <3999712+blacks1ne@users.noreply.github.com>
936 lines
23 KiB
Go
936 lines
23 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,
|
|
inclusionProver crypto.InclusionProver,
|
|
) (*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)
|
|
}
|
|
|
|
proof, err := TraversalProofFromProtobuf(pb.TraversalProof, inclusionProver)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &Transaction{
|
|
Domain: domain,
|
|
Inputs: inputs,
|
|
Outputs: outputs,
|
|
Fees: fees,
|
|
RangeProof: pb.RangeProof,
|
|
TraversalProof: proof,
|
|
// 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,
|
|
inclusionProver crypto.InclusionProver,
|
|
) (
|
|
*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)
|
|
}
|
|
|
|
proof, err := TraversalProofFromProtobuf(pb.TraversalProof, inclusionProver)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &PendingTransaction{
|
|
Domain: domain,
|
|
Inputs: inputs,
|
|
Outputs: outputs,
|
|
Fees: fees,
|
|
RangeProof: pb.RangeProof,
|
|
TraversalProof: proof,
|
|
// 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
|
|
}
|