Skip to content

Commit c7e59e1

Browse files
committed
Addressed TODOs
1 parent 4bb61db commit c7e59e1

File tree

3 files changed

+77
-42
lines changed

3 files changed

+77
-42
lines changed

pkg/solana/ccip/chainaccessor/config.go

Lines changed: 57 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,57 +20,90 @@ import (
2020
// https://github.com/smartcontractkit/chainlink-ccip/blob/7cae1b8434dd376eb70f2ddaace43093982f3a57/chains/solana/contracts/programs/rmn-remote/src/state.rs#L20-L27
2121
var globalCurseValue = []byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
2222

23-
// getOffRampStaticConfig retrieves static configuration for the off-ramp contract
24-
func (a *SolanaAccessor) getOffRampStaticConfig(ctx context.Context) (ccipocr3.OffRampStaticChainConfig, error) {
23+
// getOffRampConfig retrieves static, dynamic, commitOCR3, and execOCR3 configurations for the off-ramp contract
24+
func (a *SolanaAccessor) getOffRampConfig(ctx context.Context) (ccipocr3.OfframpConfig, error) {
2525
offrampAddr, err := a.getBinding(consts.ContractNameOffRamp)
2626
if err != nil {
27-
return ccipocr3.OffRampStaticChainConfig{}, fmt.Errorf("failed to get binding for offramp: %w", err)
27+
return ccipocr3.OfframpConfig{}, fmt.Errorf("failed to get binding for offramp: %w", err)
2828
}
2929

3030
config, err := a.getOfframpConfig(ctx, offrampAddr)
3131
if err != nil {
32-
return ccipocr3.OffRampStaticChainConfig{}, err
32+
return ccipocr3.OfframpConfig{}, err
3333
}
3434

3535
offrampRefAddress, err := a.getOfframpReferenceAddresses(ctx, offrampAddr)
3636
if err != nil {
37-
return ccipocr3.OffRampStaticChainConfig{}, err
37+
return ccipocr3.OfframpConfig{}, err
3838
}
3939

40-
return ccipocr3.OffRampStaticChainConfig{
40+
staticConfig := ccipocr3.OffRampStaticChainConfig{
4141
ChainSelector: ccipocr3.ChainSelector(config.SvmChainSelector),
4242
GasForCallExactCheck: 0,
4343
RmnRemote: offrampRefAddress.RmnRemote.Bytes(),
4444
TokenAdminRegistry: []byte{}, // PDA dependent on the token address
4545
NonceManager: offrampRefAddress.Router.Bytes(),
46-
}, nil
47-
}
46+
}
4847

49-
// getOffRampDynamicConfig retrieves dynamic configuration for the off-ramp contract
50-
func (a *SolanaAccessor) getOffRampDynamicConfig(ctx context.Context) (ccipocr3.OffRampDynamicChainConfig, error) {
51-
offrampAddr, err := a.getBinding(consts.ContractNameOffRamp)
52-
if err != nil {
53-
return ccipocr3.OffRampDynamicChainConfig{}, fmt.Errorf("failed to get binding for offramp: %w", err)
48+
dynamicConfig := ccipocr3.OffRampDynamicChainConfig{
49+
FeeQuoter: offrampRefAddress.FeeQuoter.Bytes(),
50+
PermissionLessExecutionThresholdSeconds: uint32(config.EnableManualExecutionAfter), // nolint:gosec // G115: value validated to be within uint32 max above
51+
IsRMNVerificationDisabled: true,
52+
MessageInterceptor: []byte{}, // expected to be empty for solana
5453
}
5554

56-
config, err := a.getOfframpConfig(ctx, offrampAddr)
57-
if err != nil {
58-
return ccipocr3.OffRampDynamicChainConfig{}, err
55+
commitConfig := config.Ocr3[0]
56+
commitOCR3Config := ccipocr3.OCRConfigResponse{
57+
OCRConfig: ccipocr3.OCRConfig{
58+
ConfigInfo: ccipocr3.ConfigInfo{
59+
ConfigDigest: commitConfig.ConfigInfo.ConfigDigest,
60+
F: commitConfig.ConfigInfo.F,
61+
N: commitConfig.ConfigInfo.N,
62+
IsSignatureVerificationEnabled: commitConfig.ConfigInfo.IsSignatureVerificationEnabled == 1,
63+
},
64+
Signers: convertSignersType(commitConfig.Signers),
65+
Transmitters: convertTransmittersType(commitConfig.Transmitters),
66+
},
5967
}
6068

61-
offrampRefAddress, err := a.getOfframpReferenceAddresses(ctx, offrampAddr)
62-
if err != nil {
63-
return ccipocr3.OffRampDynamicChainConfig{}, err
69+
executeConfig := config.Ocr3[1]
70+
executeOCR3Config := ccipocr3.OCRConfigResponse{
71+
OCRConfig: ccipocr3.OCRConfig{
72+
ConfigInfo: ccipocr3.ConfigInfo{
73+
ConfigDigest: executeConfig.ConfigInfo.ConfigDigest,
74+
F: executeConfig.ConfigInfo.F,
75+
N: executeConfig.ConfigInfo.N,
76+
IsSignatureVerificationEnabled: executeConfig.ConfigInfo.IsSignatureVerificationEnabled == 1,
77+
},
78+
Signers: convertSignersType(executeConfig.Signers),
79+
Transmitters: convertTransmittersType(executeConfig.Transmitters),
80+
},
6481
}
6582

66-
return ccipocr3.OffRampDynamicChainConfig{
67-
FeeQuoter: offrampRefAddress.FeeQuoter.Bytes(),
68-
PermissionLessExecutionThresholdSeconds: uint32(config.EnableManualExecutionAfter), // TODO: is this conversion dangerous?
69-
IsRMNVerificationDisabled: true,
70-
MessageInterceptor: []byte{},
83+
return ccipocr3.OfframpConfig{
84+
CommitLatestOCRConfig: commitOCR3Config,
85+
ExecLatestOCRConfig: executeOCR3Config,
86+
StaticConfig: staticConfig,
87+
DynamicConfig: dynamicConfig,
7188
}, nil
7289
}
7390

91+
func convertSignersType(signers [16][20]uint8) [][]byte {
92+
newSigners := make([][]byte, 0, len(signers))
93+
for _, signer := range signers {
94+
newSigners = append(newSigners, signer[:])
95+
}
96+
return newSigners
97+
}
98+
99+
func convertTransmittersType(transmitters [16][32]uint8) [][]byte {
100+
newTransmitters := make([][]byte, 0, len(transmitters))
101+
for _, transmitter := range transmitters {
102+
newTransmitters = append(newTransmitters, transmitter[:])
103+
}
104+
return newTransmitters
105+
}
106+
74107
// getOffRampSourceChainConfigs retrieves source chain configurations from the off-ramp contract
75108
func (a *SolanaAccessor) getOffRampSourceChainConfigs(ctx context.Context, sourceChainSelectors []ccipocr3.ChainSelector) (map[ccipocr3.ChainSelector]ccipocr3.SourceChainConfig, error) {
76109
offrampAddr, err := a.getBinding(consts.ContractNameOffRamp)

pkg/solana/ccip/chainaccessor/solana_accessor.go

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"errors"
66
"fmt"
7+
"math"
78
"math/big"
89
"sync"
910
"time"
@@ -62,9 +63,12 @@ func NewSolanaAccessor(
6263
fee fees.Estimator,
6364
addrCodec ccipocr3.ChainSpecificAddressCodec,
6465
) (*SolanaAccessor, error) {
65-
// TODO: validate state of client and logPoller (should be initialized in NewChain)
6666
lggr := logger.Named(l, "SolanaAccessor")
6767

68+
if err := logPoller.Ready(); err != nil {
69+
return nil, fmt.Errorf("log poller not ready: %w", err)
70+
}
71+
6872
codec, err := buildEventsCodec()
6973
if err != nil {
7074
return nil, fmt.Errorf("failed to build codec parsed types: %w", err)
@@ -105,22 +109,11 @@ func (a *SolanaAccessor) GetAllConfigsLegacy(ctx context.Context, destChainSelec
105109
// we're fetching config on the destination chain (offramp + fee quoter static config + RMN)
106110

107111
// OffRamp
108-
offrampStaticConfig, err := a.getOffRampStaticConfig(ctx)
112+
offrampConfig, err := a.getOffRampConfig(ctx)
109113
if !errors.Is(err, ErrNoBindings) && err != nil {
110114
return ccipocr3.ChainConfigSnapshot{}, nil, fmt.Errorf("failed to get current offramp static config: %w", err)
111115
}
112-
// TODO: assert offrampStaticConfig.ChainSelector == destChainSelector as a quick sanity check
113-
offrampDynamicConfig, err := a.getOffRampDynamicConfig(ctx)
114-
if !errors.Is(err, ErrNoBindings) && err != nil {
115-
return ccipocr3.ChainConfigSnapshot{}, nil, fmt.Errorf("failed to get current offramp dynamic config: %w", err)
116-
}
117-
config.Offramp = ccipocr3.OfframpConfig{
118-
// TODO: read OCR config from contract
119-
CommitLatestOCRConfig: ccipocr3.OCRConfigResponse{},
120-
ExecLatestOCRConfig: ccipocr3.OCRConfigResponse{},
121-
StaticConfig: offrampStaticConfig,
122-
DynamicConfig: offrampDynamicConfig,
123-
}
116+
config.Offramp = offrampConfig
124117

125118
// FeeQuoter
126119
feeQuoterStaticConfig, err := a.getFeeQuoterStaticConfig(ctx)
@@ -131,11 +124,17 @@ func (a *SolanaAccessor) GetAllConfigsLegacy(ctx context.Context, destChainSelec
131124
StaticConfig: feeQuoterStaticConfig,
132125
}
133126

127+
rmnRemoteProxyAddr, err := a.getBinding(consts.ContractNameRMNProxy)
128+
if !errors.Is(err, ErrNoBindings) && err != nil {
129+
return ccipocr3.ChainConfigSnapshot{}, nil, fmt.Errorf("failed to get binding for rmn remote proxy: %w", err)
130+
}
131+
134132
// RMN
135133
// TODO: RMNProxy should be an implementation detail hidden behind chainAccessor
136134
config.RMNProxy = ccipocr3.RMNProxyConfig{
137135
// TODO: point at a rmnremote address/router/offramp to allow fetching curseinfo
138-
RemoteAddress: nil,
136+
// There is no proxy for Solana so is it right to just set the "proxy" address as the remote address here?
137+
RemoteAddress: rmnRemoteProxyAddr.Bytes(),
139138
}
140139
config.RMNRemote = ccipocr3.RMNRemoteConfig{
141140
// We don't support RMN so return an empty config
@@ -382,10 +381,13 @@ func (a *SolanaAccessor) GetTokenPriceUSD(ctx context.Context, rawTokenAddress c
382381
return ccipocr3.TimestampedUnixBig{}, fmt.Errorf("failed to get fee quoter billing token config account: %w", err)
383382
}
384383
value := new(big.Int).SetBytes(billingTokenConfig.UsdPerToken.Value[:])
384+
if billingTokenConfig.UsdPerToken.Timestamp > math.MaxUint32 {
385+
return ccipocr3.TimestampedUnixBig{}, fmt.Errorf("billing token config timestamp exceeds uint32 max: %d", billingTokenConfig.UsdPerToken.Timestamp)
386+
}
385387
return ccipocr3.TimestampedUnixBig{
386388
Value: value,
387389
// TODO: u64 -> u32? should we fix the onchain type?
388-
Timestamp: uint32(billingTokenConfig.UsdPerToken.Timestamp), //nolint:gosec // G115
390+
Timestamp: uint32(billingTokenConfig.UsdPerToken.Timestamp), //nolint:gosec // G115: validated to be within uint32 max above
389391
}, nil
390392
}
391393

@@ -447,7 +449,7 @@ func (a *SolanaAccessor) CommitReportsGTETimestamp(ctx context.Context, ts time.
447449
limitSort := query.LimitAndSort{
448450
SortBy: []query.SortBy{query.NewSortBySequence(query.Asc)},
449451
Limit: query.Limit{
450-
Count: uint64(internalLimit), // nolint:gosec // G115: limit can never reasonably exceed uint64 max // TODO: why do we use 2 x limit here?
452+
Count: uint64(internalLimit), // nolint:gosec // G115: limit can never reasonably exceed uint64 max
451453
},
452454
}
453455

pkg/solana/ccip/provider/provider.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ func NewCCIPProvider(lggr logger.Logger, chainSelector ccipocr3.ChainSelector, c
5656
return &Provider{
5757
lggr: logger.Named(lggr, CCIPProviderName),
5858
ca: ca,
59-
ct: nil, // unimplemented
59+
ct: nil, // TODO: unimplemented
6060
codec: c,
6161
}, nil
6262
}

0 commit comments

Comments
 (0)