Skip to content

Commit

Permalink
Move plugintypes.execute.go to exectypes package
Browse files Browse the repository at this point in the history
  • Loading branch information
winder committed Aug 7, 2024
1 parent e5ee623 commit 795cfb8
Show file tree
Hide file tree
Showing 18 changed files with 339 additions and 334 deletions.
2 changes: 1 addition & 1 deletion .mockery.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ with-expecter: true
filename: "{{.InterfaceName | snakecase}}.go"
dir: mocks/{{ replaceAll .InterfaceDirRelative "internal" "internal_" }}
packages:
github.com/smartcontractkit/chainlink-ccip/execute/types:
github.com/smartcontractkit/chainlink-ccip/execute/exectypes:
interfaces:
TokenDataReader:
github.com/smartcontractkit/chainlink-ccip/execute/internal/gen:
Expand Down
32 changes: 32 additions & 0 deletions execute/exectypes/commit_data.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package exectypes

import (
"time"

cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3"
)

// CommitData is the data that is committed to the chain.
type CommitData struct {
// SourceChain of the chain that contains the commit report.
SourceChain cciptypes.ChainSelector `json:"chainSelector"`
// Timestamp of the block that contains the commit.
Timestamp time.Time `json:"timestamp"`
// BlockNum of the block that contains the commit.
BlockNum uint64 `json:"blockNum"`
// MerkleRoot of the messages that are in this commit report.
MerkleRoot cciptypes.Bytes32 `json:"merkleRoot"`
// SequenceNumberRange of the messages that are in this commit report.
SequenceNumberRange cciptypes.SeqNumRange `json:"sequenceNumberRange"`

// Messages that are part of the commit report.
Messages []cciptypes.Message `json:"messages"`

// ExecutedMessages are the messages in this report that have already been executed.
ExecutedMessages []cciptypes.SeqNum `json:"executedMessages"`

// The following values are cached for validation algorithms, serialization is not required for consensus.

// TokenData for each message.
TokenData [][][]byte `json:"-"`
}
43 changes: 43 additions & 0 deletions execute/exectypes/observation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package exectypes

import (
"encoding/json"

cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3"
)

type CommitObservations map[cciptypes.ChainSelector][]CommitData
type MessageObservations map[cciptypes.ChainSelector]map[cciptypes.SeqNum]cciptypes.Message

// Observation is the observation of the ExecutePlugin.
// TODO: revisit observation types. The maps used here are more space efficient and easier to work
// with but require more transformations compared to the on-chain representations.
type Observation struct {
// CommitReports are determined during the first phase of execute.
// It contains the commit reports we would like to execute in the following round.
CommitReports CommitObservations `json:"commitReports"`
// Messages are determined during the second phase of execute.
// Ideally, it contains all the messages identified by the previous outcome's
// NextCommits. With the previous outcome, and these messsages, we can build the
// execute report.
Messages MessageObservations `json:"messages"`
// TODO: some of the nodes configuration may need to be included here.
}

func NewObservation(
commitReports CommitObservations, messages MessageObservations) Observation {
return Observation{
CommitReports: commitReports,
Messages: messages,
}
}

func (obs Observation) Encode() ([]byte, error) {
return json.Marshal(obs)
}

func DecodeObservation(b []byte) (Observation, error) {
obs := Observation{}
err := json.Unmarshal(b, &obs)
return obs, err
}
64 changes: 64 additions & 0 deletions execute/exectypes/outcome.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package exectypes

import (
"encoding/json"
"sort"

cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3"
)

// Outcome is the outcome of the ExecutePlugin.
type Outcome struct {
// PendingCommitReports are the oldest reports with pending commits. The slice is
// sorted from oldest to newest.
PendingCommitReports []CommitData `json:"commitReports"`

// Report is built from the oldest pending commit reports.
Report cciptypes.ExecutePluginReport `json:"report"`
}

func (o Outcome) IsEmpty() bool {
return len(o.PendingCommitReports) == 0 && len(o.Report.ChainReports) == 0
}

func NewOutcome(
pendingCommits []CommitData,
report cciptypes.ExecutePluginReport,
) Outcome {
return newSortedOutcome(pendingCommits, report)
}

// Encode encodes the outcome by first sorting the pending commit reports and the chain reports
// and then JSON marshalling.
// The encoding MUST be deterministic.
func (o Outcome) Encode() ([]byte, error) {
// We sort again here in case construction is not via the constructor.
return json.Marshal(newSortedOutcome(o.PendingCommitReports, o.Report))
}

func newSortedOutcome(
pendingCommits []CommitData,
report cciptypes.ExecutePluginReport) Outcome {
pendingCommitsCP := append([]CommitData{}, pendingCommits...)
reportCP := append([]cciptypes.ExecutePluginReportSingleChain{}, report.ChainReports...)
sort.Slice(
pendingCommitsCP,
func(i, j int) bool {
return pendingCommitsCP[i].SourceChain < pendingCommitsCP[j].SourceChain
})
sort.Slice(
reportCP,
func(i, j int) bool {
return reportCP[i].SourceChainSelector < reportCP[j].SourceChainSelector
})
return Outcome{
PendingCommitReports: pendingCommitsCP,
Report: cciptypes.ExecutePluginReport{ChainReports: reportCP},
}
}

func DecodeOutcome(b []byte) (Outcome, error) {
o := Outcome{}
err := json.Unmarshal(b, &o)
return o, err
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package types
package exectypes

import (
"context"
Expand Down
28 changes: 14 additions & 14 deletions execute/internal/validation/reports_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import (

cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3"

"github.com/smartcontractkit/chainlink-ccip/plugintypes"
"github.com/smartcontractkit/chainlink-ccip/execute/exectypes"
)

func Test_CommitReportValidator_ExecutePluginCommitData(t *testing.T) {
tests := []struct {
name string
min int
reports []plugintypes.ExecutePluginCommitData
valid []plugintypes.ExecutePluginCommitData
reports []exectypes.CommitData
valid []exectypes.CommitData
}{
{
name: "empty",
Expand All @@ -26,62 +26,62 @@ func Test_CommitReportValidator_ExecutePluginCommitData(t *testing.T) {
{
name: "single report, enough observations",
min: 1,
reports: []plugintypes.ExecutePluginCommitData{
reports: []exectypes.CommitData{
{MerkleRoot: [32]byte{1}},
},
valid: []plugintypes.ExecutePluginCommitData{
valid: []exectypes.CommitData{
{MerkleRoot: [32]byte{1}},
},
},
{
name: "single report, not enough observations",
min: 2,
reports: []plugintypes.ExecutePluginCommitData{
reports: []exectypes.CommitData{
{MerkleRoot: [32]byte{1}},
},
valid: nil,
},
{
name: "multiple reports, partial observations",
min: 2,
reports: []plugintypes.ExecutePluginCommitData{
reports: []exectypes.CommitData{
{MerkleRoot: [32]byte{3}},
{MerkleRoot: [32]byte{1}},
{MerkleRoot: [32]byte{2}},
{MerkleRoot: [32]byte{1}},
{MerkleRoot: [32]byte{2}},
},
valid: []plugintypes.ExecutePluginCommitData{
valid: []exectypes.CommitData{
{MerkleRoot: [32]byte{1}},
{MerkleRoot: [32]byte{2}},
},
},
{
name: "multiple reports for same root",
min: 2,
reports: []plugintypes.ExecutePluginCommitData{
reports: []exectypes.CommitData{
{MerkleRoot: [32]byte{1}, BlockNum: 1},
{MerkleRoot: [32]byte{1}, BlockNum: 2},
{MerkleRoot: [32]byte{1}, BlockNum: 3},
{MerkleRoot: [32]byte{1}, BlockNum: 4},
{MerkleRoot: [32]byte{1}, BlockNum: 1},
},
valid: []plugintypes.ExecutePluginCommitData{
valid: []exectypes.CommitData{
{MerkleRoot: [32]byte{1}, BlockNum: 1},
},
},
{
name: "different executed messages same root",
min: 2,
reports: []plugintypes.ExecutePluginCommitData{
reports: []exectypes.CommitData{
{MerkleRoot: [32]byte{1}, ExecutedMessages: []cciptypes.SeqNum{1, 2}},
{MerkleRoot: [32]byte{1}, ExecutedMessages: []cciptypes.SeqNum{2, 3}},
{MerkleRoot: [32]byte{1}, ExecutedMessages: []cciptypes.SeqNum{3, 4}},
{MerkleRoot: [32]byte{1}, ExecutedMessages: []cciptypes.SeqNum{4, 5}},
{MerkleRoot: [32]byte{1}, ExecutedMessages: []cciptypes.SeqNum{5, 6}},
{MerkleRoot: [32]byte{1}, ExecutedMessages: []cciptypes.SeqNum{1, 2}},
},
valid: []plugintypes.ExecutePluginCommitData{
valid: []exectypes.CommitData{
{MerkleRoot: [32]byte{1}, ExecutedMessages: []cciptypes.SeqNum{1, 2}},
},
},
Expand All @@ -92,10 +92,10 @@ func Test_CommitReportValidator_ExecutePluginCommitData(t *testing.T) {
t.Parallel()

// Initialize the minObservationValidator
idFunc := func(data plugintypes.ExecutePluginCommitData) [32]byte {
idFunc := func(data exectypes.CommitData) [32]byte {
return sha3.Sum256([]byte(fmt.Sprintf("%v", data)))
}
validator := NewMinObservationValidator[plugintypes.ExecutePluginCommitData](tt.min, idFunc)
validator := NewMinObservationValidator[exectypes.CommitData](tt.min, idFunc)
for _, report := range tt.reports {
validator.Add(report)
}
Expand Down
Loading

0 comments on commit 795cfb8

Please sign in to comment.