diff --git a/go/feed/feed.go b/go/feed/feed.go index c90ad96..77a58d9 100644 --- a/go/feed/feed.go +++ b/go/feed/feed.go @@ -15,6 +15,9 @@ const ( FeedVersion2 FeedVersion3 FeedVersion4 + FeedVersion5 + FeedVersion6 + FeedVersion7 FeedVersion8 FeedVersion9 FeedVersion10 diff --git a/go/report/report.go b/go/report/report.go index 382834b..cc86edd 100644 --- a/go/report/report.go +++ b/go/report/report.go @@ -9,13 +9,16 @@ import ( v2 "github.com/smartcontractkit/data-streams-sdk/go/report/v2" v3 "github.com/smartcontractkit/data-streams-sdk/go/report/v3" v4 "github.com/smartcontractkit/data-streams-sdk/go/report/v4" + v5 "github.com/smartcontractkit/data-streams-sdk/go/report/v5" + v6 "github.com/smartcontractkit/data-streams-sdk/go/report/v6" + v7 "github.com/smartcontractkit/data-streams-sdk/go/report/v7" v8 "github.com/smartcontractkit/data-streams-sdk/go/report/v8" v9 "github.com/smartcontractkit/data-streams-sdk/go/report/v9" ) // Data represents the actual report data and attributes type Data interface { - v1.Data | v2.Data | v3.Data | v4.Data | v8.Data | v9.Data | v10.Data + v1.Data | v2.Data | v3.Data | v4.Data | v5.Data | v6.Data | v7.Data | v8.Data | v9.Data | v10.Data Schema() abi.Arguments } diff --git a/go/report/report_test.go b/go/report/report_test.go index bb2f513..e2b4495 100644 --- a/go/report/report_test.go +++ b/go/report/report_test.go @@ -9,9 +9,13 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" v1 "github.com/smartcontractkit/data-streams-sdk/go/report/v1" + v10 "github.com/smartcontractkit/data-streams-sdk/go/report/v10" v2 "github.com/smartcontractkit/data-streams-sdk/go/report/v2" v3 "github.com/smartcontractkit/data-streams-sdk/go/report/v3" v4 "github.com/smartcontractkit/data-streams-sdk/go/report/v4" + v5 "github.com/smartcontractkit/data-streams-sdk/go/report/v5" + v6 "github.com/smartcontractkit/data-streams-sdk/go/report/v6" + v7 "github.com/smartcontractkit/data-streams-sdk/go/report/v7" v8 "github.com/smartcontractkit/data-streams-sdk/go/report/v8" v9 "github.com/smartcontractkit/data-streams-sdk/go/report/v9" ) @@ -73,6 +77,48 @@ func TestReport(t *testing.T) { t.Errorf("expected: %#v, got: %#v", v4Report, rv4) } + b, err = schema.Pack(v5Report.ReportContext, v5Report.ReportBlob, v5Report.RawRs, v5Report.RawSs, v5Report.RawVs) + if err != nil { + t.Errorf("failed to encode report: %s", err) + } + + rv5, err := Decode[v5.Data](b) + if err != nil { + t.Errorf("failed to decode report: %s", err) + } + + if !reflect.DeepEqual(v5Report, rv5) { + t.Errorf("expected: %#v, got: %#v", v5Report, rv5) + } + + b, err = schema.Pack(v6Report.ReportContext, v6Report.ReportBlob, v6Report.RawRs, v6Report.RawSs, v6Report.RawVs) + if err != nil { + t.Errorf("failed to encode report: %s", err) + } + + rv6, err := Decode[v6.Data](b) + if err != nil { + t.Errorf("failed to decode report: %s", err) + } + + if !reflect.DeepEqual(v6Report, rv6) { + t.Errorf("expected: %#v, got: %#v", v6Report, rv6) + } + + b, err = schema.Pack(v7Report.ReportContext, v7Report.ReportBlob, v7Report.RawRs, v7Report.RawSs, v7Report.RawVs) + if err != nil { + t.Errorf("failed to encode report: %s", err) + } + + rv7, err := Decode[v7.Data](b) + if err != nil { + t.Errorf("failed to decode report: %s", err) + } + + if !reflect.DeepEqual(v7Report, rv7) { + t.Errorf("expected: %#v, got: %#v", v7Report, rv7) + } + b, err = schema.Pack(v8Report.ReportContext, v8Report.ReportBlob, v8Report.RawRs, v8Report.RawSs, v8Report.RawVs) if err != nil { t.Errorf("failed to encode report: %s", err) @@ -97,9 +143,23 @@ func TestReport(t *testing.T) { t.Errorf("failed to decode report: %s", err) } - if !reflect.DeepEqual(v8Report, rv8) { + if !reflect.DeepEqual(v9Report, rv9) { t.Errorf("expected: %#v, got: %#v", v9Report, rv9) } + + b, err = schema.Pack(v10Report.ReportContext, v10Report.ReportBlob, v10Report.RawRs, v10Report.RawSs, v10Report.RawVs) + if err != nil { + t.Errorf("failed to encode report: %s", err) + } + + rv10, err := Decode[v10.Data](b) + if err != nil { + t.Errorf("failed to decode report: %s", err) + } + + if !reflect.DeepEqual(v10Report, rv10) { + t.Errorf("expected: %#v, got: %#v", v10Report, rv10) + } } var v1Report = &Report[v1.Data]{ @@ -138,6 +198,33 @@ var v4Report = &Report[v4.Data]{ RawVs: [32]uint8{00, 01, 10, 74, 67, 29, 24, 17, 12, 18, 22, 11, 69, 11, 63, 86, 12, 86, 23, 58, 13, 53, 29, 12, 17, 10, 17, 12, 63, 27, 12, 14}, } +var v5Report = &Report[v5.Data]{ + Data: v5Data, + ReportContext: [3][32]uint8{}, + ReportBlob: mustPackData(v5Data), + RawRs: [][32]uint8{{00, 01, 10, 74, 67, 29, 24, 17, 12, 18, 22, 11, 69, 11, 63, 86, 12, 86, 23, 58, 13, 53, 29, 12, 17, 10, 17, 12, 63, 27, 12, 14}}, + RawSs: [][32]uint8{{01, 02, 10, 73, 65, 19, 14, 27, 42, 48, 52, 18, 39, 116, 67, 85, 13, 82, 33, 48, 23, 33, 49, 32, 67, 50, 37, 32, 63, 77, 14, 64}}, + RawVs: [32]uint8{00, 01, 10, 74, 67, 29, 24, 17, 12, 18, 22, 11, 69, 11, 63, 86, 12, 86, 23, 58, 13, 53, 29, 12, 17, 10, 17, 12, 63, 27, 12, 14}, +} + +var v6Report = &Report[v6.Data]{ + Data: v6Data, + ReportContext: [3][32]uint8{}, + ReportBlob: mustPackData(v6Data), + RawRs: [][32]uint8{{00, 01, 10, 74, 67, 29, 24, 17, 12, 18, 22, 11, 69, 11, 63, 86, 12, 86, 23, 58, 13, 53, 29, 12, 17, 10, 17, 12, 63, 27, 12, 14}}, + RawSs: [][32]uint8{{01, 02, 10, 73, 65, 19, 14, 27, 42, 48, 52, 18, 39, 116, 67, 85, 13, 82, 33, 48, 23, 33, 49, 32, 67, 50, 37, 32, 63, 77, 14, 64}}, + RawVs: [32]uint8{00, 01, 10, 74, 67, 29, 24, 17, 12, 18, 22, 11, 69, 11, 63, 86, 12, 86, 23, 58, 13, 53, 29, 12, 17, 10, 17, 12, 63, 27, 12, 14}, +} + +var v7Report = &Report[v7.Data]{ + Data: v7Data, + ReportContext: [3][32]uint8{}, + ReportBlob: mustPackData(v7Data), + RawRs: [][32]uint8{{00, 01, 10, 74, 67, 29, 24, 17, 12, 18, 22, 11, 69, 11, 63, 86, 12, 86, 23, 58, 13, 53, 29, 12, 17, 10, 17, 12, 63, 27, 12, 14}}, + RawSs: [][32]uint8{{01, 02, 10, 73, 65, 19, 14, 27, 42, 48, 52, 18, 39, 116, 67, 85, 13, 82, 33, 48, 23, 33, 49, 32, 67, 50, 37, 32, 63, 77, 14, 64}}, + RawVs: [32]uint8{00, 01, 10, 74, 67, 29, 24, 17, 12, 18, 22, 11, 69, 11, 63, 86, 12, 86, 23, 58, 13, 53, 29, 12, 17, 10, 17, 12, 63, 27, 12, 14}, +} + var v8Report = &Report[v8.Data]{ Data: v8Data, ReportContext: [3][32]uint8{}, @@ -156,6 +243,15 @@ var v9Report = &Report[v9.Data]{ RawVs: [32]uint8{00, 01, 10, 74, 67, 29, 24, 17, 12, 18, 22, 11, 69, 11, 63, 86, 12, 86, 23, 58, 13, 53, 29, 12, 17, 10, 17, 12, 63, 27, 12, 14}, } +var v10Report = &Report[v10.Data]{ + Data: v10Data, + ReportContext: [3][32]uint8{}, + ReportBlob: mustPackData(v10Data), + RawRs: [][32]uint8{{00, 01, 10, 74, 67, 29, 24, 17, 12, 18, 22, 11, 69, 11, 63, 86, 12, 86, 23, 58, 13, 53, 29, 12, 17, 10, 17, 12, 63, 27, 12, 14}}, + RawSs: [][32]uint8{{01, 02, 10, 73, 65, 19, 14, 27, 42, 48, 52, 18, 39, 116, 67, 85, 13, 82, 33, 48, 23, 33, 49, 32, 67, 50, 37, 32, 63, 77, 14, 64}}, + RawVs: [32]uint8{00, 01, 10, 74, 67, 29, 24, 17, 12, 18, 22, 11, 69, 11, 63, 86, 12, 86, 23, 58, 13, 53, 29, 12, 17, 10, 17, 12, 63, 27, 12, 14}, +} + var v1Data = v1.Data{ FeedID: [32]uint8{00, 01, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114}, ObservationsTimestamp: uint32(time.Now().Unix()), @@ -201,6 +297,42 @@ var v4Data = v4.Data{ MarketStatus: v4.MarketStatusOpen, } +var v5Data = v5.Data{ + FeedID: [32]uint8{00, 5, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114}, + ValidFromTimestamp: uint32(time.Now().Unix()), + ObservationsTimestamp: uint32(time.Now().Unix()), + NativeFee: big.NewInt(10), + LinkFee: big.NewInt(10), + ExpiresAt: uint32(time.Now().Unix()) + 100, + Rate: big.NewInt(550), + Timestamp: uint32(time.Now().Unix()), + Duration: uint32(86400), +} + +var v6Data = v6.Data{ + FeedID: [32]uint8{00, 6, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114}, + ValidFromTimestamp: uint32(time.Now().Unix()), + ObservationsTimestamp: uint32(time.Now().Unix()), + NativeFee: big.NewInt(10), + LinkFee: big.NewInt(10), + ExpiresAt: uint32(time.Now().Unix()) + 100, + Price: big.NewInt(600), + Price2: big.NewInt(601), + Price3: big.NewInt(602), + Price4: big.NewInt(603), + Price5: big.NewInt(604), +} + +var v7Data = v7.Data{ + FeedID: [32]uint8{00, 7, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114}, + ValidFromTimestamp: uint32(time.Now().Unix()), + ObservationsTimestamp: uint32(time.Now().Unix()), + NativeFee: big.NewInt(10), + LinkFee: big.NewInt(10), + ExpiresAt: uint32(time.Now().Unix()) + 100, + ExchangeRate: big.NewInt(700), +} + var v8Data = v8.Data{ FeedID: [32]uint8{00, 8, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114}, ValidFromTimestamp: uint32(time.Now().Unix()), @@ -226,6 +358,22 @@ var v9Data = v9.Data{ Ripcord: 108, } +var v10Data = v10.Data{ + FeedID: [32]uint8{00, 10, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114}, + ValidFromTimestamp: uint32(time.Now().Unix()), + ObservationsTimestamp: uint32(time.Now().Unix()), + NativeFee: big.NewInt(10), + LinkFee: big.NewInt(10), + ExpiresAt: uint32(time.Now().Unix()) + 100, + LastUpdateTimestamp: uint64(time.Now().UnixNano() - int64(10*time.Second)), + Price: big.NewInt(1000), + MarketStatus: 1, + CurrentMultiplier: big.NewInt(100), + NewMultiplier: big.NewInt(101), + ActivationDateTime: uint32(time.Now().Unix()) + 200, + TokenizedPrice: big.NewInt(1001), +} + func mustPackData(d interface{}) []byte { var args []interface{} var dataSchema abi.Arguments @@ -280,6 +428,45 @@ func mustPackData(d interface{}) []byte { v.BenchmarkPrice, v.MarketStatus, } + case v5.Data: + dataSchema = v5.Schema() + args = []interface{}{ + v.FeedID, + v.ValidFromTimestamp, + v.ObservationsTimestamp, + v.NativeFee, + v.LinkFee, + v.ExpiresAt, + v.Rate, + v.Timestamp, + v.Duration, + } + case v6.Data: + dataSchema = v6.Schema() + args = []interface{}{ + v.FeedID, + v.ValidFromTimestamp, + v.ObservationsTimestamp, + v.NativeFee, + v.LinkFee, + v.ExpiresAt, + v.Price, + v.Price2, + v.Price3, + v.Price4, + v.Price5, + } + case v7.Data: + dataSchema = v7.Schema() + args = []interface{}{ + v.FeedID, + v.ValidFromTimestamp, + v.ObservationsTimestamp, + v.NativeFee, + v.LinkFee, + v.ExpiresAt, + v.ExchangeRate, + } case v8.Data: dataSchema = v8.Schema() args = []interface{}{ @@ -307,6 +494,23 @@ func mustPackData(d interface{}) []byte { v.Aum, v.Ripcord, } + case v10.Data: + dataSchema = v10.Schema() + args = []interface{}{ + v.FeedID, + v.ValidFromTimestamp, + v.ObservationsTimestamp, + v.NativeFee, + v.LinkFee, + v.ExpiresAt, + v.LastUpdateTimestamp, + v.Price, + v.MarketStatus, + v.CurrentMultiplier, + v.NewMultiplier, + v.ActivationDateTime, + v.TokenizedPrice, + } default: panic(fmt.Sprintf("invalid type to pack: %#v", v)) } diff --git a/go/report/v5/data.go b/go/report/v5/data.go new file mode 100644 index 0000000..4f8b3cd --- /dev/null +++ b/go/report/v5/data.go @@ -0,0 +1,64 @@ +package v5 + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/smartcontractkit/data-streams-sdk/go/feed" +) + +var schema = Schema() + +// Schema returns this data version schema +func Schema() abi.Arguments { + mustNewType := func(t string) abi.Type { + result, err := abi.NewType(t, "", []abi.ArgumentMarshaling{}) + if err != nil { + panic(fmt.Sprintf("Unexpected error during abi.NewType: %s", err)) + } + return result + } + return abi.Arguments([]abi.Argument{ + {Name: "feedId", Type: mustNewType("bytes32")}, + {Name: "validFromTimestamp", Type: mustNewType("uint32")}, + {Name: "observationsTimestamp", Type: mustNewType("uint32")}, + {Name: "nativeFee", Type: mustNewType("uint192")}, + {Name: "linkFee", Type: mustNewType("uint192")}, + {Name: "expiresAt", Type: mustNewType("uint32")}, + {Name: "rate", Type: mustNewType("int192")}, + {Name: "timestamp", Type: mustNewType("uint32")}, + {Name: "duration", Type: mustNewType("uint32")}, + }) +} + +// Data is the container for this schema attributes +type Data struct { + FeedID feed.ID `abi:"feedId"` + ValidFromTimestamp uint32 + ObservationsTimestamp uint32 + NativeFee *big.Int + LinkFee *big.Int + ExpiresAt uint32 + Rate *big.Int + Timestamp uint32 + Duration uint32 +} + +// Schema returns this data version schema +func (Data) Schema() abi.Arguments { + return Schema() +} + +// Decode decodes the serialized data bytes +func Decode(data []byte) (*Data, error) { + values, err := schema.Unpack(data) + if err != nil { + return nil, fmt.Errorf("failed to decode report: %w", err) + } + decoded := new(Data) + if err = schema.Copy(decoded, values); err != nil { + return nil, fmt.Errorf("failed to copy report values to struct: %w", err) + } + return decoded, nil +} diff --git a/go/report/v5/data_test.go b/go/report/v5/data_test.go new file mode 100644 index 0000000..b97b255 --- /dev/null +++ b/go/report/v5/data_test.go @@ -0,0 +1,47 @@ +package v5 + +import ( + "math/big" + "reflect" + "testing" + "time" +) + +func TestData(t *testing.T) { + r := &Data{ + FeedID: [32]uint8{00, 05, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114}, + ValidFromTimestamp: uint32(time.Now().Unix()), + ObservationsTimestamp: uint32(time.Now().Unix()), + NativeFee: big.NewInt(10), + LinkFee: big.NewInt(10), + ExpiresAt: uint32(time.Now().Unix()) + 100, + Rate: big.NewInt(100), + Timestamp: uint32(time.Now().Unix()), + Duration: 3600, // 1 hour in seconds + } + + b, err := schema.Pack( + r.FeedID, + r.ValidFromTimestamp, + r.ObservationsTimestamp, + r.NativeFee, + r.LinkFee, + r.ExpiresAt, + r.Rate, + r.Timestamp, + r.Duration, + ) + if err != nil { + t.Errorf("failed to serialize report: %s", err) + } + + // Test data decoding + decoded, err := Decode(b) + if err != nil { + t.Errorf("failed to deserialize report: %s", err) + } + + if !reflect.DeepEqual(r, decoded) { + t.Errorf("expected: %#v, got %#v", r, decoded) + } +} diff --git a/go/report/v6/data.go b/go/report/v6/data.go new file mode 100644 index 0000000..4703ca2 --- /dev/null +++ b/go/report/v6/data.go @@ -0,0 +1,68 @@ +package v6 + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/smartcontractkit/data-streams-sdk/go/feed" +) + +var schema = Schema() + +// Schema returns this data version schema +func Schema() abi.Arguments { + mustNewType := func(t string) abi.Type { + result, err := abi.NewType(t, "", []abi.ArgumentMarshaling{}) + if err != nil { + panic(fmt.Sprintf("Unexpected error during abi.NewType: %s", err)) + } + return result + } + return abi.Arguments([]abi.Argument{ + {Name: "feedId", Type: mustNewType("bytes32")}, + {Name: "validFromTimestamp", Type: mustNewType("uint32")}, + {Name: "observationsTimestamp", Type: mustNewType("uint32")}, + {Name: "nativeFee", Type: mustNewType("uint192")}, + {Name: "linkFee", Type: mustNewType("uint192")}, + {Name: "expiresAt", Type: mustNewType("uint32")}, + {Name: "price", Type: mustNewType("int192")}, + {Name: "price2", Type: mustNewType("int192")}, + {Name: "price3", Type: mustNewType("int192")}, + {Name: "price4", Type: mustNewType("int192")}, + {Name: "price5", Type: mustNewType("int192")}, + }) +} + +// Data is the container for this schema attributes +type Data struct { + FeedID feed.ID `abi:"feedId"` + ValidFromTimestamp uint32 + ObservationsTimestamp uint32 + NativeFee *big.Int + LinkFee *big.Int + ExpiresAt uint32 + Price *big.Int + Price2 *big.Int + Price3 *big.Int + Price4 *big.Int + Price5 *big.Int +} + +// Schema returns this data version schema +func (Data) Schema() abi.Arguments { + return Schema() +} + +// Decode decodes the serialized data bytes +func Decode(data []byte) (*Data, error) { + values, err := schema.Unpack(data) + if err != nil { + return nil, fmt.Errorf("failed to decode report: %w", err) + } + decoded := new(Data) + if err = schema.Copy(decoded, values); err != nil { + return nil, fmt.Errorf("failed to copy report values to struct: %w", err) + } + return decoded, nil +} diff --git a/go/report/v6/data_test.go b/go/report/v6/data_test.go new file mode 100644 index 0000000..38205d4 --- /dev/null +++ b/go/report/v6/data_test.go @@ -0,0 +1,51 @@ +package v6 + +import ( + "math/big" + "reflect" + "testing" + "time" +) + +func TestData(t *testing.T) { + r := &Data{ + FeedID: [32]uint8{00, 06, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114}, + ValidFromTimestamp: uint32(time.Now().Unix()), + ObservationsTimestamp: uint32(time.Now().Unix()), + NativeFee: big.NewInt(10), + LinkFee: big.NewInt(10), + ExpiresAt: uint32(time.Now().Unix()) + 100, + Price: big.NewInt(100), + Price2: big.NewInt(110), + Price3: big.NewInt(120), + Price4: big.NewInt(130), + Price5: big.NewInt(140), + } + + b, err := schema.Pack( + r.FeedID, + r.ValidFromTimestamp, + r.ObservationsTimestamp, + r.NativeFee, + r.LinkFee, + r.ExpiresAt, + r.Price, + r.Price2, + r.Price3, + r.Price4, + r.Price5, + ) + if err != nil { + t.Errorf("failed to serialize report: %s", err) + } + + // Test data decoding + decoded, err := Decode(b) + if err != nil { + t.Errorf("failed to deserialize report: %s", err) + } + + if !reflect.DeepEqual(r, decoded) { + t.Errorf("expected: %#v, got %#v", r, decoded) + } +} diff --git a/go/report/v7/data.go b/go/report/v7/data.go new file mode 100644 index 0000000..7c3afed --- /dev/null +++ b/go/report/v7/data.go @@ -0,0 +1,60 @@ +package v7 + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/smartcontractkit/data-streams-sdk/go/feed" +) + +var schema = Schema() + +// Schema returns this data version schema +func Schema() abi.Arguments { + mustNewType := func(t string) abi.Type { + result, err := abi.NewType(t, "", []abi.ArgumentMarshaling{}) + if err != nil { + panic(fmt.Sprintf("Unexpected error during abi.NewType: %s", err)) + } + return result + } + return abi.Arguments([]abi.Argument{ + {Name: "feedId", Type: mustNewType("bytes32")}, + {Name: "validFromTimestamp", Type: mustNewType("uint32")}, + {Name: "observationsTimestamp", Type: mustNewType("uint32")}, + {Name: "nativeFee", Type: mustNewType("uint192")}, + {Name: "linkFee", Type: mustNewType("uint192")}, + {Name: "expiresAt", Type: mustNewType("uint32")}, + {Name: "exchangeRate", Type: mustNewType("int192")}, + }) +} + +// Data is the container for this schema attributes +type Data struct { + FeedID feed.ID `abi:"feedId"` + ValidFromTimestamp uint32 + ObservationsTimestamp uint32 + NativeFee *big.Int + LinkFee *big.Int + ExpiresAt uint32 + ExchangeRate *big.Int +} + +// Schema returns this data version schema +func (Data) Schema() abi.Arguments { + return Schema() +} + +// Decode decodes the serialized data bytes +func Decode(data []byte) (*Data, error) { + values, err := schema.Unpack(data) + if err != nil { + return nil, fmt.Errorf("failed to decode report: %w", err) + } + decoded := new(Data) + if err = schema.Copy(decoded, values); err != nil { + return nil, fmt.Errorf("failed to copy report values to struct: %w", err) + } + return decoded, nil +} diff --git a/go/report/v7/data_test.go b/go/report/v7/data_test.go new file mode 100644 index 0000000..10ecc78 --- /dev/null +++ b/go/report/v7/data_test.go @@ -0,0 +1,43 @@ +package v7 + +import ( + "math/big" + "reflect" + "testing" + "time" +) + +func TestData(t *testing.T) { + r := &Data{ + FeedID: [32]uint8{00, 07, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114}, + ValidFromTimestamp: uint32(time.Now().Unix()), + ObservationsTimestamp: uint32(time.Now().Unix()), + NativeFee: big.NewInt(10), + LinkFee: big.NewInt(10), + ExpiresAt: uint32(time.Now().Unix()) + 100, + ExchangeRate: big.NewInt(100), + } + + b, err := schema.Pack( + r.FeedID, + r.ValidFromTimestamp, + r.ObservationsTimestamp, + r.NativeFee, + r.LinkFee, + r.ExpiresAt, + r.ExchangeRate, + ) + if err != nil { + t.Errorf("failed to serialize report: %s", err) + } + + // Test data decoding + decoded, err := Decode(b) + if err != nil { + t.Errorf("failed to deserialize report: %s", err) + } + + if !reflect.DeepEqual(r, decoded) { + t.Errorf("expected: %#v, got %#v", r, decoded) + } +}