Documentation
¶
Index ¶
Constants ¶
const AssetsLockedEventsLimit = 10
AssetsLockedEventsLimit is the maximum number of AssetsLocked events to fetch in a single request and include in the vote extension.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AssetsLockedExtractor ¶
type AssetsLockedExtractor interface { // CanonicalEvents takes the given extended commit info and determines the // sequence of canonical AssetsLocked events supported by 2/3+ of the bridge // validators and confirmed by 2/3+ of the non-bridge validators. If the // sequence of canonical events cannot be determined, the function returns an // error. Otherwise, it returns the canonical events in a sequence strictly // increasing by 1. CanonicalEvents( ctx sdk.Context, extendedCommitInfo cmtabci.ExtendedCommitInfo, height int64, ) (bridgetypes.AssetsLockedEvents, error) }
AssetsLockedExtractor is an interface representing a component whose task is extracting the sequence of canonical AssetsLocked events supported by 2/3+ of the bridge validators and confirmed by 2/3+ of the non-bridge validators from the given extended commit info.
type BridgeKeeper ¶
type BridgeKeeper interface { GetAssetsLockedSequenceTip(ctx sdk.Context) math.Int AcceptAssetsLocked(ctx sdk.Context, events types.AssetsLockedEvents) error }
BridgeKeeper is an interface to the x/bridge module keeper.
type EthereumSidecarClient ¶
type EthereumSidecarClient interface { // GetAssetsLockedEvents returns confirmed AssetsLockedEvents with // the sequence number falling within the half-open range, denoted by // sequenceStart (included) and sequenceEnd (excluded). To indicate an // unbounded edge of the range, use a zero initialized value (`math.Int{}`) // for sequenceStart or sequenceEnd. // // The implementation should ensure that sequence numbers of the returned // events form a sequence strictly increasing by 1. Such a sequence // guarantees that there are no gaps between the sequence numbers of the // events and that each event is unique by its sequence number. GetAssetsLockedEvents( ctx context.Context, sequenceStart math.Int, sequenceEnd math.Int, ) ([]types.AssetsLockedEvent, error) }
EthereumSidecarClient is an interface for a client that can interact with the Ethereum sidecar.
type PreBlockHandler ¶
type PreBlockHandler struct {
// contains filtered or unexported fields
}
PreBlockHandler is the bridge-specific pre-block handler (part of the FinalizeBlock ABCI request)
func NewPreBlockHandler ¶
func NewPreBlockHandler( logger log.Logger, bridgeKeeper BridgeKeeper, ) *PreBlockHandler
NewPreBlockHandler returns a new PreBlockHandler.
func (*PreBlockHandler) PreBlocker ¶
func (pbh *PreBlockHandler) PreBlocker() sdk.PreBlocker
PreBlocker returns the pre-block handler (part of the FinalizeBlock ABCI request). This function:
- Extracts the sequence of canonical AssetsLocked events from the injected pseudo-transaction. Minimum validation is performed to avoid unexpected panics but no error is expected here as this handler is invoked after the proposal phase which guarantees the pseudo-transaction is well-formed and contain a valid sequence of canonical AssetsLocked events.
- Accepts the AssetsLocked events by calling the bridge keeper's AcceptAssetsLocked method. This call updates the internal state of the bridge module to reflect the new AssetsLocked events and mints new BTC as result.
Dev note: In case of success, this function should return a non-nil pointer value (&sdk.ResponsePreBlock{}) as ResponsePreBlock and a nil error. The specific value of ResponsePreBlock is not relevant for the app-level handler but, we try to adhere to the Go best practices and return a non-nil pointer value in case of success. Conversely, in case of failure, this function should return a nil ResponsePreBlock and a non-nil error. BEWARE: An error returned from this function will be bubbled up by the app-level handler and will cause the FinalizeBlock ABCI request to fail. This, in turn, will lead to an unrecoverable consensus failure. Make sure you know what you are doing before returning an error.
type ProposalHandler ¶
type ProposalHandler struct {
// contains filtered or unexported fields
}
ProposalHandler is the bridge-specific handler for the PrepareProposal and ProcessProposal ABCI requests.
func NewProposalHandler ¶
func NewProposalHandler( logger log.Logger, valStore bridgetypes.ValidatorStore, keeper BridgeKeeper, voteExtensionDecomposer VoteExtensionDecomposer, voteExtensionsValidator VoteExtensionsValidator, ) *ProposalHandler
NewProposalHandler creates a new ProposalHandler instance.
func (*ProposalHandler) PrepareProposalHandler ¶
func (ph *ProposalHandler) PrepareProposalHandler() sdk.PrepareProposalHandler
PrepareProposalHandler returns the handler for the PrepareProposal ABCI request. This function:
- Validates the signatures of the commit's vote extensions
- Extracts the bridge-specific parts from the vote extensions that hold the AssetsLocked events
- Determines the sequence of canonical AssetsLocked events supported by 2/3+ of the bridge validators and confirmed by 2/3+ of the non-bridge validators
- Injects the pseudo-transaction containing the canonical events at the beginning of the original transaction list being part of the proposal.
Dev note: It is fine to return a nil response and an error from this function in case of failure. The upstream app-level vote extension handler will handle the error gracefully and won't include the bridge-specific part in the app-level proposal.
func (*ProposalHandler) ProcessProposalHandler ¶
func (ph *ProposalHandler) ProcessProposalHandler() sdk.ProcessProposalHandler
ProcessProposalHandler returns the handler for the ProcessProposal ABCI request. This function validates the injected bridge-specific pseudo-tx to determine proposal acceptance or rejection. Specifically it:
- Makes sure the injected pseudo-tx exists and unmarshals correctly
- Verifies whether the commit info attached to the pseudo-tx unmarshals correctly
- Ensures injected pseudo-tx contains a non-empty slice of AssetsLocked events
- Validates the signatures of the vote extensions attached to the injected pseudo-tx (as part of the commit info)
- Recreates the canonical sequence of AssetsLocked events using the attached vote extensions and ensures it matches the AssetsLocked events from the injected pseudo-tx
- Makes sure the AssetsLocked events from the injected pseudo-tx start directly after the current sequence tip
If the injected pseudo-tx is valid, the proposal is accepted. Empty pseudo-txs lead to proposal acceptance by default.
Dev note: In case the injected pseudo-tx is invalid, we REJECT the proposal explicitly and return an error describing the reason. Due to the limitations of the Cosmos interface, REJECT without an error does not provide any details about the reason. Conversely, error without REJECT is confusing as it should rather denote a failure of the handler itself. The upstream app-level proposal handler will handle all non-ACCEPT cases gracefully and reject the app-level proposal.
See Skip's price oracle ProcessProposal handler for a similar pattern: https://github.com/skip-mev/connect/blob/53b22d1ff50f5b60d50346640e32bbd77472e95e/abci/proposals/proposals.go#L255
type VoteExtensionDecomposer ¶
type VoteExtensionDecomposer func(compositeVoteExtensionBytes []byte) ( voteExtensionBytes []byte, err error, )
VoteExtensionDecomposer is a function that decomposes a composite app-level vote extension and returns the part that is relevant to the bridge.
type VoteExtensionHandler ¶
type VoteExtensionHandler struct {
// contains filtered or unexported fields
}
VoteExtensionHandler is the bridge-specific handler for the ExtendVote and VerifyVoteExtension ABCI requests.
func NewVoteExtensionHandler ¶
func NewVoteExtensionHandler( logger log.Logger, sidecarClient EthereumSidecarClient, bridgeKeeper BridgeKeeper, ) *VoteExtensionHandler
NewVoteExtensionHandler creates a new VoteExtensionHandler instance.
func (*VoteExtensionHandler) ExtendVoteHandler ¶
func (veh *VoteExtensionHandler) ExtendVoteHandler() sdk.ExtendVoteHandler
ExtendVoteHandler returns the handler for the ExtendVote ABCI request. It fetches the AssetsLocked events from the sidecar and includes them in the vote extension, in their natural order (by sequence asc). Events are fetched from a half-open range [start, end), where `start` is the currently stored sequence tip + 1, and `end` is `start` + AssetsLockedEventsLimit. It is guaranteed that the number of events included in the vote extension will not exceed AssetsLockedEventsLimit.
Dev note: It is fine to return a nil response and an error from this function in case of failure. The upstream app-level vote extension handler will handle the error gracefully and won't include the bridge-specific part in the app-level vote extension.
func (*VoteExtensionHandler) VerifyVoteExtensionHandler ¶
func (veh *VoteExtensionHandler) VerifyVoteExtensionHandler() sdk.VerifyVoteExtensionHandler
VerifyVoteExtensionHandler returns the handler for the VerifyVoteExtension ABCI request. It verifies the vote extension by checking that:
- The vote extension unmarshals
- AssetsLocked events are valid (positive sequence number, positive amount, proper bech32 recipient) and form a sequence strictly increasing by 1
- The number of AssetsLocked events does not exceed the limit
If the vote extension is valid, it is accepted. Empty vote extensions are accepted by default.
Dev note: In case the vote extension is invalid, we REJECT it explicitly and return an error describing the reason. Due to the limitations of the Cosmos interface, REJECT without an error does not provide any details about the reason. Conversely, error without REJECT is confusing as it should rather denote a failure of the handler itself. The upstream app-level vote extension handler will handle all non-ACCEPT cases gracefully and reject the app-level vote extension.
See Skip's price oracle VerifyVoteExtension handler for a similar pattern: https://github.com/skip-mev/connect/blob/8c9ac8bf5b5bf239caa11086db34f88f30efe2c5/abci/ve/vote_extension.go#L213
type VoteExtensionsValidator ¶
type VoteExtensionsValidator func( ctx sdk.Context, valStore baseapp.ValidatorStore, height int64, chainID string, extCommit cmtabci.ExtendedCommitInfo, ) error
VoteExtensionsValidator is a function for verifying vote extension signatures that may be passed or manually injected into a block proposal from a proposer in PrepareProposal. It returns an error if any signature is invalid or if unexpected vote extensions and/or signatures are found or less than 2/3 power is received.