Documentation ¶
Index ¶
- Constants
- Variables
- func ConvertChainIdToReadinessSyncing(chainID vaa.ChainID) (readiness.Component, error)
- func DecryptAESGCM(data, key []byte) ([]byte, error)
- func EncryptAESGCM(plaintext, key []byte) ([]byte, error)
- func GetOrCreateNodeKey(logger *zap.Logger, path string) (crypto.PrivKey, error)
- func LoadArmoredKey(filename string, blockType string, unsafeDevMode bool) (*ecdsa.PrivateKey, error)
- func LoadGuardianKey(filename string, unsafeDevMode bool) (*ecdsa.PrivateKey, error)
- func LockMemory()
- func MustConvertChainIdToReadinessSyncing(chainID vaa.ChainID) readiness.Component
- func MustRegisterReadinessSyncing(chainID vaa.ChainID)
- func NewInstrumentedGRPCServer(logger *zap.Logger, rpcLogDetail GrpcLogDetail) *grpc.Server
- func PostMsgWithTimestamp[T any](msg *T, c chan<- *MsgWithTimeStamp[T]) error
- func PostObservationRequest(obsvReqSendC chan<- *gossipv1.ObservationRequest, ...) error
- func RunWithScissors(ctx context.Context, errC chan error, name string, ...)
- func SetRestrictiveUmask()
- func StartRunnable(ctx context.Context, errC chan error, catchPanics bool, name string, ...)
- func WrapWithScissors(runnable supervisor.Runnable, name string) supervisor.Runnable
- func WriteArmoredKey(key *ecdsa.PrivateKey, description string, filename string, blockType string, ...) error
- type Environment
- type GrpcLogDetail
- type GuardianSet
- type GuardianSetState
- func (st *GuardianSetState) Cleanup()
- func (st *GuardianSetState) Get() *GuardianSet
- func (st *GuardianSetState) GetAll() map[common.Address]map[peer.ID]*gossipv1.Heartbeat
- func (st *GuardianSetState) LastHeartbeat(addr common.Address) map[peer.ID]*gossipv1.Heartbeat
- func (st *GuardianSetState) Set(set *GuardianSet)
- func (st *GuardianSetState) SetHeartbeat(addr common.Address, peerId peer.ID, hb *gossipv1.Heartbeat) error
- type MessagePublication
- func (msg *MessagePublication) CreateDigest() string
- func (msg *MessagePublication) CreateVAA(gsIndex uint32) *vaa.VAA
- func (msg *MessagePublication) Marshal() ([]byte, error)
- func (msg *MessagePublication) MarshalJSON() ([]byte, error)
- func (msg *MessagePublication) MessageID() []byte
- func (msg *MessagePublication) MessageIDString() string
- func (msg *MessagePublication) UnmarshalJSON(data []byte) error
- func (msg *MessagePublication) ZapFields(fields ...zap.Field) []zap.Field
- type MsgWithTimeStamp
Constants ¶
const ( ReadinessEthSyncing readiness.Component = "ethSyncing" ReadinessIBCSyncing readiness.Component = "IBCSyncing" )
const AddressLength = 32
const (
GuardianKeyArmoredBlock = "WORMHOLE GUARDIAN PRIVATE KEY"
)
const HashLength = 32
const MaxGuardianCount = 19
MaxGuardianCount specifies the maximum number of guardians supported by on-chain contracts.
Matching constants:
- MAX_LEN_GUARDIAN_KEYS in Solana contract (limited by transaction size - 19 is the maximum amount possible)
The Eth and Terra contracts do not specify a maximum number and support more than that, but presumably, chain-specific transaction size limits will apply at some point (untested).
const MaxNodesPerGuardian = 15
MaxNodesPerGuardian specifies the maximum amount of nodes per guardian key that we'll accept whenever we maintain any per-guardian, per-node state.
There currently isn't any state clean up, so the value is on the high side to prevent accidentally reaching the limit due to operational mistakes.
const MaxStateAge = 1 * time.Minute
MaxStateAge specified the maximum age of state entries in seconds. Expired entries are purged from the state by Cleanup().
Variables ¶
var ( ScissorsErrorsCaught = promauto.NewCounterVec( prometheus.CounterOpts{ Name: "scissor_errors_caught", Help: "Total number of unhandled errors caught", }, []string{"name"}) ScissorsPanicsCaught = promauto.NewCounterVec( prometheus.CounterOpts{ Name: "scissor_panics_caught", Help: "Total number of panics caught", }, []string{"name"}) )
var ErrChanFull = errors.New("channel is full")
Functions ¶
func ConvertChainIdToReadinessSyncing ¶
ConvertChainIdToReadinessSyncing maps a chain ID to a readiness syncing value. It returns an error if the chain ID is invalid.
func DecryptAESGCM ¶
func EncryptAESGCM ¶
func GetOrCreateNodeKey ¶
func LoadArmoredKey ¶
func LoadArmoredKey(filename string, blockType string, unsafeDevMode bool) (*ecdsa.PrivateKey, error)
LoadArmoredKey loads a serialized key from disk.
func LoadGuardianKey ¶
func LoadGuardianKey(filename string, unsafeDevMode bool) (*ecdsa.PrivateKey, error)
LoadGuardianKey loads a serialized guardian key from disk.
func LockMemory ¶
func LockMemory()
LockMemory locks current and future pages in memory to protect secret keys from being swapped out to disk. It's possible (and strongly recommended) to deploy Wormhole such that keys are only ever stored in memory and never touch the disk. This is a privileged operation and requires CAP_IPC_LOCK.
func MustConvertChainIdToReadinessSyncing ¶
MustConvertChainIdToReadinessSyncing maps a chain ID to a readiness syncing value. It panics if the chain ID is invalid so it should only be used during initialization.
func MustRegisterReadinessSyncing ¶
MustRegisterReadinessSyncing registers the specified chain for readiness syncing. It panics if the chain ID is invalid so it should only be used during initialization. TODO: Using vaa.ChainID is bad here because there can be multiple watchers for the same chainId, e.g. solana-finalized and solana-confirmed. This is currently handled as a special case for solana in node/node.go, but should really be fixed here.
func NewInstrumentedGRPCServer ¶
func NewInstrumentedGRPCServer(logger *zap.Logger, rpcLogDetail GrpcLogDetail) *grpc.Server
func PostMsgWithTimestamp ¶
func PostMsgWithTimestamp[T any](msg *T, c chan<- *MsgWithTimeStamp[T]) error
PostMsgWithTimestamp sends the message to the specified channel using the current timestamp. Returns ErrChanFull on error.
func PostObservationRequest ¶
func PostObservationRequest(obsvReqSendC chan<- *gossipv1.ObservationRequest, req *gossipv1.ObservationRequest) error
func RunWithScissors ¶
func RunWithScissors(ctx context.Context, errC chan error, name string, runnable supervisor.Runnable)
Start a go routine with recovering from any panic by sending an error to a error channel
func SetRestrictiveUmask ¶
func SetRestrictiveUmask()
SetRestrictiveUmask masks the group and world bits. This ensures that key material and sockets we create aren't accidentally group- or world-readable.
func StartRunnable ¶
func StartRunnable(ctx context.Context, errC chan error, catchPanics bool, name string, runnable supervisor.Runnable)
StartRunnable starts a go routine with the ability to recover from errors by publishing them to an error channel. If catchPanics is true, it will also catch panics and publish the panic message to the error channel. If catchPanics is false, the panic will be propagated upward.
func WrapWithScissors ¶
func WrapWithScissors(runnable supervisor.Runnable, name string) supervisor.Runnable
func WriteArmoredKey ¶
func WriteArmoredKey(key *ecdsa.PrivateKey, description string, filename string, blockType string, unsafe bool) error
WriteArmoredKey serializes a key and writes it to disk.
Types ¶
type Environment ¶
type Environment string
const ( MainNet Environment = "prod" UnsafeDevNet Environment = "dev" // local devnet; Keys are deterministic and many security controls are disabled TestNet Environment = "test" // public testnet (needs to be reliable, but run with less Guardians and faster finality) GoTest Environment = "unit-test" AccountantMock Environment = "accountant-mock" // Used for mocking accountant with a Wormchain connection )
func ParseEnvironment ¶
func ParseEnvironment(str string) (Environment, error)
ParseEnvironment parses a string into the corresponding Environment value, allowing various reasonable variations.
type GrpcLogDetail ¶
type GrpcLogDetail string
const ( GrpcLogDetailNone GrpcLogDetail = "none" GrpcLogDetailMinimal GrpcLogDetail = "minimal" GrpcLogDetailFull GrpcLogDetail = "full" )
type GuardianSet ¶
type GuardianSet struct { // Guardian's public key hashes truncated by the ETH standard hashing mechanism (20 bytes). Keys []common.Address // On-chain set index Index uint32 }
func (*GuardianSet) KeyIndex ¶
func (g *GuardianSet) KeyIndex(addr common.Address) (int, bool)
KeyIndex returns a given address index from the guardian set. Returns (-1, false) if the address wasn't found and (addr, true) otherwise.
func (*GuardianSet) KeysAsHexStrings ¶
func (g *GuardianSet) KeysAsHexStrings() []string
type GuardianSetState ¶
type GuardianSetState struct {
// contains filtered or unexported fields
}
func NewGuardianSetState ¶
func NewGuardianSetState(guardianSetStateUpdateC chan *gossipv1.Heartbeat) *GuardianSetState
NewGuardianSetState returns a new GuardianSetState.
The provided channel will be pushed heartbeat updates as they are set, but be aware that the channel will block guardian set updates if full.
func (*GuardianSetState) Cleanup ¶
func (st *GuardianSetState) Cleanup()
Cleanup removes expired entries from the state.
func (*GuardianSetState) Get ¶
func (st *GuardianSetState) Get() *GuardianSet
func (*GuardianSetState) LastHeartbeat ¶
LastHeartbeat returns the most recent heartbeat message received for a given guardian node, or nil if none have been received.
func (*GuardianSetState) Set ¶
func (st *GuardianSetState) Set(set *GuardianSet)
func (*GuardianSetState) SetHeartbeat ¶
func (st *GuardianSetState) SetHeartbeat(addr common.Address, peerId peer.ID, hb *gossipv1.Heartbeat) error
SetHeartbeat stores a verified heartbeat observed by a given guardian.
type MessagePublication ¶
type MessagePublication struct { TxHash common.Hash // TODO: rename to identifier? on Solana, this isn't actually the tx hash Timestamp time.Time Nonce uint32 Sequence uint64 ConsistencyLevel uint8 EmitterChain vaa.ChainID EmitterAddress vaa.Address Payload []byte IsReobservation bool // Unreliable indicates if this message can be reobserved. If a message is considered unreliable it cannot be // reobserved. Unreliable bool }
func UnmarshalMessagePublication ¶
func UnmarshalMessagePublication(data []byte) (*MessagePublication, error)
UnmarshalMessagePublication deserializes a MessagePublication
func UnmarshalOldMessagePublicationBeforeIsReobservation ¶
func UnmarshalOldMessagePublicationBeforeIsReobservation(data []byte) (*MessagePublication, error)
UnmarshalOldMessagePublicationBeforeIsReobservation deserializes a MessagePublication from prior to the addition of IsReobservation. This function can be deleted once all guardians have been upgraded. That's why the code is just duplicated.
func (*MessagePublication) CreateDigest ¶
func (msg *MessagePublication) CreateDigest() string
func (*MessagePublication) CreateVAA ¶
func (msg *MessagePublication) CreateVAA(gsIndex uint32) *vaa.VAA
func (*MessagePublication) Marshal ¶
func (msg *MessagePublication) Marshal() ([]byte, error)
func (*MessagePublication) MarshalJSON ¶
func (msg *MessagePublication) MarshalJSON() ([]byte, error)
The standard json Marshal / Unmarshal of time.Time gets confused between local and UTC time.
func (*MessagePublication) MessageID ¶
func (msg *MessagePublication) MessageID() []byte
func (*MessagePublication) MessageIDString ¶
func (msg *MessagePublication) MessageIDString() string
func (*MessagePublication) UnmarshalJSON ¶
func (msg *MessagePublication) UnmarshalJSON(data []byte) error
func (*MessagePublication) ZapFields ¶
func (msg *MessagePublication) ZapFields(fields ...zap.Field) []zap.Field
ZapFields takes some zap fields and appends zap fields related to the message. Example usage: `logger.Info("logging something with a message", msg.ZapFields(zap.Int("some_other_field", 100))...)“ TODO refactor the codebase to use this function instead of manually logging the message with inconsistent fields
type MsgWithTimeStamp ¶
MsgWithTimeStamp allows us to track the time of receipt of an event.
func CreateMsgWithTimestamp ¶
func CreateMsgWithTimestamp[T any](msg *T) *MsgWithTimeStamp[T]
CreateMsgWithTimestamp creates a new MsgWithTimeStamp with the current time.