synapsecns/sanguine

View on GitHub
agents/types/attestation.go

Summary

Maintainability
A
1 hr
Test Coverage
package types

import (
    "context"
    "math/big"

    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/crypto"
    "github.com/synapsecns/sanguine/ethergo/signer/signer"
)

const (
    attestationOffsetRoot        = 0
    attestationOffsetDataHash    = 32
    attestationOffsetNonce       = 64
    attestationOffsetBlockNumber = 68
    attestationOffsetTimestamp   = 73
    attestationSize              = 78
)

// Attestation is the attestation interface.
type Attestation interface {
    Encoder
    // SnapshotRoot is the root of the Snapshot Merkle Tree.
    SnapshotRoot() [32]byte
    // DataHash is the agent root and SnapGasHash combined into a single hash.
    DataHash() [32]byte
    // Nonce is the attestation nonce.
    Nonce() uint32
    // BlockNumber is the block number when the attestation was created in Summit.
    BlockNumber() *big.Int
    // Timestamp is the timestamp when the attestation was created in Summit.
    Timestamp() *big.Int
    // SignAttestation signs the attestation
    SignAttestation(ctx context.Context, signer signer.Signer, valid bool) (signer.Signature, []byte, common.Hash, error)
}

type attestation struct {
    snapshotRoot [32]byte
    dataHash     [32]byte
    nonce        uint32
    blockNumber  *big.Int
    timestamp    *big.Int
}

// NewAttestation creates a new attestation.
func NewAttestation(snapshotRoot [32]byte, dataHash [32]byte, nonce uint32, blockNumber *big.Int, timestamp *big.Int) Attestation {
    return &attestation{
        snapshotRoot: snapshotRoot,
        dataHash:     dataHash,
        nonce:        nonce,
        blockNumber:  blockNumber,
        timestamp:    timestamp,
    }
}

func (a attestation) SnapshotRoot() [32]byte {
    return a.snapshotRoot
}

func (a attestation) DataHash() [32]byte {
    return a.dataHash
}

func (a attestation) Nonce() uint32 {
    return a.nonce
}

func (a attestation) BlockNumber() *big.Int {
    return a.blockNumber
}

func (a attestation) Timestamp() *big.Int {
    return a.timestamp
}

func (a attestation) SignAttestation(ctx context.Context, signer signer.Signer, valid bool) (signer.Signature, []byte, common.Hash, error) {
    var attestationSalt string
    if valid {
        attestationSalt = AttestationValidSalt
    } else {
        attestationSalt = AttestationInvalidSalt
    }
    return signEncoder(ctx, signer, a, attestationSalt)
}

// GetAttestationDataHash generates the data hash from the agent root and SnapGasHash.
func GetAttestationDataHash(agentRoot [32]byte, snapGasHash [32]byte) [32]byte {
    concatenatedBytes := append(agentRoot[:], snapGasHash[:]...)
    dataHash := crypto.Keccak256(concatenatedBytes)

    var dataHashB32 [32]byte
    copy(dataHashB32[:], dataHash)

    return dataHashB32
}