Skip to content

Commit c901c5a

Browse files
Chore: Reuse Aptos field renaming (#49)
* add ability to rename response fields from CR functions * hexify * use Aptos field rename type definition * re-use Aptos field renaming method * fix tests * lint fixes --------- Co-authored-by: stackman27 <sishir.giri@smartcontract.com>
1 parent 995b7e2 commit c901c5a

File tree

3 files changed

+20
-60
lines changed

3 files changed

+20
-60
lines changed

relayer/chainreader/config/config.go

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55

66
"github.com/smartcontractkit/chainlink-sui/relayer/client"
77

8+
aptosCRConfig "github.com/smartcontractkit/chainlink-aptos/relayer/chainreader/config"
89
"github.com/smartcontractkit/chainlink-sui/relayer/codec"
910
)
1011

@@ -32,7 +33,7 @@ type ChainReaderFunction struct {
3233
// Defines a way to transform a tuple result into a JSON object
3334
ResultTupleToStruct []string
3435
// Defines a mapping for renaming response fields
35-
ResultFieldRenames map[string]RenamedField
36+
ResultFieldRenames map[string]aptosCRConfig.RenamedField
3637
}
3738

3839
type ChainReaderEvent struct {
@@ -45,21 +46,12 @@ type ChainReaderEvent struct {
4546
client.EventSelector
4647

4748
// Renames of event field names (optional). When not provided, the field names are used as-is.
48-
EventFieldRenames map[string]RenamedField
49+
EventFieldRenames map[string]aptosCRConfig.RenamedField
4950

5051
// Renames provided filters to match the event field names (optional). When not provided, the filters are used as-is.
5152
EventFilterRenames map[string]string
5253
}
5354

54-
type RenamedField struct {
55-
// The new field name (optional). This does not need to be provided if this field does not need
56-
// to be renamed.
57-
NewName string
58-
59-
// Rename sub-fields. This assumes that the event field value is a struct or a map with string keys.
60-
SubFieldRenames map[string]RenamedField
61-
}
62-
6355
type EventsIndexerConfig struct {
6456
PollingInterval time.Duration
6557
SyncTimeout time.Duration

relayer/chainreader/reader/chainreader.go

Lines changed: 14 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import (
1919
"github.com/smartcontractkit/chainlink-aptos/relayer/chainreader/loop"
2020

2121
aptosCRConfig "github.com/smartcontractkit/chainlink-aptos/relayer/chainreader/config"
22-
craptosutils "github.com/smartcontractkit/chainlink-aptos/relayer/chainreader/utils"
22+
aptosCRUtils "github.com/smartcontractkit/chainlink-aptos/relayer/chainreader/utils"
2323

2424
"github.com/smartcontractkit/chainlink-sui/relayer/chainreader/config"
2525
"github.com/smartcontractkit/chainlink-sui/relayer/chainreader/database"
@@ -202,7 +202,10 @@ func (s *suiChainReader) GetLatestValue(ctx context.Context, readIdentifier stri
202202

203203
// Apply result field renames if configured
204204
if functionConfig.ResultFieldRenames != nil {
205-
structResult = applyResultFieldRenames(structResult, functionConfig.ResultFieldRenames).(map[string]any)
205+
err = aptosCRUtils.MaybeRenameFields(structResult, functionConfig.ResultFieldRenames)
206+
if err != nil {
207+
return fmt.Errorf("failed to rename result fields in GetLatestValue: %w", err)
208+
}
206209
}
207210

208211
// if we are running in loop plugin mode, we will want to encode the result into JSON bytes
@@ -218,7 +221,10 @@ func (s *suiChainReader) GetLatestValue(ctx context.Context, readIdentifier stri
218221
// Apply renames to the result slice or contained maps before encoding
219222
var renamed any = results
220223
if functionConfig.ResultFieldRenames != nil {
221-
renamed = applyResultFieldRenames(renamed, functionConfig.ResultFieldRenames)
224+
err = aptosCRUtils.MaybeRenameFields(renamed, functionConfig.ResultFieldRenames)
225+
if err != nil {
226+
return fmt.Errorf("failed to rename result fields in GetLatestValue: %w", err)
227+
}
222228
}
223229
return s.encodeLoopResult(renamed, returnVal)
224230
}
@@ -228,7 +234,10 @@ func (s *suiChainReader) GetLatestValue(ctx context.Context, readIdentifier stri
228234
// Apply renames (if any) to the primary result element before decoding
229235
var primary any = results[0]
230236
if functionConfig.ResultFieldRenames != nil {
231-
primary = applyResultFieldRenames(primary, functionConfig.ResultFieldRenames)
237+
err = aptosCRUtils.MaybeRenameFields(primary, functionConfig.ResultFieldRenames)
238+
if err != nil {
239+
return fmt.Errorf("failed to rename result fields in GetLatestValue: %w", err)
240+
}
232241
}
233242

234243
// TODO: handle multiple results for non-loop plugin mode
@@ -731,47 +740,6 @@ func (s *suiChainReader) encodeLoopResult(valueField any, returnVal any) error {
731740
return nil
732741
}
733742

734-
// applyResultFieldRenames applies field and sub-field renames to a value.
735-
// It supports:
736-
// - map[string]any: renames top-level keys and recurses for sub-fields if configured
737-
// - []any: applies renames to each element (useful when each element is a map)
738-
// - primitives or other types: returned as-is
739-
func applyResultFieldRenames(value any, renames map[string]config.RenamedField) any {
740-
switch typed := value.(type) {
741-
case map[string]any:
742-
result := make(map[string]any, len(typed))
743-
for key, val := range typed {
744-
// Check if this field has a rename rule
745-
if rule, ok := renames[key]; ok {
746-
newKey := key
747-
if rule.NewName != "" {
748-
newKey = rule.NewName
749-
}
750-
// Recurse into sub-fields if both val and rule specify them
751-
if rule.SubFieldRenames != nil {
752-
result[newKey] = applyResultFieldRenames(val, rule.SubFieldRenames)
753-
} else {
754-
result[newKey] = val
755-
}
756-
} else {
757-
// Preserve original field if no rename rule exists
758-
result[key] = val
759-
}
760-
}
761-
return result
762-
case []any:
763-
// Apply renames to each element; if the element is a map, it will be handled above
764-
out := make([]any, len(typed))
765-
for i := range typed {
766-
out[i] = applyResultFieldRenames(typed[i], renames)
767-
}
768-
return out
769-
default:
770-
// No transformation for primitives or unsupported types
771-
return value
772-
}
773-
}
774-
775743
// getEventConfig retrieves event configuration for the given key
776744
func (s *suiChainReader) getEventConfig(moduleConfig *config.ChainReaderModule, eventKey string) (*config.ChainReaderEvent, error) {
777745
if moduleConfig.Events == nil {
@@ -809,7 +777,7 @@ func (s *suiChainReader) queryEvents(ctx context.Context, eventConfig *config.Ch
809777
}
810778

811779
if eventConfig.EventFilterRenames != nil {
812-
expressions = craptosutils.ApplyEventFilterRenames(expressions, eventConfig.EventFilterRenames)
780+
expressions = aptosCRUtils.ApplyEventFilterRenames(expressions, eventConfig.EventFilterRenames)
813781
}
814782

815783
// Query events from database

relayer/chainreader/reader/chainreader_local_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ func runChainReaderCounterTest(t *testing.T, log logger.Logger, rpcUrl string) {
123123
Name: "get_address_list",
124124
SignerAddress: accountAddress,
125125
Params: []codec.SuiFunctionParam{}, // No parameters needed
126-
ResultFieldRenames: map[string]config.RenamedField{
126+
ResultFieldRenames: map[string]aptosCRConfig.RenamedField{
127127
"addresses": {NewName: "wallets"},
128128
"count": {NewName: "size"},
129129
},
@@ -137,7 +137,7 @@ func runChainReaderCounterTest(t *testing.T, log logger.Logger, rpcUrl string) {
137137
Name: "get_simple_result",
138138
SignerAddress: accountAddress,
139139
Params: []codec.SuiFunctionParam{}, // No parameters needed
140-
ResultFieldRenames: map[string]config.RenamedField{
140+
ResultFieldRenames: map[string]aptosCRConfig.RenamedField{
141141
"value": {NewName: "renamedValue"},
142142
},
143143
},
@@ -152,7 +152,7 @@ func runChainReaderCounterTest(t *testing.T, log logger.Logger, rpcUrl string) {
152152
SignerAddress: accountAddress,
153153
Params: []codec.SuiFunctionParam{}, // No parameters needed
154154
ResultTupleToStruct: []string{"value", "address", "bool", "struct_tag"},
155-
ResultFieldRenames: map[string]config.RenamedField{
155+
ResultFieldRenames: map[string]aptosCRConfig.RenamedField{
156156
"value": {NewName: "answer"},
157157
"struct_tag": {NewName: "tag"},
158158
},

0 commit comments

Comments
 (0)