From 0a44a0890cbfba62113406132c1f58c5ff493582 Mon Sep 17 00:00:00 2001 From: Augustus Chang Date: Tue, 16 Jul 2024 16:49:55 -0400 Subject: [PATCH 1/7] fix signature --- relayer/pkg/chainlink/ocr2/medianreport/report.go | 14 +++++++++++++- .../pkg/chainlink/ocr2/medianreport/report_test.go | 12 +++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/relayer/pkg/chainlink/ocr2/medianreport/report.go b/relayer/pkg/chainlink/ocr2/medianreport/report.go index 187403d8..d01b1304 100644 --- a/relayer/pkg/chainlink/ocr2/medianreport/report.go +++ b/relayer/pkg/chainlink/ocr2/medianreport/report.go @@ -8,6 +8,7 @@ import ( "sort" "github.com/NethermindEth/juno/core/felt" + "github.com/NethermindEth/starknet.go/curve" starknetutils "github.com/NethermindEth/starknet.go/utils" "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median" @@ -74,13 +75,24 @@ func (c ReportCodec) BuildReport(oo []median.ParsedAttributedObservation) (types var observers = make([]byte, starknet.FeltLength) var observations []*felt.Felt + for i, o := range oo { - observers[i] = byte(o.Observer) + // encoding scheme is offset by 1 byte to avoid felt overflow + // [0x0, <1_ID>, <2_ID>, ..., , 0x0, 0x0, ..., 0x0] + // note: this does not alter Starknet's MAX_ORACLES (31) + // to differentiate this encoding scheme from the original encoding scheme is to check if, within the first N + 1 bytes, 0 occurs twice + // where N is the number of oracles in the DON + observers[i+1] = byte(o.Observer) f := starknetutils.BigIntToFelt(o.Value) observations = append(observations, f) } + observersBig := starknetutils.BytesToBig(observers) + if observersBig.Cmp(curve.Curve.P) != -1 { + return nil, fmt.Errorf("invalid observers value: %v is larger than size of finite field", observersBig) + } + var report []byte buf := timestampFelt.Bytes() diff --git a/relayer/pkg/chainlink/ocr2/medianreport/report_test.go b/relayer/pkg/chainlink/ocr2/medianreport/report_test.go index 3c92b112..1edbfa07 100644 --- a/relayer/pkg/chainlink/ocr2/medianreport/report_test.go +++ b/relayer/pkg/chainlink/ocr2/medianreport/report_test.go @@ -13,6 +13,15 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median" ) +func TestTrial(t *testing.T) { + val := "4077890116503514227502940569025930714369419670386493876774642852321317355520" + x, err := big.NewInt(0).SetString(val, 10) + assert.False(t, err) + + res1 := x.Cmp(big.NewInt(0)) + assert.Equal(t, -1, res1) +} + func TestBuildReportWithNegativeValues(t *testing.T) { c := ReportCodec{} oo := []median.ParsedAttributedObservation{} @@ -73,7 +82,8 @@ func TestBuildReport(t *testing.T) { }) // create expected outputs - observers[i] = uint8(i) + // remember to add 1 byte offset to avoid felt overflow + observers[i+1] = uint8(i) } report, err := c.BuildReport(oo) From a1a69f33719e28d4ece8be4502c4acb518f09a46 Mon Sep 17 00:00:00 2001 From: Augustus Chang Date: Tue, 16 Jul 2024 16:59:40 -0400 Subject: [PATCH 2/7] remove test --- relayer/pkg/chainlink/ocr2/medianreport/report_test.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/relayer/pkg/chainlink/ocr2/medianreport/report_test.go b/relayer/pkg/chainlink/ocr2/medianreport/report_test.go index 1edbfa07..8f0dfa89 100644 --- a/relayer/pkg/chainlink/ocr2/medianreport/report_test.go +++ b/relayer/pkg/chainlink/ocr2/medianreport/report_test.go @@ -13,15 +13,6 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median" ) -func TestTrial(t *testing.T) { - val := "4077890116503514227502940569025930714369419670386493876774642852321317355520" - x, err := big.NewInt(0).SetString(val, 10) - assert.False(t, err) - - res1 := x.Cmp(big.NewInt(0)) - assert.Equal(t, -1, res1) -} - func TestBuildReportWithNegativeValues(t *testing.T) { c := ReportCodec{} oo := []median.ParsedAttributedObservation{} From 3689e4b7a4473f635a0b83b241cdb240ee15e193 Mon Sep 17 00:00:00 2001 From: Augustus Chang Date: Tue, 16 Jul 2024 17:00:59 -0400 Subject: [PATCH 3/7] update comment --- relayer/pkg/chainlink/ocr2/medianreport/report.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relayer/pkg/chainlink/ocr2/medianreport/report.go b/relayer/pkg/chainlink/ocr2/medianreport/report.go index d01b1304..845bb4e7 100644 --- a/relayer/pkg/chainlink/ocr2/medianreport/report.go +++ b/relayer/pkg/chainlink/ocr2/medianreport/report.go @@ -80,7 +80,7 @@ func (c ReportCodec) BuildReport(oo []median.ParsedAttributedObservation) (types // encoding scheme is offset by 1 byte to avoid felt overflow // [0x0, <1_ID>, <2_ID>, ..., , 0x0, 0x0, ..., 0x0] // note: this does not alter Starknet's MAX_ORACLES (31) - // to differentiate this encoding scheme from the original encoding scheme is to check if, within the first N + 1 bytes, 0 occurs twice + // to differentiate this encoding scheme from the original encoding scheme, check if, within the first N + 1 bytes, 0 occurs twice // where N is the number of oracles in the DON observers[i+1] = byte(o.Observer) From fd1169777c526826476f85a63233e45a76c81494 Mon Sep 17 00:00:00 2001 From: Augustus Chang Date: Wed, 17 Jul 2024 10:59:31 -0400 Subject: [PATCH 4/7] change to 0x01 pad instead of 0x00 pad --- relayer/pkg/chainlink/ocr2/medianreport/report.go | 8 ++++---- relayer/pkg/chainlink/ocr2/medianreport/report_test.go | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/relayer/pkg/chainlink/ocr2/medianreport/report.go b/relayer/pkg/chainlink/ocr2/medianreport/report.go index 845bb4e7..ffb7364b 100644 --- a/relayer/pkg/chainlink/ocr2/medianreport/report.go +++ b/relayer/pkg/chainlink/ocr2/medianreport/report.go @@ -76,12 +76,12 @@ func (c ReportCodec) BuildReport(oo []median.ParsedAttributedObservation) (types var observers = make([]byte, starknet.FeltLength) var observations []*felt.Felt + observers[0] = uint8(1) for i, o := range oo { - // encoding scheme is offset by 1 byte to avoid felt overflow - // [0x0, <1_ID>, <2_ID>, ..., , 0x0, 0x0, ..., 0x0] + // encoding scheme is offset by 0x01-padded to avoid felt overflow + // [0x01, <1_ID>, <2_ID>, ..., , 0x0, 0x0, ..., 0x0] // note: this does not alter Starknet's MAX_ORACLES (31) - // to differentiate this encoding scheme from the original encoding scheme, check if, within the first N + 1 bytes, 0 occurs twice - // where N is the number of oracles in the DON + // where N is the length of the observations array observers[i+1] = byte(o.Observer) f := starknetutils.BigIntToFelt(o.Value) diff --git a/relayer/pkg/chainlink/ocr2/medianreport/report_test.go b/relayer/pkg/chainlink/ocr2/medianreport/report_test.go index 8f0dfa89..3bf83701 100644 --- a/relayer/pkg/chainlink/ocr2/medianreport/report_test.go +++ b/relayer/pkg/chainlink/ocr2/medianreport/report_test.go @@ -63,6 +63,8 @@ func TestBuildReport(t *testing.T) { v := big.NewInt(0) v.SetString("1000000000000000000", 10) + // 0x01 pad the first byte + observers[0] = uint8(1) for i := 0; i < n; i++ { oo = append(oo, median.ParsedAttributedObservation{ Timestamp: uint32(time.Now().Unix()), From a9cc1b00d637e4f46c469eea992ff8730f2cc688 Mon Sep 17 00:00:00 2001 From: Augustus Chang Date: Thu, 18 Jul 2024 11:53:38 -0400 Subject: [PATCH 5/7] add new overflow test --- .../ocr2/medianreport/report_test.go | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/relayer/pkg/chainlink/ocr2/medianreport/report_test.go b/relayer/pkg/chainlink/ocr2/medianreport/report_test.go index 3bf83701..69dc1830 100644 --- a/relayer/pkg/chainlink/ocr2/medianreport/report_test.go +++ b/relayer/pkg/chainlink/ocr2/medianreport/report_test.go @@ -53,6 +53,28 @@ func TestBuildReportWithNegativeValues(t *testing.T) { assert.ErrorContains(t, err, "starknet does not support negative values: value = (10), fee = (10), gas = (-10)") } +func TestBuildReportNoObserversOverflow(t *testing.T) { + c := ReportCodec{} + oo := []median.ParsedAttributedObservation{} + fmt.Println("hello") + v := big.NewInt(0) + v.SetString("1000000000000000000", 10) + + // test largest possible encoded observers byte array + for i := 30; i >= 0; i-- { + oo = append(oo, median.ParsedAttributedObservation{ + Timestamp: uint32(time.Now().Unix()), + Value: big.NewInt(1234567890), + GasPriceSubunits: big.NewInt(2), + JuelsPerFeeCoin: v, + Observer: commontypes.OracleID(i), + }) + } + + _, err := c.BuildReport(oo) + assert.Nil(t, err) +} + func TestBuildReport(t *testing.T) { c := ReportCodec{} oo := []median.ParsedAttributedObservation{} From aba6bc49e3f5c101ce6dadc14052541f1833e6de Mon Sep 17 00:00:00 2001 From: Augustus Chang Date: Thu, 18 Jul 2024 12:03:32 -0400 Subject: [PATCH 6/7] add extra check --- .../pkg/chainlink/ocr2/medianreport/report_test.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/relayer/pkg/chainlink/ocr2/medianreport/report_test.go b/relayer/pkg/chainlink/ocr2/medianreport/report_test.go index 69dc1830..679610d4 100644 --- a/relayer/pkg/chainlink/ocr2/medianreport/report_test.go +++ b/relayer/pkg/chainlink/ocr2/medianreport/report_test.go @@ -6,6 +6,8 @@ import ( "testing" "time" + "github.com/NethermindEth/starknet.go/curve" + starknetutils "github.com/NethermindEth/starknet.go/utils" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -71,8 +73,15 @@ func TestBuildReportNoObserversOverflow(t *testing.T) { }) } - _, err := c.BuildReport(oo) + report, err := c.BuildReport(oo) assert.Nil(t, err) + + index := timestampSizeBytes + observersBytes := []byte(report[index : index+observersSizeBytes]) + observersBig := starknetutils.BytesToBig(observersBytes) + + // encoded observers felt is less than max felt + assert.Equal(t, -1, observersBig.Cmp(curve.Curve.P)) } func TestBuildReport(t *testing.T) { From 6b8ae3da88bd725685b0b0209fcd7924dbfa17b1 Mon Sep 17 00:00:00 2001 From: Augustus Chang Date: Thu, 18 Jul 2024 12:07:33 -0400 Subject: [PATCH 7/7] add test message --- relayer/pkg/chainlink/ocr2/medianreport/report_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relayer/pkg/chainlink/ocr2/medianreport/report_test.go b/relayer/pkg/chainlink/ocr2/medianreport/report_test.go index 679610d4..9bef6615 100644 --- a/relayer/pkg/chainlink/ocr2/medianreport/report_test.go +++ b/relayer/pkg/chainlink/ocr2/medianreport/report_test.go @@ -81,7 +81,7 @@ func TestBuildReportNoObserversOverflow(t *testing.T) { observersBig := starknetutils.BytesToBig(observersBytes) // encoded observers felt is less than max felt - assert.Equal(t, -1, observersBig.Cmp(curve.Curve.P)) + assert.Equal(t, -1, observersBig.Cmp(curve.Curve.P), "observers should be less than max felt") } func TestBuildReport(t *testing.T) {