diff --git a/pkg/solana/codec/codec_entry.go b/pkg/solana/codec/codec_entry.go index 3e14490ef..c338206e6 100644 --- a/pkg/solana/codec/codec_entry.go +++ b/pkg/solana/codec/codec_entry.go @@ -29,18 +29,26 @@ func NewEntry(idl IDL, idlTypeDef IdlTypeDef, includeDiscriminator bool, mod cod mod = codec.MultiModifier{} } - _, accCodec, err := createCodecType(idlTypeDef, refs, includeDiscriminator) + _, accCodec, err := createCodecType(idlTypeDef, refs, false) if err != nil { return nil, err } - return &codecEntry{codecType: accCodec, typ: accCodec.GetType(), mod: mod}, nil + entry := &codecEntry{name: idlTypeDef.Name, includeDiscriminator: includeDiscriminator, codecType: accCodec, typ: accCodec.GetType(), mod: mod} + if entry.includeDiscriminator { + entry.Discriminator = commonencodings.NamedTypeCodec{Name: "Discriminator" + idlTypeDef.Name, Codec: NewDiscriminator(idlTypeDef.Name)} + } + + return entry, nil } type codecEntry struct { - typ reflect.Type - codecType commonencodings.TypeCodec - mod codec.Modifier + name string + includeDiscriminator bool + Discriminator commonencodings.NamedTypeCodec + typ reflect.Type + codecType commonencodings.TypeCodec + mod codec.Modifier } func (entry *codecEntry) GetType() reflect.Type { @@ -52,10 +60,28 @@ func (entry *codecEntry) GetCodecType() commonencodings.TypeCodec { } func (entry *codecEntry) Encode(value any, into []byte) ([]byte, error) { - return entry.codecType.Encode(value, into) + encodedVal, err := entry.codecType.Encode(value, into) + if err != nil { + return nil, err + } + + if entry.includeDiscriminator { + var byt []byte + disc := NewDiscriminator(entry.name) + encodedDisc, err := disc.Encode(&disc.hashPrefix, byt) + if err != nil { + return nil, err + } + return append(encodedDisc, encodedVal...), nil + } + + return encodedVal, nil } func (entry *codecEntry) Decode(encoded []byte) (any, []byte, error) { + if entry.includeDiscriminator { + encoded = encoded[discriminatorLength:] + } return entry.codecType.Decode(encoded) } diff --git a/pkg/solana/codec/codec_test.go b/pkg/solana/codec/codec_test.go index f531c7205..949bd01d3 100644 --- a/pkg/solana/codec/codec_test.go +++ b/pkg/solana/codec/codec_test.go @@ -4,16 +4,11 @@ import ( "bytes" _ "embed" "encoding/json" - "fmt" - "math/big" - "reflect" "slices" - "strings" "testing" bin "github.com/gagliardetto/binary" "github.com/gagliardetto/solana-go" - "github.com/smartcontractkit/libocr/commontypes" ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/stretchr/testify/require" @@ -21,8 +16,8 @@ import ( clcommontypes "github.com/smartcontractkit/chainlink-common/pkg/types" . "github.com/smartcontractkit/chainlink-common/pkg/types/interfacetests" //nolint common practice to import test mods with . "github.com/smartcontractkit/chainlink-solana/pkg/solana/codec" - "github.com/smartcontractkit/chainlink-solana/pkg/solana/codec/generated/test_item_type" "github.com/smartcontractkit/chainlink-solana/pkg/solana/codec/testutils" + "github.com/smartcontractkit/chainlink-solana/pkg/solana/codec/testutils/test_item_type" ) const anyExtraValue = 3 @@ -49,7 +44,7 @@ func (it *codecInterfaceTester) GetAccountString(i int) string { } func (it *codecInterfaceTester) EncodeFields(t *testing.T, request *EncodeRequest) []byte { - if request.TestOn == TestItemType { + if request.TestOn == testutils.TestItemType { return encodeFieldsOnItem(t, request) } @@ -58,83 +53,34 @@ func (it *codecInterfaceTester) EncodeFields(t *testing.T, request *EncodeReques func encodeFieldsOnItem(t *testing.T, request *EncodeRequest) ocr2types.Report { buf := new(bytes.Buffer) - if err := encodeRequestToTestStruct(request).MarshalWithEncoder(bin.NewBorshEncoder(buf)); err != nil { + if err := testutils.EncodeRequestToTestStruct(request).MarshalWithEncoder(bin.NewBorshEncoder(buf)); err != nil { require.NoError(t, err) } return buf.Bytes() } -func encodeRequestToTestStruct(request *EncodeRequest) test_item_type.TestStruct { - byt := [32]byte{} - for i, v := range request.TestStructs[0].OracleIDs { - byt[i] = byte(v) - } - - k, _ := solana.PublicKeyFromBase58(request.TestStructs[0].AccountStruct.AccountStr) - - accs := make([]solana.PublicKey, len(request.TestStructs[0].Accounts)) - for i, v := range request.TestStructs[0].Accounts { - accs[i] = solana.PublicKeyFromBytes(v) - } - - testStruct := test_item_type.TestStruct{ - Field: *request.TestStructs[0].Field, - OracleId: uint8(request.TestStructs[0].OracleID), - OracleIds: byt, - AccountStruct: test_item_type.AccountStruct{ - Account: solana.PublicKeyFromBytes(request.TestStructs[0].AccountStruct.Account), - AccountStr: k, - }, - Accounts: accs, - DifferentField: request.TestStructs[0].DifferentField, - BigField: bin.Int128{ - Lo: request.TestStructs[0].BigField.Uint64(), - Hi: new(big.Int).Rsh(request.TestStructs[0].BigField, 64).Uint64(), - }, - NestedDynamicStruct: test_item_type.NestedDynamic{ - FixedBytes: request.TestStructs[0].NestedDynamicStruct.FixedBytes, - Inner: test_item_type.InnerDynamic{ - IntVal: int64(request.TestStructs[0].NestedDynamicStruct.Inner.I), - S: request.TestStructs[0].NestedDynamicStruct.Inner.S, - }, - }, - NestedStaticStruct: test_item_type.NestedStatic{ - FixedBytes: request.TestStructs[0].NestedStaticStruct.FixedBytes, - Inner: test_item_type.InnerStatic{ - IntVal: int64(request.TestStructs[0].NestedStaticStruct.Inner.I), - A: solana.PublicKeyFromBytes(request.TestStructs[0].NestedStaticStruct.Inner.A), - }, - }, - } - return testStruct -} - -func encodeFieldsOnSliceOrArray(t *testing.T, request *EncodeRequest) []byte { +func encodeFieldsOnSliceOrArray(_ *testing.T, request *EncodeRequest) []byte { args := make([]any, 1) switch request.TestOn { - case TestItemArray1Type: - args[0] = [1]testutils.TestStruct{toInternalType(request.TestStructs[0])} - case TestItemArray2Type: - args[0] = [2]testutils.TestStruct{toInternalType(request.TestStructs[0]), toInternalType(request.TestStructs[1])} + case testutils.TestItemArray1Type: + args[0] = [1]test_item_type.TestStruct{testutils.ToInternalType(request.TestStructs[0])} + case testutils.TestItemArray2Type: + args[0] = [2]test_item_type.TestStruct{testutils.ToInternalType(request.TestStructs[0]), testutils.ToInternalType(request.TestStructs[1])} default: - tmp := make([]testutils.TestStruct, len(request.TestStructs)) + tmp := make([]test_item_type.TestStruct, len(request.TestStructs)) for i, ts := range request.TestStructs { - tmp[i] = toInternalType(ts) + tmp[i] = testutils.ToInternalType(ts) } args[0] = tmp } - borshBytes, err := bin.MarshalBorsh(cpy) - if err != nil { - t.Errorf(err.Error()) - } - return borshBytes + return []byte{} } func (it *codecInterfaceTester) GetCodec(t *testing.T) clcommontypes.Codec { codecConfig := codec.Config{Configs: map[string]codec.ChainConfig{}} testStruct := CreateTestStruct[*testing.T](0, it) - for k, v := range codecDefs { + for k, v := range testutils.CodecDefs { var idl codec.IDL if err := json.Unmarshal([]byte(v), &idl); err != nil { require.NoError(t, err) @@ -144,26 +90,31 @@ func (it *codecInterfaceTester) GetCodec(t *testing.T) clcommontypes.Codec { entry.IDL = v entry.AccountDef = &idl.Accounts[0] - if k != sizeItemType && k != NilType { + if slices.Contains([]string{testutils.TestItemSliceType, testutils.TestItemArray1Type, testutils.TestItemArray2Type}, k) { + entry.ModifierConfigs = commoncodec.ModifiersConfig{ + &commoncodec.RenameModifierConfig{Fields: map[string]string{"Items.NestedDynamicStruct.Inner.IntVal": "I"}}, + &commoncodec.RenameModifierConfig{Fields: map[string]string{"Items.NestedStaticStruct.Inner.IntVal": "I"}}, + &commoncodec.AddressBytesToStringModifierConfig{ + Fields: []string{"Items.AccountStruct.AccountStr"}, + Modifier: codec.SolanaAddressModifier{}, + }, + } + } else if k != testutils.SizeItemType && k != testutils.NilType { entry.ModifierConfigs = commoncodec.ModifiersConfig{ - &commoncodec.DropModifierConfig{Fields: []string{"DiscriminatorTestStruct"}}, &commoncodec.RenameModifierConfig{Fields: map[string]string{"NestedDynamicStruct.Inner.IntVal": "I"}}, &commoncodec.RenameModifierConfig{Fields: map[string]string{"NestedStaticStruct.Inner.IntVal": "I"}}, } } - if slices.Contains([]string{TestItemType, TestItemSliceType, TestItemArray1Type, TestItemArray2Type, TestItemWithConfigExtra}, k) { + if slices.Contains([]string{testutils.TestItemType, testutils.TestItemWithConfigExtra}, k) { addressByteModifier := &commoncodec.AddressBytesToStringModifierConfig{ Fields: []string{"AccountStruct.AccountStr"}, Modifier: codec.SolanaAddressModifier{}, } - //cpy {Field:0 OracleID:1 OracleIDs:[2 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] AccountStruct:{Account:[230 246 124 140 101 222 233 141 21 37 83 232 157 45 101 15 165 209 220 244 224 64 240 236 28 111 178 18 51 245 55 105] AccountStr:5rujdkG6iAzdtzf1JPjGF82tjeSwqM1QV4KCtrqaSNrX} Accounts:[[202 126 200 254 65 52 23 23 136 249 239 73 81 38 216 127 205 238 235 253 174 61 44 136 35 46 156 74 233 63 28 226] [202 195 18 0 144 219 77 163 99 129 127 77 185 142 8 121 12 253 71 49 75 123 189 213 118 119 129 87 26 74 71 177]] DifferentField:field0 BigField:{} NestedDynamicStruct:{FixedBytes:[0 1] Inner:{I:0 S:field0}} NestedStaticStruct:{FixedBytes:[0 1] Inner:{I:0 A:[3 134 218 122 6 116 161 93 12 75 126 131 168 213 211 126 159 168 145 110 168 226 230 212 110 87 25 251 255 78 130 55]}}} - //to encode: {DiscriminatorTestStruct:nil Field:0 DifferentField:field0 OracleId:1 OracleIds:[2 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] AccountStruct:{Account:[230 246 124 140 101 222 233 141 21 37 83 232 157 45 101 15 165 209 220 244 224 64 240 236 28 111 178 18 51 245 55 105] AccountStr:[72 55 213 199 102 214 15 160 144 134 159 170 4 211 4 50 206 167 85 101 28 99 67 254 12 247 191 123 214 119 110 228]} Accounts:[[202 126 200 254 65 52 23 23 136 249 239 73 81 38 216 127 205 238 235 253 174 61 44 136 35 46 156 74 233 63 28 226] [202 195 18 0 144 219 77 163 99 129 127 77 185 142 8 121 12 253 71 49 75 123 189 213 118 119 129 87 26 74 71 177]] BigField:{} NestedDynamicStruct:{FixedBytes:[0 1] Inner:{IntVal:0 S:field0}} NestedStaticStruct:{FixedBytes:[0 1] Inner:{IntVal:0 A:[3 134 218 122 6 116 161 93 12 75 126 131 168 213 211 126 159 168 145 110 168 226 230 212 110 87 25 251 255 78 130 55]}}} - entry.ModifierConfigs = append(entry.ModifierConfigs, addressByteModifier) } - if k == TestItemWithConfigExtra { + if k == testutils.TestItemWithConfigExtra { hardCode := &commoncodec.HardCodeModifierConfig{ OnChainValues: map[string]any{ "BigField": testStruct.BigField.String(), @@ -188,196 +139,3 @@ func (it *codecInterfaceTester) IncludeArrayEncodingSizeEnforcement() bool { func (it *codecInterfaceTester) Name() string { return "Solana" } - -func argsFromTestStruct(ts TestStruct) []any { - return []any{ - ts.Field, - ts.DifferentField, - uint8(ts.OracleID), - getOracleIDs(ts), - accountStructToInternalType(ts.AccountStruct), - getAccounts(ts), - ts.BigField, - midDynamicToInternalType(ts.NestedDynamicStruct), - midStaticToInternalType(ts.NestedStaticStruct), - } -} - -func getOracleIDs(first TestStruct) [32]byte { - oracleIDs := [32]byte{} - for i, oracleID := range first.OracleIDs { - oracleIDs[i] = byte(oracleID) - } - return oracleIDs -} - -func oracleIDsToBytes(oracleIDs [32]commontypes.OracleID) [32]byte { - convertedIDs := [32]byte{} - for i, id := range oracleIDs { - convertedIDs[i] = byte(id) - } - return convertedIDs -} - -func getAccounts(first TestStruct) []solana.PublicKey { - accountBytes := make([]solana.PublicKey, len(first.Accounts)) - for i, account := range first.Accounts { - accountBytes[i] = solana.PublicKeyFromBytes(account) - } - return accountBytes -} - -func toInternalType(testStruct TestStruct) testutils.TestStruct { - return testutils.TestStruct{ - Field: *testStruct.Field, - DifferentField: testStruct.DifferentField, - OracleId: byte(testStruct.OracleID), - OracleIds: oracleIDsToBytes(testStruct.OracleIDs), - AccountStruct: accountStructToInternalType(testStruct.AccountStruct), - Accounts: convertAccounts(testStruct.Accounts), - BigField: testStruct.BigField, - NestedDynamicStruct: midDynamicToInternalType(testStruct.NestedDynamicStruct), - NestedStaticStruct: midStaticToInternalType(testStruct.NestedStaticStruct), - } -} - -func accountStructToInternalType(a AccountStruct) testutils.AccountStruct { - return testutils.AccountStruct{ - Account: solana.PublicKeyFromBytes(a.Account), - AccountStr: solana.MustPublicKeyFromBase58(a.AccountStr), - } -} - -func convertAccounts(accounts [][]byte) []solana.PublicKey { - convertedAccounts := make([]solana.PublicKey, len(accounts)) - for i, a := range accounts { - convertedAccounts[i] = solana.PublicKeyFromBytes(a) - } - return convertedAccounts -} - -func midDynamicToInternalType(m MidLevelDynamicTestStruct) testutils.MidLevelDynamicTestStruct { - return testutils.MidLevelDynamicTestStruct{ - FixedBytes: m.FixedBytes, - Inner: testutils.InnerDynamicTestStruct{ - IntVal: int64(m.Inner.I), - S: m.Inner.S, - }, - } -} - -func midStaticToInternalType(m MidLevelStaticTestStruct) testutils.MidLevelStaticTestStruct { - return testutils.MidLevelStaticTestStruct{ - FixedBytes: m.FixedBytes, - Inner: testutils.InnerStaticTestStruct{ - IntVal: int64(m.Inner.I), - A: solana.PublicKeyFromBytes(m.Inner.A), - }, - } -} - -const sizeItemType = "item for size" - -//go:embed testutils/itemIDL.json -var itemTypeJSONIDL string - -//go:embed testutils/itemSliceTypeIDL.json -var itemSliceTypeJSONIDL string - -//go:embed testutils/itemArray1TypeIDL.json -var itemArray1TypeJSONIDL string - -//go:embed testutils/itemArray2TypeIDL.json -var itemArray2TypeJSONIDL string - -//go:embed testutils/sizeItemTypeIDL.json -var sizeItemTypeJSONIDL string - -//go:embed testutils/itemWithConfigExtraIDL.json -var itemWithConfigExtraJSONIDL string - -//go:embed testutils/nilTypeIDL.json -var nilTypeJSONIDL string - -// Map of IDL strings organized similarly to your ABI code -var codecDefs = map[string]string{ - TestItemType: itemTypeJSONIDL, - //TestItemSliceType: itemSliceTypeJSONIDL, - //TestItemArray1Type: itemArray1TypeJSONIDL, - //TestItemArray2Type: itemArray2TypeJSONIDL, - //sizeItemType: sizeItemTypeJSONIDL, - //TestItemWithConfigExtra: itemWithConfigExtraJSONIDL, - //NilType: nilTypeJSONIDL, -} - -// LogFields recursively logs fields of a struct or pointer to a struct with tight formatting. -func LogFields(v interface{}) { - logFields(reflect.ValueOf(v), "") -} - -func logFields(v reflect.Value, indent string) { - str := valueToString(v) - fmt.Printf("%s%s\n", indent, str) -} - -func valueToString(v reflect.Value) string { - // Resolve pointers to their underlying value - for v.Kind() == reflect.Ptr { - if v.IsNil() { - return "nil" - } - v = v.Elem() - } - - switch v.Kind() { - case reflect.Struct: - t := v.Type() - var fields []string - for i := 0; i < v.NumField(); i++ { - field := v.Field(i) - fieldType := t.Field(i) - - // Skip unexported fields - if !field.CanInterface() { - continue - } - - fieldName := fieldType.Name - fieldValue := valueToString(field) - fields = append(fields, fmt.Sprintf("%s:%s", fieldName, fieldValue)) - } - return fmt.Sprintf("{%s}", strings.Join(fields, " ")) - case reflect.Map: - if v.Len() == 0 { - return "{}" - } - var pairs []string - for _, key := range v.MapKeys() { - value := v.MapIndex(key) - keyStr := valueToString(key) - valueStr := valueToString(value) - pairs = append(pairs, fmt.Sprintf("%s:%s", keyStr, valueStr)) - } - return fmt.Sprintf("map[%s]", strings.Join(pairs, " ")) - case reflect.Slice, reflect.Array: - if v.Len() == 0 { - return "[]" - } - var elems []string - for i := 0; i < v.Len(); i++ { - elem := v.Index(i) - elemStr := valueToString(elem) - elems = append(elems, elemStr) - } - return fmt.Sprintf("[%s]", strings.Join(elems, " ")) - case reflect.Invalid: - return "nil" - default: - // Check if the value can be interfaced - if v.CanInterface() { - return fmt.Sprintf("%v", v.Interface()) - } else { - return "" - } - } -} diff --git a/pkg/solana/codec/discriminator.go b/pkg/solana/codec/discriminator.go index 7037d5687..9bc363ae7 100644 --- a/pkg/solana/codec/discriminator.go +++ b/pkg/solana/codec/discriminator.go @@ -12,7 +12,7 @@ import ( const discriminatorLength = 8 -func NewDiscriminator(name string) encodings.TypeCodec { +func NewDiscriminator(name string) *Discriminator { sum := sha256.Sum256([]byte("account:" + name)) return &Discriminator{hashPrefix: sum[:discriminatorLength]} } diff --git a/pkg/solana/codec/encoder.go b/pkg/solana/codec/encoder.go index 227b917a3..2605bc9ee 100644 --- a/pkg/solana/codec/encoder.go +++ b/pkg/solana/codec/encoder.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "reflect" - "strings" "github.com/smartcontractkit/chainlink-common/pkg/codec" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" @@ -40,8 +39,6 @@ func (e *encoder) Encode(_ context.Context, item any, itemType string) (res []by } } - fmt.Printf("about to log these: ") - LogFields(item) return info.Encode(item, nil) } @@ -52,75 +49,3 @@ func (e *encoder) GetMaxEncodingSize(_ context.Context, n int, itemType string) } return entry.GetCodecType().Size(n) } - -// LogFields recursively logs fields of a struct or pointer to a struct with tight formatting. -func LogFields(v interface{}) { - logFields(reflect.ValueOf(v), "") -} - -func logFields(v reflect.Value, indent string) { - str := valueToString(v) - fmt.Printf("%s%s\n", indent, str) -} - -func valueToString(v reflect.Value) string { - // Resolve pointers to their underlying value - for v.Kind() == reflect.Ptr { - if v.IsNil() { - return "nil" - } - v = v.Elem() - } - - switch v.Kind() { - case reflect.Struct: - t := v.Type() - var fields []string - for i := 0; i < v.NumField(); i++ { - field := v.Field(i) - fieldType := t.Field(i) - - // Skip unexported fields - if !field.CanInterface() { - continue - } - - fieldName := fieldType.Name - fieldValue := valueToString(field) - fields = append(fields, fmt.Sprintf("%s:%s", fieldName, fieldValue)) - } - return fmt.Sprintf("{%s}", strings.Join(fields, " ")) - case reflect.Map: - if v.Len() == 0 { - return "{}" - } - var pairs []string - for _, key := range v.MapKeys() { - value := v.MapIndex(key) - keyStr := valueToString(key) - valueStr := valueToString(value) - pairs = append(pairs, fmt.Sprintf("%s:%s", keyStr, valueStr)) - } - return fmt.Sprintf("map[%s]", strings.Join(pairs, " ")) - case reflect.Slice, reflect.Array: - if v.Len() == 0 { - return "[]" - } - var elems []string - for i := 0; i < v.Len(); i++ { - elem := v.Index(i) - elemStr := valueToString(elem) - elems = append(elems, elemStr) - } - return fmt.Sprintf("[%s]", strings.Join(elems, " ")) - case reflect.Invalid: - return "nil" - default: - // Check if the value can be interfaced - if v.CanInterface() { - return fmt.Sprintf("%v", v.Interface()) - } else { - return "" - } - } -} diff --git a/pkg/solana/codec/parsed_types.go b/pkg/solana/codec/parsed_types.go index 1f1b6f22a..d4e660444 100644 --- a/pkg/solana/codec/parsed_types.go +++ b/pkg/solana/codec/parsed_types.go @@ -15,9 +15,12 @@ type ParsedTypes struct { func (parsed *ParsedTypes) ToCodec() (commontypes.RemoteCodec, error) { modByTypeName := map[string]commoncodec.Modifier{} + fmt.Println("encoder defs ", parsed.EncoderDefs) + + fmt.Println("decoder defs ", parsed.DecoderDefs) + if err := AddEntries(parsed.EncoderDefs, modByTypeName); err != nil { fmt.Println("11111111 ", err) - return nil, err } if err := AddEntries(parsed.DecoderDefs, modByTypeName); err != nil { @@ -45,6 +48,7 @@ func AddEntries(defs map[string]Entry, modByTypeName map[string]commoncodec.Modi for k, def := range defs { modByTypeName[k] = def.Modifier() + fmt.Println("mm ", def.GetType().String()) _, err := def.Modifier().RetypeToOffChain(reflect.PointerTo(def.GetType()), k) if err != nil { return fmt.Errorf("%w: cannot retype %v: %w", commontypes.ErrInvalidConfig, k, err) @@ -52,27 +56,3 @@ func AddEntries(defs map[string]Entry, modByTypeName map[string]commoncodec.Modi } return nil } - -//AYOO2 *struct { -// DiscriminatorTestItemArray *[]uint8; -// Items *[1]*struct { -// Field *int32; -// Differentfield *string; -// Oracleid *uint8; -// Oracleids *[32]uint8; -// Accountstruct *struct { -// Account *[32]uint8; -// Accountstr *[32]uint8 -// }; -// Accounts *[][32]uint8; -// Bigfield *big.Int; -// Nesteddynamicstruct *struct { -// Fixedbytes *[2]uint8; -// Inner *struct { Intval *int64; S *string } -// }; -// Nestedstaticstruct *struct { -// Fixedbytes *[2]uint8; -// Inner *struct { Intval *int64; A *[32]uint8 } -// } -// } -//} diff --git a/pkg/solana/codec/solana.go b/pkg/solana/codec/solana.go index 9a4c3adc3..1d9a17a4e 100644 --- a/pkg/solana/codec/solana.go +++ b/pkg/solana/codec/solana.go @@ -112,8 +112,6 @@ func NewCodec(conf Config) (commontypes.RemoteCodec, error) { parsed.DecoderDefs[k] = newEntry } - fmt.Println("AYOOO") - return parsed.ToCodec() } diff --git a/pkg/solana/codec/solana_test.go b/pkg/solana/codec/solana_test.go index 4dd116691..ffefd5047 100644 --- a/pkg/solana/codec/solana_test.go +++ b/pkg/solana/codec/solana_test.go @@ -3,13 +3,10 @@ package codec_test import ( "encoding/json" "testing" - "time" - ag_solana "github.com/gagliardetto/solana-go" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - codeccommon "github.com/smartcontractkit/chainlink-common/pkg/codec" "github.com/smartcontractkit/chainlink-common/pkg/codec/encodings/binary" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" @@ -60,75 +57,6 @@ func TestNewIDLDefinedTypesCodecCodec(t *testing.T) { require.Equal(t, expected, decoded) } -func TestNewIDLCodec_WithModifiers(t *testing.T) { - t.Parallel() - - ctx := tests.Context(t) - _, _, idlCodec := newTestIDLAndCodec(t, true) - modConfig := codeccommon.ModifiersConfig{ - &codeccommon.RenameModifierConfig{Fields: map[string]string{"Value": "V"}}, - } - - renameMod, err := modConfig.ToModifier(codec.DecoderHooks...) - require.NoError(t, err) - - idlCodecWithMods, err := codec.NewNamedModifierCodec(idlCodec, testutils.TestStructWithNestedStruct, renameMod) - require.NoError(t, err) - - type modifiedTestStruct struct { - V uint8 - InnerStruct testutils.ObjectRef1 - BasicNestedArray [][]uint32 - Option *string - DefinedArray []testutils.ObjectRef2 - BasicVector []string - TimeVal int64 - DurationVal time.Duration - PublicKey ag_solana.PublicKey - EnumVal uint8 - } - - expected := modifiedTestStruct{ - V: testutils.DefaultTestStruct.Value, - InnerStruct: testutils.DefaultTestStruct.InnerStruct, - BasicNestedArray: testutils.DefaultTestStruct.BasicNestedArray, - Option: testutils.DefaultTestStruct.Option, - DefinedArray: testutils.DefaultTestStruct.DefinedArray, - BasicVector: testutils.DefaultTestStruct.BasicVector, - TimeVal: testutils.DefaultTestStruct.TimeVal, - DurationVal: testutils.DefaultTestStruct.DurationVal, - PublicKey: testutils.DefaultTestStruct.PublicKey, - EnumVal: testutils.DefaultTestStruct.EnumVal, - } - - withModsBts, err := idlCodecWithMods.Encode(ctx, expected, testutils.TestStructWithNestedStruct) - require.NoError(t, err) - - noModsBts, err := idlCodec.Encode(ctx, testutils.DefaultTestStruct, testutils.TestStructWithNestedStruct) - - // the codec without modifiers should encode an unmodified struct to the same bytes - // as the codec with modifiers encodes a modified struct - require.NoError(t, err) - require.Equal(t, withModsBts, noModsBts) - - var decoded modifiedTestStruct - - // the codec with modifiers should decode from unmodified bytes into a modified struct - require.NoError(t, idlCodecWithMods.Decode(ctx, noModsBts, &decoded, testutils.TestStructWithNestedStruct)) - require.Equal(t, expected, decoded) - - var unmodifiedDecoded testutils.StructWithNestedStruct - - // the codec without modifiers should decode from unmodified bytes to the same values as - // modified struct - require.NoError(t, idlCodec.Decode(ctx, noModsBts, &unmodifiedDecoded, testutils.TestStructWithNestedStruct)) - require.Equal(t, expected.V, unmodifiedDecoded.Value) - require.Equal(t, expected.TimeVal, unmodifiedDecoded.TimeVal) - require.Equal(t, expected.DurationVal, unmodifiedDecoded.DurationVal) - require.Equal(t, expected.PublicKey, unmodifiedDecoded.PublicKey) - require.Equal(t, expected.EnumVal, unmodifiedDecoded.EnumVal) -} - func TestNewIDLCodec_CircularDependency(t *testing.T) { t.Parallel() diff --git a/pkg/solana/codec/testutils/converters.go b/pkg/solana/codec/testutils/converters.go new file mode 100644 index 000000000..ae79ca945 --- /dev/null +++ b/pkg/solana/codec/testutils/converters.go @@ -0,0 +1,148 @@ +package testutils + +import ( + "math/big" + + bin "github.com/gagliardetto/binary" + "github.com/gagliardetto/solana-go" + "github.com/smartcontractkit/libocr/commontypes" + + "github.com/smartcontractkit/chainlink-common/pkg/types/interfacetests" + "github.com/smartcontractkit/chainlink-solana/pkg/solana/codec/testutils/test_item_type" +) + +func EncodeRequestToTestStruct(request *interfacetests.EncodeRequest) test_item_type.TestStruct { + byt := [32]byte{} + for i, v := range request.TestStructs[0].OracleIDs { + byt[i] = byte(v) + } + + k, _ := solana.PublicKeyFromBase58(request.TestStructs[0].AccountStruct.AccountStr) + + accs := make([]solana.PublicKey, len(request.TestStructs[0].Accounts)) + for i, v := range request.TestStructs[0].Accounts { + accs[i] = solana.PublicKeyFromBytes(v) + } + + testStruct := test_item_type.TestStruct{ + Field: *request.TestStructs[0].Field, + OracleId: uint8(request.TestStructs[0].OracleID), + OracleIds: byt, + AccountStruct: test_item_type.AccountStruct{ + Account: solana.PublicKeyFromBytes(request.TestStructs[0].AccountStruct.Account), + AccountStr: k, + }, + Accounts: accs, + DifferentField: request.TestStructs[0].DifferentField, + BigField: bigIntToBinInt128(request.TestStructs[0].BigField), + NestedDynamicStruct: test_item_type.NestedDynamic{ + FixedBytes: request.TestStructs[0].NestedDynamicStruct.FixedBytes, + Inner: test_item_type.InnerDynamic{ + IntVal: int64(request.TestStructs[0].NestedDynamicStruct.Inner.I), + S: request.TestStructs[0].NestedDynamicStruct.Inner.S, + }, + }, + NestedStaticStruct: test_item_type.NestedStatic{ + FixedBytes: request.TestStructs[0].NestedStaticStruct.FixedBytes, + Inner: test_item_type.InnerStatic{ + IntVal: int64(request.TestStructs[0].NestedStaticStruct.Inner.I), + A: solana.PublicKeyFromBytes(request.TestStructs[0].NestedStaticStruct.Inner.A), + }, + }, + } + return testStruct +} + +func bigIntToBinInt128(val *big.Int) bin.Int128 { + return bin.Int128{ + Lo: val.Uint64(), + Hi: new(big.Int).Rsh(val, 64).Uint64(), + } +} + +func argsFromTestStruct(ts interfacetests.TestStruct) []any { + return []any{ + ts.Field, + ts.DifferentField, + uint8(ts.OracleID), + getOracleIDs(ts), + accountStructToInternalType(ts.AccountStruct), + getAccounts(ts), + ts.BigField, + midDynamicToInternalType(ts.NestedDynamicStruct), + midStaticToInternalType(ts.NestedStaticStruct), + } +} + +func getOracleIDs(first interfacetests.TestStruct) [32]byte { + oracleIDs := [32]byte{} + for i, oracleID := range first.OracleIDs { + oracleIDs[i] = byte(oracleID) + } + return oracleIDs +} + +func oracleIDsToBytes(oracleIDs [32]commontypes.OracleID) [32]byte { + convertedIDs := [32]byte{} + for i, id := range oracleIDs { + convertedIDs[i] = byte(id) + } + return convertedIDs +} + +func ToInternalType(testStruct interfacetests.TestStruct) test_item_type.TestStruct { + return test_item_type.TestStruct{ + Field: *testStruct.Field, + DifferentField: testStruct.DifferentField, + OracleId: byte(testStruct.OracleID), + OracleIds: oracleIDsToBytes(testStruct.OracleIDs), + AccountStruct: accountStructToInternalType(testStruct.AccountStruct), + Accounts: convertAccounts(testStruct.Accounts), + BigField: bigIntToBinInt128(testStruct.BigField), + NestedDynamicStruct: midDynamicToInternalType(testStruct.NestedDynamicStruct), + NestedStaticStruct: midStaticToInternalType(testStruct.NestedStaticStruct), + } +} + +func accountStructToInternalType(a interfacetests.AccountStruct) test_item_type.AccountStruct { + return test_item_type.AccountStruct{ + Account: solana.PublicKeyFromBytes(a.Account), + AccountStr: solana.MustPublicKeyFromBase58(a.AccountStr), + } +} + +func convertAccounts(accounts [][]byte) []solana.PublicKey { + convertedAccounts := make([]solana.PublicKey, len(accounts)) + for i, a := range accounts { + convertedAccounts[i] = solana.PublicKeyFromBytes(a) + } + return convertedAccounts +} + +func midDynamicToInternalType(m interfacetests.MidLevelDynamicTestStruct) test_item_type.NestedDynamic { + return test_item_type.NestedDynamic{ + FixedBytes: m.FixedBytes, + Inner: test_item_type.InnerDynamic{ + IntVal: int64(m.Inner.I), + S: m.Inner.S, + }, + } +} + +func midStaticToInternalType(m interfacetests.MidLevelStaticTestStruct) test_item_type.NestedStatic { + return test_item_type.NestedStatic{ + FixedBytes: m.FixedBytes, + Inner: test_item_type.InnerStatic{ + IntVal: int64(m.Inner.I), + A: solana.PublicKeyFromBytes(m.Inner.A), + }, + } +} + +func getAccounts(first interfacetests.TestStruct) []solana.PublicKey { + accountBytes := make([]solana.PublicKey, len(first.Accounts)) + for i, account := range first.Accounts { + accountBytes[i] = solana.PublicKeyFromBytes(account) + } + return accountBytes +} diff --git a/pkg/solana/codec/testutils/itemSliceTypeIDL.json b/pkg/solana/codec/testutils/itemSliceTypeIDL.json deleted file mode 100644 index 964d4d301..000000000 --- a/pkg/solana/codec/testutils/itemSliceTypeIDL.json +++ /dev/null @@ -1,104 +0,0 @@ -{ - "version": "0.1.0", - "name": "test_item_slice_type", - "instructions": [ - { - "name": "ProcessTestItemSliceType", - "accounts": [ - { - "name": "TestItemSlice", - "isMut": true, - "isSigner": false - } - ], - "args": [] - } - ], - "accounts": [ - { - "name": "TestItemSlice", - "type": { - "kind": "struct", - "fields": [ - { - "name": "Items", - "type": { - "vec": { - "defined": "TestItem" - } - } - } - ] - } - } - ], - "types": [ - { - "name": "TestItem", - "type": { - "kind": "struct", - "fields": [ - { "name": "Field", "type": "i32" }, - { "name": "DifferentField", "type": "string" }, - { "name": "OracleId", "type": "u8" }, - { "name": "OracleIds", "type": { "array": ["u8", 32] } }, - { "name": "AccountStruct", "type": { "defined": "AccountStruct" } }, - { "name": "Accounts", "type": { "vec": "publicKey" } }, - { "name": "BigField", "type": "i128" }, - { "name": "NestedDynamicStruct", "type": { "defined": "NestedDynamic" } }, - { "name": "NestedStaticStruct", "type": { "defined": "NestedStatic" } } - ] - } - }, - { - "name": "AccountStruct", - "type": { - "kind": "struct", - "fields": [ - { "name": "Account", "type": "publicKey" }, - { "name": "AccountStr", "type": "publicKey" } - ] - } - }, - { - "name": "InnerDynamic", - "type": { - "kind": "struct", - "fields": [ - { "name": "IntVal", "type": "i64" }, - { "name": "S", "type": "string" } - ] - } - }, - { - "name": "NestedDynamic", - "type": { - "kind": "struct", - "fields": [ - { "name": "FixedBytes", "type": { "array": ["u8", 2] } }, - { "name": "Inner", "type": { "defined": "InnerDynamic" } } - ] - } - }, - { - "name": "InnerStatic", - "type": { - "kind": "struct", - "fields": [ - { "name": "IntVal", "type": "i64" }, - { "name": "A", "type": "publicKey" } - ] - } - }, - { - "name": "NestedStatic", - "type": { - "kind": "struct", - "fields": [ - { "name": "FixedBytes", "type": { "array": ["u8", 2] } }, - { "name": "Inner", "type": { "defined": "InnerStatic" } } - ] - } - } - ] -} diff --git a/pkg/solana/codec/testutils/test_item_slice_type/itemSliceTypeIDL.json b/pkg/solana/codec/testutils/test_item_slice_type/itemSliceTypeIDL.json new file mode 100644 index 000000000..8f4d42bd2 --- /dev/null +++ b/pkg/solana/codec/testutils/test_item_slice_type/itemSliceTypeIDL.json @@ -0,0 +1,104 @@ + { + "version": "0.1.0", + "name": "test_item_slice_type", + "instructions": [ + { + "name": "ProcessTestItemSliceType", + "accounts": [ + { + "name": "TestItemSlice", + "isMut": true, + "isSigner": false + } + ], + "args": [] + } + ], + "accounts": [ + { + "name": "TestItemSlice", + "type": { + "kind": "struct", + "fields": [ + { + "name": "Items", + "type": { + "vec": { + "defined": "TestItem" + } + } + } + ] + } + } + ], + "types": [ + { + "name": "TestItem", + "type": { + "kind": "struct", + "fields": [ + { "name": "Field", "type": "i32" }, + { "name": "DifferentField", "type": "string" }, + { "name": "OracleId", "type": "u8" }, + { "name": "OracleIds", "type": { "array": ["u8", 32] } }, + { "name": "AccountStruct", "type": { "defined": "AccountStruct" } }, + { "name": "Accounts", "type": { "vec": "publicKey" } }, + { "name": "BigField", "type": "i128" }, + { "name": "NestedDynamicStruct", "type": { "defined": "NestedDynamic" } }, + { "name": "NestedStaticStruct", "type": { "defined": "NestedStatic" } } + ] + } + }, + { + "name": "AccountStruct", + "type": { + "kind": "struct", + "fields": [ + { "name": "Account", "type": "publicKey" }, + { "name": "AccountStr", "type": "publicKey" } + ] + } + }, + { + "name": "InnerDynamic", + "type": { + "kind": "struct", + "fields": [ + { "name": "IntVal", "type": "i64" }, + { "name": "S", "type": "string" } + ] + } + }, + { + "name": "NestedDynamic", + "type": { + "kind": "struct", + "fields": [ + { "name": "FixedBytes", "type": { "array": ["u8", 2] } }, + { "name": "Inner", "type": { "defined": "InnerDynamic" } } + ] + } + }, + { + "name": "InnerStatic", + "type": { + "kind": "struct", + "fields": [ + { "name": "IntVal", "type": "i64" }, + { "name": "A", "type": "publicKey" } + ] + } + }, + { + "name": "NestedStatic", + "type": { + "kind": "struct", + "fields": [ + { "name": "FixedBytes", "type": { "array": ["u8", 2] } }, + { "name": "Inner", "type": { "defined": "InnerStatic" } } + ] + } + } + ] + } diff --git a/pkg/solana/codec/testutils/test_item_slice_type/types.go b/pkg/solana/codec/testutils/test_item_slice_type/types.go new file mode 100644 index 000000000..16c0ce105 --- /dev/null +++ b/pkg/solana/codec/testutils/test_item_slice_type/types.go @@ -0,0 +1,283 @@ +// Code generated by https://github.com/gagliardetto/anchor-go. DO NOT EDIT. + +package test_item_slice_type + +import ( + ag_binary "github.com/gagliardetto/binary" + ag_solanago "github.com/gagliardetto/solana-go" +) + +type TestItem struct { + Field int32 + DifferentField string + OracleId uint8 + OracleIds [32]uint8 + AccountStruct AccountStruct + Accounts []ag_solanago.PublicKey + BigField ag_binary.Int128 + NestedDynamicStruct NestedDynamic + NestedStaticStruct NestedStatic +} + +func (obj TestItem) MarshalWithEncoder(encoder *ag_binary.Encoder) (err error) { + // Serialize `Field` param: + err = encoder.Encode(obj.Field) + if err != nil { + return err + } + // Serialize `DifferentField` param: + err = encoder.Encode(obj.DifferentField) + if err != nil { + return err + } + // Serialize `OracleId` param: + err = encoder.Encode(obj.OracleId) + if err != nil { + return err + } + // Serialize `OracleIds` param: + err = encoder.Encode(obj.OracleIds) + if err != nil { + return err + } + // Serialize `AccountStruct` param: + err = encoder.Encode(obj.AccountStruct) + if err != nil { + return err + } + // Serialize `Accounts` param: + err = encoder.Encode(obj.Accounts) + if err != nil { + return err + } + // Serialize `BigField` param: + err = encoder.Encode(obj.BigField) + if err != nil { + return err + } + // Serialize `NestedDynamicStruct` param: + err = encoder.Encode(obj.NestedDynamicStruct) + if err != nil { + return err + } + // Serialize `NestedStaticStruct` param: + err = encoder.Encode(obj.NestedStaticStruct) + if err != nil { + return err + } + return nil +} + +func (obj *TestItem) UnmarshalWithDecoder(decoder *ag_binary.Decoder) (err error) { + // Deserialize `Field`: + err = decoder.Decode(&obj.Field) + if err != nil { + return err + } + // Deserialize `DifferentField`: + err = decoder.Decode(&obj.DifferentField) + if err != nil { + return err + } + // Deserialize `OracleId`: + err = decoder.Decode(&obj.OracleId) + if err != nil { + return err + } + // Deserialize `OracleIds`: + err = decoder.Decode(&obj.OracleIds) + if err != nil { + return err + } + // Deserialize `AccountStruct`: + err = decoder.Decode(&obj.AccountStruct) + if err != nil { + return err + } + // Deserialize `Accounts`: + err = decoder.Decode(&obj.Accounts) + if err != nil { + return err + } + // Deserialize `BigField`: + err = decoder.Decode(&obj.BigField) + if err != nil { + return err + } + // Deserialize `NestedDynamicStruct`: + err = decoder.Decode(&obj.NestedDynamicStruct) + if err != nil { + return err + } + // Deserialize `NestedStaticStruct`: + err = decoder.Decode(&obj.NestedStaticStruct) + if err != nil { + return err + } + return nil +} + +type AccountStruct struct { + Account ag_solanago.PublicKey + AccountStr ag_solanago.PublicKey +} + +func (obj AccountStruct) MarshalWithEncoder(encoder *ag_binary.Encoder) (err error) { + // Serialize `Account` param: + err = encoder.Encode(obj.Account) + if err != nil { + return err + } + // Serialize `AccountStr` param: + err = encoder.Encode(obj.AccountStr) + if err != nil { + return err + } + return nil +} + +func (obj *AccountStruct) UnmarshalWithDecoder(decoder *ag_binary.Decoder) (err error) { + // Deserialize `Account`: + err = decoder.Decode(&obj.Account) + if err != nil { + return err + } + // Deserialize `AccountStr`: + err = decoder.Decode(&obj.AccountStr) + if err != nil { + return err + } + return nil +} + +type InnerDynamic struct { + IntVal int64 + S string +} + +func (obj InnerDynamic) MarshalWithEncoder(encoder *ag_binary.Encoder) (err error) { + // Serialize `IntVal` param: + err = encoder.Encode(obj.IntVal) + if err != nil { + return err + } + // Serialize `S` param: + err = encoder.Encode(obj.S) + if err != nil { + return err + } + return nil +} + +func (obj *InnerDynamic) UnmarshalWithDecoder(decoder *ag_binary.Decoder) (err error) { + // Deserialize `IntVal`: + err = decoder.Decode(&obj.IntVal) + if err != nil { + return err + } + // Deserialize `S`: + err = decoder.Decode(&obj.S) + if err != nil { + return err + } + return nil +} + +type NestedDynamic struct { + FixedBytes [2]uint8 + Inner InnerDynamic +} + +func (obj NestedDynamic) MarshalWithEncoder(encoder *ag_binary.Encoder) (err error) { + // Serialize `FixedBytes` param: + err = encoder.Encode(obj.FixedBytes) + if err != nil { + return err + } + // Serialize `Inner` param: + err = encoder.Encode(obj.Inner) + if err != nil { + return err + } + return nil +} + +func (obj *NestedDynamic) UnmarshalWithDecoder(decoder *ag_binary.Decoder) (err error) { + // Deserialize `FixedBytes`: + err = decoder.Decode(&obj.FixedBytes) + if err != nil { + return err + } + // Deserialize `Inner`: + err = decoder.Decode(&obj.Inner) + if err != nil { + return err + } + return nil +} + +type InnerStatic struct { + IntVal int64 + A ag_solanago.PublicKey +} + +func (obj InnerStatic) MarshalWithEncoder(encoder *ag_binary.Encoder) (err error) { + // Serialize `IntVal` param: + err = encoder.Encode(obj.IntVal) + if err != nil { + return err + } + // Serialize `A` param: + err = encoder.Encode(obj.A) + if err != nil { + return err + } + return nil +} + +func (obj *InnerStatic) UnmarshalWithDecoder(decoder *ag_binary.Decoder) (err error) { + // Deserialize `IntVal`: + err = decoder.Decode(&obj.IntVal) + if err != nil { + return err + } + // Deserialize `A`: + err = decoder.Decode(&obj.A) + if err != nil { + return err + } + return nil +} + +type NestedStatic struct { + FixedBytes [2]uint8 + Inner InnerStatic +} + +func (obj NestedStatic) MarshalWithEncoder(encoder *ag_binary.Encoder) (err error) { + // Serialize `FixedBytes` param: + err = encoder.Encode(obj.FixedBytes) + if err != nil { + return err + } + // Serialize `Inner` param: + err = encoder.Encode(obj.Inner) + if err != nil { + return err + } + return nil +} + +func (obj *NestedStatic) UnmarshalWithDecoder(decoder *ag_binary.Decoder) (err error) { + // Deserialize `FixedBytes`: + err = decoder.Decode(&obj.FixedBytes) + if err != nil { + return err + } + // Deserialize `Inner`: + err = decoder.Decode(&obj.Inner) + if err != nil { + return err + } + return nil +} diff --git a/pkg/solana/codec/testutils/test_item_type/accounts.go b/pkg/solana/codec/testutils/test_item_type/accounts.go new file mode 100644 index 000000000..728945e62 --- /dev/null +++ b/pkg/solana/codec/testutils/test_item_type/accounts.go @@ -0,0 +1,140 @@ +// Code generated by https://github.com/gagliardetto/anchor-go. DO NOT EDIT. + +package test_item_type + +import ( + "fmt" + + ag_binary "github.com/gagliardetto/binary" + ag_solanago "github.com/gagliardetto/solana-go" +) + +type TestStruct struct { + Field int32 + OracleId uint8 + OracleIds [32]uint8 + AccountStruct AccountStruct + Accounts []ag_solanago.PublicKey + DifferentField string + BigField ag_binary.Int128 + NestedDynamicStruct NestedDynamic + NestedStaticStruct NestedStatic +} + +var TestStructDiscriminator = [8]byte{243, 149, 82, 70, 154, 54, 107, 6} + +func (obj TestStruct) MarshalWithEncoder(encoder *ag_binary.Encoder) (err error) { + // Write account discriminator: + err = encoder.WriteBytes(TestStructDiscriminator[:], false) + if err != nil { + return err + } + // Serialize `Field` param: + err = encoder.Encode(obj.Field) + if err != nil { + return err + } + // Serialize `OracleId` param: + err = encoder.Encode(obj.OracleId) + if err != nil { + return err + } + // Serialize `OracleIds` param: + err = encoder.Encode(obj.OracleIds) + if err != nil { + return err + } + // Serialize `AccountStruct` param: + err = encoder.Encode(obj.AccountStruct) + if err != nil { + return err + } + // Serialize `Accounts` param: + err = encoder.Encode(obj.Accounts) + if err != nil { + return err + } + // Serialize `DifferentField` param: + err = encoder.Encode(obj.DifferentField) + if err != nil { + return err + } + // Serialize `BigField` param: + err = encoder.Encode(obj.BigField) + if err != nil { + return err + } + // Serialize `NestedDynamicStruct` param: + err = encoder.Encode(obj.NestedDynamicStruct) + if err != nil { + return err + } + // Serialize `NestedStaticStruct` param: + err = encoder.Encode(obj.NestedStaticStruct) + if err != nil { + return err + } + return nil +} + +func (obj *TestStruct) UnmarshalWithDecoder(decoder *ag_binary.Decoder) (err error) { + // Read and check account discriminator: + { + discriminator, err := decoder.ReadTypeID() + if err != nil { + return err + } + if !discriminator.Equal(TestStructDiscriminator[:]) { + return fmt.Errorf( + "wrong discriminator: wanted %s, got %s", + "[243 149 82 70 154 54 107 6]", + fmt.Sprint(discriminator[:])) + } + } + // Deserialize `Field`: + err = decoder.Decode(&obj.Field) + if err != nil { + return err + } + // Deserialize `OracleId`: + err = decoder.Decode(&obj.OracleId) + if err != nil { + return err + } + // Deserialize `OracleIds`: + err = decoder.Decode(&obj.OracleIds) + if err != nil { + return err + } + // Deserialize `AccountStruct`: + err = decoder.Decode(&obj.AccountStruct) + if err != nil { + return err + } + // Deserialize `Accounts`: + err = decoder.Decode(&obj.Accounts) + if err != nil { + return err + } + // Deserialize `DifferentField`: + err = decoder.Decode(&obj.DifferentField) + if err != nil { + return err + } + // Deserialize `BigField`: + err = decoder.Decode(&obj.BigField) + if err != nil { + return err + } + // Deserialize `NestedDynamicStruct`: + err = decoder.Decode(&obj.NestedDynamicStruct) + if err != nil { + return err + } + // Deserialize `NestedStaticStruct`: + err = decoder.Decode(&obj.NestedStaticStruct) + if err != nil { + return err + } + return nil +} diff --git a/pkg/solana/codec/testutils/itemIDL.json b/pkg/solana/codec/testutils/test_item_type/itemIDL.json similarity index 95% rename from pkg/solana/codec/testutils/itemIDL.json rename to pkg/solana/codec/testutils/test_item_type/itemIDL.json index 02483eab1..529ae23a7 100644 --- a/pkg/solana/codec/testutils/itemIDL.json +++ b/pkg/solana/codec/testutils/test_item_type/itemIDL.json @@ -9,11 +9,6 @@ "name": "TestStruct", "isMut": true, "isSigner": false - }, - { - "name": "User", - "isMut": false, - "isSigner": true } ], "args": [] diff --git a/pkg/solana/codec/testutils/test_item_type/types.go b/pkg/solana/codec/testutils/test_item_type/types.go new file mode 100644 index 000000000..a5049aa53 --- /dev/null +++ b/pkg/solana/codec/testutils/test_item_type/types.go @@ -0,0 +1,173 @@ +// Code generated by https://github.com/gagliardetto/anchor-go. DO NOT EDIT. + +package test_item_type + +import ( + ag_binary "github.com/gagliardetto/binary" + ag_solanago "github.com/gagliardetto/solana-go" +) + +type AccountStruct struct { + Account ag_solanago.PublicKey + AccountStr ag_solanago.PublicKey +} + +func (obj AccountStruct) MarshalWithEncoder(encoder *ag_binary.Encoder) (err error) { + // Serialize `Account` param: + err = encoder.Encode(obj.Account) + if err != nil { + return err + } + // Serialize `AccountStr` param: + err = encoder.Encode(obj.AccountStr) + if err != nil { + return err + } + return nil +} + +func (obj *AccountStruct) UnmarshalWithDecoder(decoder *ag_binary.Decoder) (err error) { + // Deserialize `Account`: + err = decoder.Decode(&obj.Account) + if err != nil { + return err + } + // Deserialize `AccountStr`: + err = decoder.Decode(&obj.AccountStr) + if err != nil { + return err + } + return nil +} + +type InnerDynamic struct { + IntVal int64 + S string +} + +func (obj InnerDynamic) MarshalWithEncoder(encoder *ag_binary.Encoder) (err error) { + // Serialize `IntVal` param: + err = encoder.Encode(obj.IntVal) + if err != nil { + return err + } + // Serialize `S` param: + err = encoder.Encode(obj.S) + if err != nil { + return err + } + return nil +} + +func (obj *InnerDynamic) UnmarshalWithDecoder(decoder *ag_binary.Decoder) (err error) { + // Deserialize `IntVal`: + err = decoder.Decode(&obj.IntVal) + if err != nil { + return err + } + // Deserialize `S`: + err = decoder.Decode(&obj.S) + if err != nil { + return err + } + return nil +} + +type NestedDynamic struct { + FixedBytes [2]uint8 + Inner InnerDynamic +} + +func (obj NestedDynamic) MarshalWithEncoder(encoder *ag_binary.Encoder) (err error) { + // Serialize `FixedBytes` param: + err = encoder.Encode(obj.FixedBytes) + if err != nil { + return err + } + // Serialize `Inner` param: + err = encoder.Encode(obj.Inner) + if err != nil { + return err + } + return nil +} + +func (obj *NestedDynamic) UnmarshalWithDecoder(decoder *ag_binary.Decoder) (err error) { + // Deserialize `FixedBytes`: + err = decoder.Decode(&obj.FixedBytes) + if err != nil { + return err + } + // Deserialize `Inner`: + err = decoder.Decode(&obj.Inner) + if err != nil { + return err + } + return nil +} + +type InnerStatic struct { + IntVal int64 + A ag_solanago.PublicKey +} + +func (obj InnerStatic) MarshalWithEncoder(encoder *ag_binary.Encoder) (err error) { + // Serialize `IntVal` param: + err = encoder.Encode(obj.IntVal) + if err != nil { + return err + } + // Serialize `A` param: + err = encoder.Encode(obj.A) + if err != nil { + return err + } + return nil +} + +func (obj *InnerStatic) UnmarshalWithDecoder(decoder *ag_binary.Decoder) (err error) { + // Deserialize `IntVal`: + err = decoder.Decode(&obj.IntVal) + if err != nil { + return err + } + // Deserialize `A`: + err = decoder.Decode(&obj.A) + if err != nil { + return err + } + return nil +} + +type NestedStatic struct { + FixedBytes [2]uint8 + Inner InnerStatic +} + +func (obj NestedStatic) MarshalWithEncoder(encoder *ag_binary.Encoder) (err error) { + // Serialize `FixedBytes` param: + err = encoder.Encode(obj.FixedBytes) + if err != nil { + return err + } + // Serialize `Inner` param: + err = encoder.Encode(obj.Inner) + if err != nil { + return err + } + return nil +} + +func (obj *NestedStatic) UnmarshalWithDecoder(decoder *ag_binary.Decoder) (err error) { + // Deserialize `FixedBytes`: + err = decoder.Decode(&obj.FixedBytes) + if err != nil { + return err + } + // Deserialize `Inner`: + err = decoder.Decode(&obj.Inner) + if err != nil { + return err + } + return nil +} diff --git a/pkg/solana/codec/testutils/types.go b/pkg/solana/codec/testutils/types.go index 6517d55d4..b76be6dd0 100644 --- a/pkg/solana/codec/testutils/types.go +++ b/pkg/solana/codec/testutils/types.go @@ -48,6 +48,12 @@ var ( PublicKey: solana.NewWallet().PublicKey(), EnumVal: 0, } + TestItemType = "TestItem" + TestItemSliceType = "TestItemSliceType" + TestItemArray1Type = "TestItemArray1Type" + TestItemArray2Type = "TestItemArray2Type" + TestItemWithConfigExtra = "TestItemWithConfigExtra" + NilType = "NilType" ) type StructWithNestedStruct struct { @@ -87,39 +93,36 @@ var JSONIDLWithAllTypes string //go:embed circularDepIDL.json var CircularDepIDL string -type TestStruct struct { - Field int32 - DifferentField string - OracleId uint8 - OracleIds [32]uint8 - AccountStruct AccountStruct - Accounts []solana.PublicKey - BigField *big.Int - NestedDynamicStruct MidLevelDynamicTestStruct - NestedStaticStruct MidLevelStaticTestStruct -} +const SizeItemType = "item for size" -type AccountStruct struct { - Account solana.PublicKey - AccountStr solana.PublicKey -} +//go:embed test_item_type/itemIDL.json +var itemTypeJSONIDL string -type MidLevelDynamicTestStruct struct { - FixedBytes [2]byte - Inner InnerDynamicTestStruct -} +//go:embed test_item_slice_type/itemSliceTypeIDL.json +var itemSliceTypeJSONIDL string -type InnerDynamicTestStruct struct { - IntVal int64 - S string -} +//go:embed itemArray1TypeIDL.json +var itemArray1TypeJSONIDL string -type MidLevelStaticTestStruct struct { - FixedBytes [2]byte - Inner InnerStaticTestStruct -} +//go:embed itemArray2TypeIDL.json +var itemArray2TypeJSONIDL string + +//go:embed sizeItemTypeIDL.json +var sizeItemTypeJSONIDL string + +//go:embed itemWithConfigExtraIDL.json +var itemWithConfigExtraJSONIDL string + +//go:embed nilTypeIDL.json +var nilTypeJSONIDL string -type InnerStaticTestStruct struct { - IntVal int64 - A solana.PublicKey +// Map of IDL strings organized similarly to your ABI code +var CodecDefs = map[string]string{ + //TestItemType: itemTypeJSONIDL, + TestItemSliceType: itemSliceTypeJSONIDL, + //TestItemArray1Type: itemArray1TypeJSONIDL, + //TestItemArray2Type: itemArray2TypeJSONIDL, + //sizeItemType: sizeItemTypeJSONIDL, + //TestItemWithConfigExtra: itemWithConfigExtraJSONIDL, + //NilType: nilTypeJSONIDL, }