Files
scroll/common/message/message.go
2022-11-22 09:47:43 +08:00

135 lines
3.7 KiB
Go

package message
import (
"crypto/ecdsa"
"encoding/binary"
"encoding/json"
"github.com/scroll-tech/go-ethereum/common"
"github.com/scroll-tech/go-ethereum/core/types"
"github.com/scroll-tech/go-ethereum/crypto"
"golang.org/x/crypto/blake2s"
)
// MsgType denotes the type of message being sent or received.
type MsgType uint16
const (
// ErrorMsgType error type of message.
ErrorMsgType MsgType = iota
// RegisterMsgType register type of message, sent by a roller when a connection is established.
RegisterMsgType
// TaskMsgType task type of message, sent by a sequencer to a roller to notify them
// they need to generate a proof.
TaskMsgType
// ProofMsgType proof type of message, sent by a roller to a sequencer when they have finished
// proof generation of a given set of block traces.
ProofMsgType
)
// RespStatus is the status of the proof generation
type RespStatus uint32
const (
// StatusOk indicates the proof generation succeeded
StatusOk RespStatus = iota
// StatusProofError indicates the proof generation failed
StatusProofError
)
// Msg is the top-level message container which contains the payload and the
// message identifier.
type Msg struct {
// Message type
Type MsgType `json:"type"`
// Message payload
Payload []byte `json:"payload"`
}
// AuthMessage is the first message exchanged from the Roller to the Sequencer.
// It effectively acts as a registration, and makes the Roller identification
// known to the Sequencer.
type AuthMessage struct {
// Message fields
Identity Identity `json:"message"`
// Roller signature
Signature string `json:"signature"`
}
// Identity contains all the fields to be signed by the roller.
type Identity struct {
// Roller name
Name string `json:"name"`
// Time of message creation
Timestamp int64 `json:"timestamp"`
// Roller public key
PublicKey string `json:"publicKey"`
// Version is common.Version+ZK_VERSION. Use the following to check the latest ZK_VERSION version.
// curl -sL https://api.github.com/repos/scroll-tech/common-rs/commits | jq -r ".[0].sha"
Version string `json:"version"`
}
// Sign auth message
func (a *AuthMessage) Sign(priv *ecdsa.PrivateKey) error {
// Hash identity content
hash, err := a.Identity.Hash()
if err != nil {
return err
}
// Sign register message
sig, err := crypto.Sign(hash, priv)
if err != nil {
return err
}
a.Signature = common.Bytes2Hex(sig)
return nil
}
// Hash returns the hash of the auth message, which should be the message used
// to construct the Signature.
func (i *Identity) Hash() ([]byte, error) {
bs, err := json.Marshal(i)
if err != nil {
return nil, err
}
hash := blake2s.Sum256(bs)
return hash[:], nil
}
// TaskMsg is a wrapper type around db ProveTask type.
type TaskMsg struct {
ID string `json:"id"`
Traces []*types.BlockTrace `json:"blockTraces"`
}
// ProofMsg is the message received from rollers that contains zk proof, the status of
// the proof generation succeeded, and an error message if proof generation failed.
type ProofMsg struct {
Status RespStatus `json:"status"`
Error string `json:"error,omitempty"`
ID string `json:"id"`
// FIXME: Maybe we need to allow Proof omitempty
Proof *AggProof `json:"proof"`
}
// AggProof includes the proof and public input that are required to verification and rollup.
type AggProof struct {
Proof []byte `json:"proof"`
Instance []byte `json:"instance"`
FinalPair []byte `json:"final_pair"`
Vk []byte `json:"vk"`
}
// Marshal marshals the TraceProof as bytes
func (proof *AggProof) Marshal() ([]byte, error) {
jsonByt, err := json.Marshal(proof)
if err != nil {
return nil, err
}
buf := make([]byte, 4)
binary.BigEndian.PutUint32(buf, uint32(len(jsonByt)))
return append(buf, jsonByt...), nil
}