@@ -3,6 +3,7 @@ package chainaccessor
3
3
import (
4
4
"context"
5
5
"crypto/sha3"
6
+ "encoding/json"
6
7
"errors"
7
8
"fmt"
8
9
"math/big"
72
73
execStateChangedStatePath = consts .EventAttributeState
73
74
)
74
75
76
+ // Map of relevant events and their metadata required to build the codec and bind program addresses
75
77
var eventFilterConfigMap = map [string ]filterConfig {
76
78
consts .EventNameCCIPMessageSent : {
77
79
idl : ccipRouterIDL ,
@@ -126,6 +128,40 @@ func (a *SolanaAccessor) bindContractEvent(ctx context.Context, contractName str
126
128
return nil
127
129
}
128
130
131
+ func buildEventsCodec () (types.RemoteCodec , error ) {
132
+ parsed := & codec.ParsedTypes {
133
+ DecoderDefs : make (map [string ]codec.Entry ),
134
+ }
135
+
136
+ for eventName , eventCfg := range eventFilterConfigMap {
137
+ var codecIDL codec.IDL
138
+ if err := json .Unmarshal ([]byte (eventCfg .idl ), & codecIDL ); err != nil {
139
+ return nil , fmt .Errorf ("unexpected error: invalid CCIP OffRamp IDL, error: %w" , err )
140
+ }
141
+
142
+ idlDef , err := codec .FindDefinitionFromIDL (codec .ChainConfigTypeInstructionDef , eventName , codecIDL )
143
+ if err != nil {
144
+ return nil , err
145
+ }
146
+ eventIdl , isOk := idlDef .(codec.IdlEvent )
147
+ if ! isOk {
148
+ return nil , fmt .Errorf ("unexpected type from IDL definition for event read: %q" , eventName )
149
+ }
150
+ entry , err := codec .CreateCodecEntry (eventIdl , eventName , codecIDL , nil )
151
+ if err != nil {
152
+ return nil , fmt .Errorf ("failed to create codec entry for event %s, error: %w" , eventName , err )
153
+ }
154
+ parsed .DecoderDefs [eventName ] = entry
155
+ }
156
+
157
+ codec , err := parsed .ToCodec ()
158
+ if err != nil {
159
+ return nil , fmt .Errorf ("failed to build codec: %w" , err )
160
+ }
161
+
162
+ return codec , nil
163
+ }
164
+
129
165
// registerFilterIfNotExists registers a filter for the given event if it doesn't already exist.
130
166
func (a * SolanaAccessor ) registerFilterIfNotExists (
131
167
ctx context.Context ,
@@ -173,13 +209,13 @@ func (a *SolanaAccessor) registerFilterIfNotExists(
173
209
// chainaccessor.SendRequestedEvent. This function is idempotent and performs a
174
210
// one-to-one mapping of event fields from the Solana format to the standard CCIP format.
175
211
func (a * SolanaAccessor ) convertCCIPMessageSent (ctx context.Context , logs []logpollertypes.Log , onrampAddr solana.PublicKey ) ([]* chainaccessor.SendRequestedEvent , error ) {
176
- iter , err := a .decodeLogsIntoSequences (ctx , logs , & ccip.EventCCIPMessageSent {})
212
+ iter , err := a .decodeLogsIntoSequences (ctx , consts . EventNameCCIPMessageSent , logs , & ccip.EventCCIPMessageSent {})
177
213
if err != nil {
178
214
return nil , fmt .Errorf ("failed to decode logs into sequences: %w" , err )
179
215
}
180
216
181
217
if len (logs ) != len (iter ) {
182
- return nil , fmt .Errorf ("failed to convert all logs into generic ccip event, logs %d, events %s " , len (logs ), len (iter ))
218
+ return nil , fmt .Errorf ("failed to convert all logs into generic ccip event, logs %d, events %d " , len (logs ), len (iter ))
183
219
}
184
220
185
221
genericEvents := make ([]* chainaccessor.SendRequestedEvent , 0 )
@@ -269,7 +305,7 @@ func processSubKeyPaths(cfg filterConfig) [][]string {
269
305
func (a * SolanaAccessor ) processCommitReports (
270
306
ctx context.Context , logs []logpollertypes.Log , ts time.Time , limit int ,
271
307
) ([]ccipocr3.CommitPluginReportWithMeta , error ) {
272
- iter , err := a .decodeLogsIntoSequences (ctx , logs , & ccip.EventCommitReportAccepted {})
308
+ iter , err := a .decodeLogsIntoSequences (ctx , consts . EventNameCommitReportAccepted , logs , & ccip.EventCommitReportAccepted {})
273
309
if err != nil {
274
310
return nil , fmt .Errorf ("failed to decode logs into sequences: %w" , err )
275
311
}
@@ -490,7 +526,7 @@ func createExecutedMessagesKeyFilter(rangesPerChain map[ccipocr3.ChainSelector][
490
526
}
491
527
492
528
func (a * SolanaAccessor ) processExecutionStateChangesEvents (ctx context.Context , logs []logpollertypes.Log , nonEmptyRangesPerChain map [ccipocr3.ChainSelector ][]ccipocr3.SeqNumRange ) (map [ccipocr3.ChainSelector ][]ccipocr3.SeqNum , error ) {
493
- iter , err := a .decodeLogsIntoSequences (ctx , logs , & ccip.EventExecutionStateChanged {})
529
+ iter , err := a .decodeLogsIntoSequences (ctx , consts . EventNameExecutionStateChanged , logs , & ccip.EventExecutionStateChanged {})
494
530
if err != nil {
495
531
return nil , fmt .Errorf ("failed to decode logs into sequences: %w" , err )
496
532
}
@@ -545,6 +581,7 @@ func validateExecutionStateChangedEvent(
545
581
546
582
func (a * SolanaAccessor ) decodeLogsIntoSequences (
547
583
ctx context.Context ,
584
+ eventName string ,
548
585
logs []logpollertypes.Log ,
549
586
into any ,
550
587
) ([]types.Sequence , error ) {
@@ -572,15 +609,17 @@ func (a *SolanaAccessor) decodeLogsIntoSequences(
572
609
// create a new value of the same type as 'into' for the data to be extracted to
573
610
sequences [idx ].Data = typeVal .Interface ()
574
611
575
- if err := a .decodeLog (ctx , & logs [idx ], sequences [idx ].Data ); err != nil {
612
+ if err := a .decodeLog (ctx , eventName , logs [idx ], sequences [idx ].Data ); err != nil {
576
613
return nil , err
577
614
}
578
615
}
579
616
580
617
return sequences , nil
581
618
}
582
619
583
- func (a * SolanaAccessor ) decodeLog (ctx context.Context , log * logpollertypes.Log , into any ) error {
584
- // TODO: add decoding logic
585
- return errors .New ("not implemented" )
620
+ func (a * SolanaAccessor ) decodeLog (ctx context.Context , eventName string , log logpollertypes.Log , into any ) error {
621
+ if err := a .codec .Decode (ctx , log .Data , into , eventName ); err != nil {
622
+ return fmt .Errorf ("%w: failed to decode log data for event %s: %s" , types .ErrInvalidType , eventName , err .Error ())
623
+ }
624
+ return nil
586
625
}
0 commit comments