governor

package
v0.0.0-...-e5947bb Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 13, 2026 License: Apache-2.0 Imports: 30 Imported by: 6

README

Governor

Performing a database upgrade

A database upgrade is required whenever the serialized format of a MessagePublication changes. This occurs if a field is added, removed, or changed or if the marshaling format changes.

The Governor has to handle this in a special way because it must be able to read the old format and write the new format. This is required so that the Governor can continue to monitor transfers and messages that have already been recorded. It only needs to support the old format for the duration of its sliding window as the old transfers and messages will automatically be dropped after the duration of the window.

Example upgrade

Commit 1ed88d1 performs a modification of the MessagePublication struct and upgrades both the Governor and the Accountant.

Upgrade Process

When upgrading the database format, follow these steps:

  1. Update prefixes in node/pkg/db/governor.go:

    • Move current prefixes to old*Prefix constants (e.g., transferPrefixoldTransferPrefix)
    • Increment version number in new prefixes (e.g., GOV:XFER4:GOV:XFER5:)
    • Update corresponding length constants
  2. Update database functions:

    • Ensure Is* functions use new prefixes for current format detection
    • Ensure isOld* functions use old prefixes for legacy format detection
    • Update *MsgID functions to use new prefixes
  3. Update unit tests in node/pkg/db/governor_test.go:

    • Update existing tests to use new prefixes
    • Create separate test functions for each version using naming pattern TestIs*V[N]
    • Add function comments explaining version suffix and prefix mapping
    • Example: TestIsTransferV4 tests GOV:XFER4:, TestIsTransferV3 tests GOV:XFER3:
  4. Test coverage:

    • Ensure both current and legacy formats are tested
    • Include round-trip tests to verify serialization compatibility:
      • Save and load to database
      • Marshal and unmarshal
Database APIs

The actual database CRUD calls should be kept version-agnostic to avoid an explosion in the number of versioned methods and the accompanying maintenance burden.

Live Migration

When the Governor restarts and loads its data from the key-value store, it marks which transfers and/or messages are in the old format and saves them in the new format right away. It also deletes the records using the old format. This minimizes the time needed to support the two different versions.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CheckQuery

func CheckQuery(logger *zap.Logger) error

CheckQuery is a free function used to test that the CoinGecko query still works after the mainnet token list has been updated.

func CheckedAddInt64

func CheckedAddInt64(x int64, y int64) (int64, error)

CheckedAddInt64 adds two uint64 values with overflow checks. Returns an error if the calculation would overflow or underflow. In this case, the returned value is 0.

func CheckedAddUint64

func CheckedAddUint64(x uint64, y uint64) (uint64, error)

CheckedAddUint64 adds two uint64 values with overflow checks

func FlowCancelCorridors

func FlowCancelCorridors() []corridor

FlowCancelCorridors returns a list of `pipe`s representing a pair of chains for which flow canceling is enabled. In practice this list should contain pairs of chains that have a large amount of volume between each other. These are more likely to cause chronic congestion which flow canceling can help to alleviate. Pairs of chains that are not frequently congested do not need to enable flow canceling as they should have plenty of regular Governor capacity to work with.

func ValidateCorridors

func ValidateCorridors(input []corridor) bool

Types

type ChainConfigEntry

type ChainConfigEntry struct {
	EmitterChainID     vaa.ChainID
	DailyLimit         uint64
	BigTransactionSize uint64
}

Layout of the config data for each chain

func ChainList

func ChainList() []ChainConfigEntry

type ChainGovernor

type ChainGovernor struct {
	// contains filtered or unexported fields
}

func NewChainGovernor

func NewChainGovernor(
	logger *zap.Logger,
	db guardianDB.GovernorDB,
	env common.Environment,
	flowCancelEnabled bool,
	coinGeckoApiKey string,
) *ChainGovernor

func (*ChainGovernor) CheckPending

func (gov *ChainGovernor) CheckPending() ([]*common.MessagePublication, error)

CheckPending is a wrapper method for CheckPendingForTime that uses time.Now as the release time. Returns a slice of MessagePublications that are ready to be published.

func (*ChainGovernor) CollectMetrics

func (gov *ChainGovernor) CollectMetrics(ctx context.Context, hb *gossipv1.Heartbeat, sendC chan<- []byte, guardianSigner guardiansigner.GuardianSigner, ourAddr ethCommon.Address)

func (*ChainGovernor) DropPendingVAA

func (gov *ChainGovernor) DropPendingVAA(vaaId string) (string, error)

Admin command to remove a VAA from the pending list and discard it.

func (*ChainGovernor) GetAvailableNotionalByChain

func (gov *ChainGovernor) GetAvailableNotionalByChain() (resp []*publicrpcv1.GovernorGetAvailableNotionalByChainResponse_Entry)

REST query to get the current available notional value per chain. This is defined as the sum of all transfers subtracted from the chains's dailyLimit. The available notional limit by chain represents the remaining capacity of a chain. As a result, it should not be a negative number: we don't want to represent that there is "negative value" available.

func (*ChainGovernor) GetEnqueuedVAAs

REST query to get the list of enqueued VAAs.

func (*ChainGovernor) GetTokenList

REST query to get the list of tokens being monitored by the governor.

func (*ChainGovernor) IsFlowCancelEnabled

func (gov *ChainGovernor) IsFlowCancelEnabled() bool

func (*ChainGovernor) IsGovernedMsg

func (gov *ChainGovernor) IsGovernedMsg(msg *common.MessagePublication) (msgIsGoverned bool, err error)

IsGovernedMsg determines if the message applies to the governor. It grabs the lock.

func (*ChainGovernor) IsVAAEnqueued

func (gov *ChainGovernor) IsVAAEnqueued(msgId *publicrpcv1.MessageID) (bool, error)

REST query to see if a VAA is enqueued.

func (*ChainGovernor) ProcessMsg

func (gov *ChainGovernor) ProcessMsg(msg *common.MessagePublication) bool

Returns true if the message can be published, false if it has been added to the pending list or if an error occurred.

func (*ChainGovernor) ReleasePendingVAA

func (gov *ChainGovernor) ReleasePendingVAA(vaaId string) (string, error)

Admin command to remove a VAA from the pending list and publish it without regard to (or impact on) the daily limit.

func (*ChainGovernor) Reload

func (gov *ChainGovernor) Reload() (string, error)

Admin command to reload the governor state from the database.

func (*ChainGovernor) ResetReleaseTimer

func (gov *ChainGovernor) ResetReleaseTimer(vaaId string, numDays uint32) (string, error)

Admin command to reset the release timer for a pending VAA, extending it to the configured limit.

func (*ChainGovernor) Run

func (gov *ChainGovernor) Run(ctx context.Context) error

func (*ChainGovernor) Status

func (gov *ChainGovernor) Status() (resp string)

Admin command to display status to the log.

type TokenConfigEntry

type TokenConfigEntry struct {
	// Chain is the Wormhole chain ID of the token's source chain (where the token was minted).
	Chain uint16
	// Addr is the token's address on the source chain in Wormhole normalized format.
	Addr        string
	Symbol      string
	CoinGeckoId string
	Decimals    int64
	Price       float64
}

Layout of the config data for each token

func FlowCancelTokenList

func FlowCancelTokenList() []TokenConfigEntry

FlowCancelTokenList returns a list of `tokenConfigEntry`s representing tokens that can 'Flow Cancel'. This means that incoming transfers that use these tokens can reduce the 'daily usage' of the Governor configured for the destination chain. The list of tokens was generated by grepping the file `generated_mainnet_tokens.go` for "USDC", "USDT", and "DAI".

Only tokens that are configured in the mainnet token list should be able to flow cancel. That is, if a token is present in this list but not in the mainnet token lists, it should not flow cancel.

Note that the field `symbol` is unused. It is retained in this file only for convenience.

func TokenList

func TokenList() []TokenConfigEntry

func (*TokenConfigEntry) String

func (e *TokenConfigEntry) String() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL