agents/types/attestation.go
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
}