github.com/ethereum-optimism/optimism@v1.7.2/op-node/p2p/signer.go (about)

     1  package p2p
     2  
     3  import (
     4  	"context"
     5  	"crypto/ecdsa"
     6  	"errors"
     7  	"io"
     8  	"math/big"
     9  
    10  	"github.com/ethereum/go-ethereum/common"
    11  	"github.com/ethereum/go-ethereum/crypto"
    12  
    13  	"github.com/ethereum-optimism/optimism/op-node/rollup"
    14  )
    15  
    16  var SigningDomainBlocksV1 = [32]byte{}
    17  
    18  type Signer interface {
    19  	Sign(ctx context.Context, domain [32]byte, chainID *big.Int, encodedMsg []byte) (sig *[65]byte, err error)
    20  	io.Closer
    21  }
    22  
    23  func SigningHash(domain [32]byte, chainID *big.Int, payloadBytes []byte) (common.Hash, error) {
    24  	var msgInput [32 + 32 + 32]byte
    25  	// domain: first 32 bytes
    26  	copy(msgInput[:32], domain[:])
    27  	// chain_id: second 32 bytes
    28  	if chainID.BitLen() > 256 {
    29  		return common.Hash{}, errors.New("chain_id is too large")
    30  	}
    31  	chainID.FillBytes(msgInput[32:64])
    32  	// payload_hash: third 32 bytes, hash of encoded payload
    33  	copy(msgInput[64:], crypto.Keccak256(payloadBytes))
    34  
    35  	return crypto.Keccak256Hash(msgInput[:]), nil
    36  }
    37  
    38  func BlockSigningHash(cfg *rollup.Config, payloadBytes []byte) (common.Hash, error) {
    39  	return SigningHash(SigningDomainBlocksV1, cfg.L2ChainID, payloadBytes)
    40  }
    41  
    42  // LocalSigner is suitable for testing
    43  type LocalSigner struct {
    44  	priv   *ecdsa.PrivateKey
    45  	hasher func(domain [32]byte, chainID *big.Int, payloadBytes []byte) (common.Hash, error)
    46  }
    47  
    48  func NewLocalSigner(priv *ecdsa.PrivateKey) *LocalSigner {
    49  	return &LocalSigner{priv: priv, hasher: SigningHash}
    50  }
    51  
    52  func (s *LocalSigner) Sign(ctx context.Context, domain [32]byte, chainID *big.Int, encodedMsg []byte) (sig *[65]byte, err error) {
    53  	if s.priv == nil {
    54  		return nil, errors.New("signer is closed")
    55  	}
    56  	signingHash, err := s.hasher(domain, chainID, encodedMsg)
    57  	if err != nil {
    58  		return nil, err
    59  	}
    60  	signature, err := crypto.Sign(signingHash[:], s.priv)
    61  	if err != nil {
    62  		return nil, err
    63  	}
    64  	return (*[65]byte)(signature), nil
    65  }
    66  
    67  func (s *LocalSigner) Close() error {
    68  	s.priv = nil
    69  	return nil
    70  }
    71  
    72  type PreparedSigner struct {
    73  	Signer
    74  }
    75  
    76  func (p *PreparedSigner) SetupSigner(ctx context.Context) (Signer, error) {
    77  	return p.Signer, nil
    78  }
    79  
    80  type SignerSetup interface {
    81  	SetupSigner(ctx context.Context) (Signer, error)
    82  }