synapsecns/sanguine

View on GitHub
agents/types/proof.go

Summary

Maintainability
A
0 mins
Test Coverage
package types

import (
    "bytes"
    "encoding/gob"
    "fmt"
    "github.com/ethereum/go-ethereum/common"
)

// Proof is a merkle proof object. The leaf it's path to the root and its index in the tree.
type Proof interface {
    // Leaf is the leaf in the proof
    Leaf() common.Hash
    // Index is the index in the tree
    Index() uint32
    // Path is the merkle branch
    Path() common.Hash
    // Encode encodes a message
    Encode() ([]byte, error)
}

// proofImpl implements the merkle proof.
type proofImpl struct {
    leaf  common.Hash
    index uint32
    path  common.Hash
}

// ProofEncoder is exported to allow proofs to be encoded/deoded from binary.
type ProofEncoder struct {
    Leaf  common.Hash
    Index uint32
    Path  common.Hash
}

// NewProof creates a new merkle proof.
func NewProof(leaf common.Hash, index uint32, path common.Hash) Proof {
    return proofImpl{
        leaf:  leaf,
        index: index,
        path:  path,
    }
}

// DecodeProof decodes a proof.
func DecodeProof(rawProof []byte) (Proof, error) {
    dec := gob.NewDecoder(bytes.NewReader(rawProof))

    var proofEncoder ProofEncoder
    err := dec.Decode(&proofEncoder)
    if err != nil {
        return nil, fmt.Errorf("could not decode proof: %w", err)
    }

    return proofImpl{
        leaf:  proofEncoder.Leaf,
        index: proofEncoder.Index,
        path:  proofEncoder.Path,
    }, nil
}

func (p proofImpl) Leaf() common.Hash {
    return p.leaf
}

func (p proofImpl) Index() uint32 {
    return p.index
}

func (p proofImpl) Path() common.Hash {
    return p.path
}

func (p proofImpl) Encode() ([]byte, error) {
    var res bytes.Buffer
    enc := gob.NewEncoder(&res)

    proofEncoder := ProofEncoder{
        Leaf:  p.leaf,
        Index: p.index,
        Path:  p.path,
    }

    err := enc.Encode(proofEncoder)
    if err != nil {
        return nil, fmt.Errorf("could not encode %T: %w", p, err)
    }
    return res.Bytes(), nil
}