Skip to content

Commit 67b0126

Browse files
authored
[CAL][1] - Add initial CAL scaffolding to CCIPReader with legacy accessor (#978)
1 parent bca1f7d commit 67b0126

File tree

7 files changed

+305
-58
lines changed

7 files changed

+305
-58
lines changed

commit/factory.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ func (p *PluginFactory) NewReportingPlugin(ctx context.Context, config ocr3types
177177
return nil, ocr3types.ReportingPluginInfo{}, fmt.Errorf("validate ocr config: %w", err)
178178
}
179179

180-
ccipReader := readerpkg.NewCCIPChainReader(
180+
ccipReader, err := readerpkg.NewCCIPChainReader(
181181
ctx,
182182
logutil.WithComponent(lggr, "CCIPReader"),
183183
readers,
@@ -186,6 +186,9 @@ func (p *PluginFactory) NewReportingPlugin(ctx context.Context, config ocr3types
186186
p.ocrConfig.Config.OfframpAddress,
187187
p.addrCodec,
188188
)
189+
if err != nil {
190+
return nil, ocr3types.ReportingPluginInfo{}, fmt.Errorf("failed to create CCIP chain reader: %w", err)
191+
}
189192

190193
// The node supports the chain that the token prices are on.
191194
_, ok := readers[offchainConfig.PriceFeedChainSelector]

commit/factory_test.go

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package commit
22

33
import (
4+
"context"
45
"encoding/json"
56
"fmt"
67
"math"
8+
"math/big"
79
"strings"
810
"testing"
911
"time"
@@ -13,13 +15,13 @@ import (
1315

1416
rmnpb "github.com/smartcontractkit/chainlink-protos/rmn/v1.6/go/serialization"
1517

16-
"github.com/smartcontractkit/chainlink-ccip/internal"
17-
1818
"github.com/smartcontractkit/chainlink-common/pkg/merklemulti"
1919
"github.com/smartcontractkit/chainlink-common/pkg/types"
2020
"github.com/smartcontractkit/chainlink-common/pkg/utils/tests"
2121
"github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types"
2222

23+
"github.com/smartcontractkit/chainlink-ccip/internal"
24+
2325
"github.com/smartcontractkit/chainlink-ccip/commit/chainfee"
2426
"github.com/smartcontractkit/chainlink-ccip/commit/committypes"
2527
"github.com/smartcontractkit/chainlink-ccip/commit/merkleroot"
@@ -305,6 +307,7 @@ func TestPluginFactory_NewReportingPlugin(t *testing.T) {
305307
b, err := json.Marshal(offChainConfig)
306308
require.NoError(t, err)
307309

310+
chainSel := ccipocr3.ChainSelector(12922642891491394802)
308311
mockAddrCodec := internal.NewMockAddressCodecHex(t)
309312
p := &PluginFactory{
310313
baseLggr: lggr,
@@ -315,9 +318,15 @@ func TestPluginFactory_NewReportingPlugin(t *testing.T) {
315318
OfframpAddress: []byte{1, 2, 3},
316319
OffchainConfig: b,
317320
// Real selector pointing to chain 2337
318-
ChainSelector: 12922642891491394802,
321+
ChainSelector: chainSel,
319322
},
320323
},
324+
contractReaders: map[ccipocr3.ChainSelector]types.ContractReader{
325+
chainSel: types.UnimplementedContractReader{},
326+
},
327+
chainWriters: map[ccipocr3.ChainSelector]types.ContractWriter{
328+
chainSel: UnimplementedTestContractWriter{},
329+
},
321330
addrCodec: mockAddrCodec,
322331
}
323332

@@ -337,3 +346,43 @@ func TestPluginFactory_NewReportingPlugin(t *testing.T) {
337346
require.Equal(t, maxQueryLength, pluginInfo.Limits.MaxQueryLength)
338347
})
339348
}
349+
350+
type UnimplementedTestContractWriter struct{}
351+
352+
func (u UnimplementedTestContractWriter) Start(ctx context.Context) error {
353+
return fmt.Errorf("ContractWriter.Start not implemented")
354+
}
355+
356+
func (u UnimplementedTestContractWriter) Close() error {
357+
return fmt.Errorf("ContractWriter.Start not implemented")
358+
}
359+
360+
func (u UnimplementedTestContractWriter) Ready() error {
361+
return fmt.Errorf("ContractWriter.Start not implemented")
362+
}
363+
364+
func (u UnimplementedTestContractWriter) HealthReport() map[string]error {
365+
return nil
366+
}
367+
368+
func (u UnimplementedTestContractWriter) Name() string {
369+
return "UnimplementedTestContractWriter"
370+
}
371+
372+
func (u UnimplementedTestContractWriter) SubmitTransaction(
373+
_ context.Context, _, _ string, _ any, _ string, _ string, _ *types.TxMeta, _ *big.Int,
374+
) error {
375+
return fmt.Errorf("ContractWriter.SubmitTransaction not implemented")
376+
}
377+
378+
func (u UnimplementedTestContractWriter) GetTransactionStatus(
379+
ctx context.Context, transactionID string,
380+
) (types.TransactionStatus, error) {
381+
return 0, fmt.Errorf("ContractWriter.GetTransactionStatus not implemented")
382+
}
383+
384+
func (u UnimplementedTestContractWriter) GetFeeComponents(ctx context.Context) (*types.ChainFeeComponents, error) {
385+
return nil, fmt.Errorf("ContractWriter.GetFeeComponents not implemented")
386+
}
387+
388+
var _ types.ContractWriter = UnimplementedTestContractWriter{}

execute/factory.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ func (p PluginFactory) NewReportingPlugin(
143143
contractreader.NewObserverReader(cr, lggr, chainID))
144144
}
145145

146-
ccipReader := readerpkg.NewCCIPChainReader(
146+
ccipReader, err := readerpkg.NewCCIPChainReader(
147147
ctx,
148148
logutil.WithComponent(lggr, "CCIPReader"),
149149
readers,
@@ -152,6 +152,9 @@ func (p PluginFactory) NewReportingPlugin(
152152
p.ocrConfig.Config.OfframpAddress,
153153
p.addrCodec,
154154
)
155+
if err != nil {
156+
return nil, ocr3types.ReportingPluginInfo{}, fmt.Errorf("failed to create ccip reader: %w", err)
157+
}
155158

156159
tokenDataObserver, err := observer.NewConfigBasedCompositeObservers(
157160
ctx,
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
package chainaccessor
2+
3+
import (
4+
"context"
5+
"time"
6+
7+
"github.com/smartcontractkit/chainlink-common/pkg/logger"
8+
"github.com/smartcontractkit/chainlink-common/pkg/types"
9+
10+
"github.com/smartcontractkit/chainlink-ccip/pkg/contractreader"
11+
cciptypes "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3"
12+
)
13+
14+
// LegacyAccessor is an implementation of cciptypes.ChainAccessor that allows the CCIPReader
15+
// to cutover and migrate away from depending directly on contract reader and contract writer.
16+
type LegacyAccessor struct {
17+
lggr logger.Logger
18+
chainSelector cciptypes.ChainSelector
19+
contractReader contractreader.Extended
20+
contractWriter types.ContractWriter
21+
addrCodec cciptypes.AddressCodec
22+
}
23+
24+
var _ cciptypes.ChainAccessor = (*LegacyAccessor)(nil)
25+
26+
func NewLegacyAccessor(
27+
lggr logger.Logger,
28+
chainSelector cciptypes.ChainSelector,
29+
contractReader contractreader.Extended,
30+
contractWriter types.ContractWriter,
31+
addrCodec cciptypes.AddressCodec,
32+
) cciptypes.ChainAccessor {
33+
return &LegacyAccessor{
34+
lggr: lggr,
35+
chainSelector: chainSelector,
36+
contractReader: contractReader,
37+
contractWriter: contractWriter,
38+
addrCodec: addrCodec,
39+
}
40+
}
41+
42+
func (l *LegacyAccessor) Metadata() cciptypes.AccessorMetadata {
43+
// TODO(NONEVM-1865): implement
44+
panic("implement me")
45+
}
46+
47+
func (l *LegacyAccessor) GetContractAddress(contractName string) ([]byte, error) {
48+
// TODO(NONEVM-1865): implement
49+
panic("implement me")
50+
}
51+
52+
func (l *LegacyAccessor) GetChainFeeComponents(
53+
ctx context.Context,
54+
) map[cciptypes.ChainSelector]cciptypes.ChainFeeComponents {
55+
// TODO(NONEVM-1865): implement
56+
panic("implement me")
57+
}
58+
59+
func (l *LegacyAccessor) GetDestChainFeeComponents(ctx context.Context) (types.ChainFeeComponents, error) {
60+
// TODO(NONEVM-1865): implement
61+
panic("implement me")
62+
}
63+
64+
func (l *LegacyAccessor) Sync(ctx context.Context, contracts cciptypes.ContractAddresses) error {
65+
// TODO(NONEVM-1865): implement
66+
panic("implement me")
67+
}
68+
69+
func (l *LegacyAccessor) MsgsBetweenSeqNums(
70+
ctx context.Context,
71+
dest cciptypes.ChainSelector,
72+
seqNumRange cciptypes.SeqNumRange,
73+
) ([]cciptypes.Message, error) {
74+
// TODO(NONEVM-1865): implement
75+
panic("implement me")
76+
}
77+
78+
func (l *LegacyAccessor) LatestMsgSeqNum(ctx context.Context, dest cciptypes.ChainSelector) (cciptypes.SeqNum, error) {
79+
// TODO(NONEVM-1865): implement
80+
panic("implement me")
81+
}
82+
83+
func (l *LegacyAccessor) GetExpectedNextSequenceNumber(
84+
ctx context.Context,
85+
dest cciptypes.ChainSelector,
86+
) (cciptypes.SeqNum, error) {
87+
// TODO(NONEVM-1865): implement
88+
panic("implement me")
89+
}
90+
91+
func (l *LegacyAccessor) GetTokenPriceUSD(
92+
ctx context.Context,
93+
address cciptypes.UnknownAddress,
94+
) (cciptypes.BigInt, error) {
95+
// TODO(NONEVM-1865): implement
96+
panic("implement me")
97+
}
98+
99+
func (l *LegacyAccessor) GetFeeQuoterDestChainConfig(
100+
ctx context.Context,
101+
dest cciptypes.ChainSelector,
102+
) (cciptypes.FeeQuoterDestChainConfig, error) {
103+
// TODO(NONEVM-1865): implement
104+
panic("implement me")
105+
}
106+
107+
func (l *LegacyAccessor) CommitReportsGTETimestamp(
108+
ctx context.Context,
109+
ts time.Time,
110+
limit int,
111+
) ([]cciptypes.CommitPluginReportWithMeta, error) {
112+
// TODO(NONEVM-1865): implement
113+
panic("implement me")
114+
}
115+
116+
func (l *LegacyAccessor) ExecutedMessages(
117+
ctx context.Context,
118+
ranges map[cciptypes.ChainSelector]cciptypes.SeqNumRange,
119+
confidence cciptypes.ConfidenceLevel,
120+
) (map[cciptypes.ChainSelector][]cciptypes.SeqNum, error) {
121+
// TODO(NONEVM-1865): implement
122+
panic("implement me")
123+
}
124+
125+
func (l *LegacyAccessor) NextSeqNum(
126+
ctx context.Context,
127+
sources []cciptypes.ChainSelector,
128+
) (seqNum map[cciptypes.ChainSelector]cciptypes.SeqNum, err error) {
129+
// TODO(NONEVM-1865): implement
130+
panic("implement me")
131+
}
132+
133+
func (l *LegacyAccessor) Nonces(
134+
ctx context.Context,
135+
addresses map[cciptypes.ChainSelector][]cciptypes.UnknownEncodedAddress,
136+
) (map[cciptypes.ChainSelector]map[string]uint64, error) {
137+
// TODO(NONEVM-1865): implement
138+
panic("implement me")
139+
}
140+
141+
func (l *LegacyAccessor) GetChainFeePriceUpdate(
142+
ctx context.Context,
143+
selectors []cciptypes.ChainSelector,
144+
) map[cciptypes.ChainSelector]cciptypes.TimestampedBig {
145+
// TODO(NONEVM-1865): implement
146+
panic("implement me")
147+
}
148+
149+
func (l *LegacyAccessor) GetLatestPriceSeqNr(ctx context.Context) (uint64, error) {
150+
// TODO(NONEVM-1865): implement
151+
panic("implement me")
152+
}
153+
154+
func (l *LegacyAccessor) GetOffRampConfigDigest(ctx context.Context, pluginType uint8) ([32]byte, error) {
155+
// TODO(NONEVM-1865): implement
156+
panic("implement me")
157+
}
158+
159+
func (l *LegacyAccessor) GetOffRampSourceChainsConfig(
160+
ctx context.Context,
161+
sourceChains []cciptypes.ChainSelector,
162+
) (map[cciptypes.ChainSelector]cciptypes.SourceChainConfig, error) {
163+
// TODO(NONEVM-1865): implement
164+
panic("implement me")
165+
}
166+
167+
func (l *LegacyAccessor) GetRMNRemoteConfig(ctx context.Context) (cciptypes.RemoteConfig, error) {
168+
// TODO(NONEVM-1865): implement
169+
panic("implement me")
170+
}
171+
172+
func (l *LegacyAccessor) GetRmnCurseInfo(ctx context.Context) (cciptypes.CurseInfo, error) {
173+
// TODO(NONEVM-1865): implement
174+
panic("implement me")
175+
}

pkg/reader/ccip.go

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424

2525
"github.com/smartcontractkit/chainlink-ccip/internal/libs/slicelib"
2626
"github.com/smartcontractkit/chainlink-ccip/pkg/addressbook"
27+
"github.com/smartcontractkit/chainlink-ccip/pkg/chainaccessor"
2728
"github.com/smartcontractkit/chainlink-ccip/pkg/consts"
2829
"github.com/smartcontractkit/chainlink-ccip/pkg/contractreader"
2930
"github.com/smartcontractkit/chainlink-ccip/pkg/logutil"
@@ -39,11 +40,13 @@ type ccipChainReader struct {
3940
lggr logger.Logger
4041
contractReaders map[cciptypes.ChainSelector]contractreader.Extended
4142
contractWriters map[cciptypes.ChainSelector]types.ContractWriter
42-
destChain cciptypes.ChainSelector
43-
offrampAddress string
44-
configPoller ConfigPoller
45-
addrCodec cciptypes.AddressCodec
46-
donAddressBook *addressbook.Book
43+
accessors map[cciptypes.ChainSelector]cciptypes.ChainAccessor
44+
45+
destChain cciptypes.ChainSelector
46+
offrampAddress string
47+
configPoller ConfigPoller
48+
addrCodec cciptypes.AddressCodec
49+
donAddressBook *addressbook.Book
4750
}
4851

4952
func newCCIPChainReaderInternal(
@@ -54,21 +57,35 @@ func newCCIPChainReaderInternal(
5457
destChain cciptypes.ChainSelector,
5558
offrampAddress []byte,
5659
addrCodec cciptypes.AddressCodec,
57-
) *ccipChainReader {
60+
) (*ccipChainReader, error) {
5861
var crs = make(map[cciptypes.ChainSelector]contractreader.Extended)
62+
var cas = make(map[cciptypes.ChainSelector]cciptypes.ChainAccessor)
63+
5964
for chainSelector, cr := range contractReaders {
6065
crs[chainSelector] = contractreader.NewExtendedContractReader(cr)
66+
if contractWriters[chainSelector] == nil {
67+
return nil, fmt.Errorf("contract writer for chain %s is not provided", chainSelector)
68+
}
69+
cas[chainSelector] = chainaccessor.NewLegacyAccessor(
70+
lggr,
71+
chainSelector,
72+
crs[chainSelector],
73+
contractWriters[chainSelector],
74+
addrCodec,
75+
)
6176
}
6277

6378
offrampAddrStr, err := addrCodec.AddressBytesToString(offrampAddress, destChain)
6479
if err != nil {
80+
// Panic here since the entire discovery process relies on the offramp address being valid.
6581
panic(fmt.Sprintf("failed to convert offramp address to string: %v", err))
6682
}
6783

6884
reader := &ccipChainReader{
6985
lggr: lggr,
7086
contractReaders: crs,
7187
contractWriters: contractWriters,
88+
accessors: cas,
7289
destChain: destChain,
7390
offrampAddress: offrampAddrStr,
7491
addrCodec: addrCodec,
@@ -95,7 +112,7 @@ func newCCIPChainReaderInternal(
95112
lggr.Errorw("failed to start config background polling", "err", err)
96113
}
97114

98-
return reader
115+
return reader, nil
99116
}
100117

101118
// WithExtendedContractReader sets the extended contract reader for the provided chain.

0 commit comments

Comments
 (0)