-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'ccip-develop' into mk/fix-int-test-wf
- Loading branch information
Showing
28 changed files
with
2,699 additions
and
116 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# OCR3 Commit Plugin | ||
|
||
## Context | ||
The purpose of the OCR3 Commit Plugin is to write reports to a configured destination chain. These reports | ||
contain metadata of cross-chain messages, from a set of source chains, that can be executed on the destination chain. | ||
|
||
## Commit Plugin Design | ||
|
||
The plugin is implemented as a state machine, and moves from state to state each round. There are 3 states: | ||
1. SelectingIntervalsForReport | ||
- Determine intervals to be included in the next report | ||
2. BuildingReport | ||
- Build a report from the intervals determined in the previous round | ||
3. WaitingForReportTransmission | ||
- Check if the maximum committed sequence numbers on the dest chain have changed since generating the most | ||
recent report, i.e. check if the report has been committed. | ||
- If the maximum committed sequence numbers have changed (i.e. the report has been committed) or the maximum | ||
number of check attempts have been exhausted, move to the SelectingIntervalsForReport state and generate a new | ||
report. | ||
- If the maximum committed sequence numbers have _not_ changed (i.e. the report is still in-flight) and the | ||
maximum number of check attempts are not been exhausted, move to the WaitingForReportTransmission state in order | ||
to check again. | ||
|
||
This approach leads to a clear separation of concerns and addresses the complications that can arise if a report | ||
is not successfully transmitted (as we explicitly only continue once we know the previous report has been committed). | ||
In this design, full messages are no longer in the observations, only merkle roots and intervals are. This reduces the | ||
size of observations, which reduces bandwidth and improves performance. | ||
|
||
This is the state machine diagram. States are in boxes, outcomes are within arrows. | ||
|
||
Start | ||
| | ||
V | ||
------------------------------- | ||
| SelectingIntervalsForReport | <---------| | ||
------------------------------- | | ||
| | | ||
ReportIntervalsSelected | | ||
| | | ||
V | | ||
------------------ | | ||
| BuildingReport | -- ReportEmpty --->| | ||
------------------ | | ||
| ReportTransmitted | ||
ReportGenerated or | ||
| ReportNotTransmitted | ||
V | | ||
-------------------------------- | | ||
| WaitingForReportTransmission | -------->| | ||
-------------------------------- | ||
| ^ | ||
| | | ||
ReportNotYetTransmitted |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package commitrmnocb | ||
|
||
import ( | ||
"fmt" | ||
|
||
mapset "github.com/deckarep/golang-set/v2" | ||
"github.com/smartcontractkit/libocr/commontypes" | ||
libocrtypes "github.com/smartcontractkit/libocr/ragep2p/types" | ||
|
||
"github.com/smartcontractkit/chainlink-common/pkg/logger" | ||
cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" | ||
|
||
"github.com/smartcontractkit/chainlink-ccip/internal/libs/slicelib" | ||
"github.com/smartcontractkit/chainlink-ccip/internal/reader" | ||
) | ||
|
||
// ChainSupport contains functions that enable an oracle to determine which chains are accessible by itself and | ||
// other oracles | ||
type ChainSupport interface { | ||
// SupportedChains returns the set of chains that the given Oracle is configured to access | ||
SupportedChains(oracleID commontypes.OracleID) (mapset.Set[cciptypes.ChainSelector], error) | ||
|
||
// SupportsDestChain returns true if the given oracle supports the dest chain, returns false otherwise | ||
SupportsDestChain(oracle commontypes.OracleID) (bool, error) | ||
|
||
// KnownSourceChainsSlice returns a list of all known source chains | ||
KnownSourceChainsSlice() ([]cciptypes.ChainSelector, error) | ||
} | ||
|
||
type CCIPChainSupport struct { | ||
lggr logger.Logger | ||
homeChain reader.HomeChain | ||
oracleIDToP2pID map[commontypes.OracleID]libocrtypes.PeerID | ||
nodeID commontypes.OracleID | ||
destChain cciptypes.ChainSelector | ||
} | ||
|
||
func (c CCIPChainSupport) KnownSourceChainsSlice() ([]cciptypes.ChainSelector, error) { | ||
knownSourceChains, err := c.homeChain.GetKnownCCIPChains() | ||
if err != nil { | ||
c.lggr.Errorw("error getting known chains", "err", err) | ||
return nil, fmt.Errorf("error getting known chains: %w", err) | ||
} | ||
knownSourceChainsSlice := knownSourceChains.ToSlice() | ||
return slicelib.Filter(knownSourceChainsSlice, func(ch cciptypes.ChainSelector) bool { return ch != c.destChain }), nil | ||
} | ||
|
||
// SupportedChains returns the set of chains that the given Oracle is configured to access | ||
func (c CCIPChainSupport) SupportedChains(oracleID commontypes.OracleID) (mapset.Set[cciptypes.ChainSelector], error) { | ||
p2pID, exists := c.oracleIDToP2pID[oracleID] | ||
if !exists { | ||
return nil, fmt.Errorf("oracle ID %d not found in oracleIDToP2pID", c.nodeID) | ||
} | ||
supportedChains, err := c.homeChain.GetSupportedChainsForPeer(p2pID) | ||
if err != nil { | ||
c.lggr.Warnw("error getting supported chains", err) | ||
return mapset.NewSet[cciptypes.ChainSelector](), fmt.Errorf("error getting supported chains: %w", err) | ||
} | ||
|
||
return supportedChains, nil | ||
} | ||
|
||
// SupportsDestChain returns true if the given oracle supports the dest chain, returns false otherwise | ||
func (c CCIPChainSupport) SupportsDestChain(oracle commontypes.OracleID) (bool, error) { | ||
destChainConfig, err := c.homeChain.GetChainConfig(c.destChain) | ||
if err != nil { | ||
return false, fmt.Errorf("get chain config: %w", err) | ||
} | ||
return destChainConfig.SupportedNodes.Contains(c.oracleIDToP2pID[oracle]), nil | ||
} | ||
|
||
// Interface compliance check | ||
var _ ChainSupport = (*CCIPChainSupport)(nil) |
Oops, something went wrong.