From 6bf0e40b4626f924adfa3cf07d225cd072363006 Mon Sep 17 00:00:00 2001 From: begmaroman Date: Tue, 13 Aug 2024 18:17:17 +0100 Subject: [PATCH 01/10] Return validation error if there are duplicates in the offchain data list --- services/datacom/datacom.go | 13 ++++++++ services/datacom/datacom_test.go | 51 ++++++++++++++++++++++++++------ 2 files changed, 55 insertions(+), 9 deletions(-) diff --git a/services/datacom/datacom.go b/services/datacom/datacom.go index 35ff0d7..0f97891 100644 --- a/services/datacom/datacom.go +++ b/services/datacom/datacom.go @@ -55,6 +55,19 @@ func (d *Endpoints) signSequence(signedSequence types.SignedSequenceInterface) ( return "0x0", rpc.NewRPCError(rpc.DefaultErrorCode, "unauthorized") } + // Make sure there are no duplicates in the given offchain data list + existingData := make(map[string]struct{}) + offChainData := signedSequence.OffChainData() + for _, data := range offChainData { + key := data.Key.Hex() + if _, ok := existingData[key]; ok { + // The given key already exist in the offchain data list + return "0x0", rpc.NewRPCError(rpc.DefaultErrorCode, fmt.Sprintf("duplicate key: %s", key)) + } + + existingData[key] = struct{}{} + } + // Store off-chain data by hash (hash(L2Data): L2Data) if err = d.db.StoreOffChainData(context.Background(), signedSequence.OffChainData()); err != nil { return "0x0", rpc.NewRPCError(rpc.DefaultErrorCode, diff --git a/services/datacom/datacom_test.go b/services/datacom/datacom_test.go index dec8b5a..21669b6 100644 --- a/services/datacom/datacom_test.go +++ b/services/datacom/datacom_test.go @@ -25,14 +25,10 @@ func TestDataCom_SignSequence(t *testing.T) { storeOffChainDataReturns []interface{} sender *ecdsa.PrivateKey signer *ecdsa.PrivateKey + sequence types.Sequence expectedError string } - sequence := types.Sequence{ - types.ArgBytes([]byte{0, 1}), - types.ArgBytes([]byte{2, 3}), - } - privateKey, err := crypto.GenerateKey() require.NoError(t, err) @@ -51,7 +47,7 @@ func TestDataCom_SignSequence(t *testing.T) { dbMock := mocks.NewDB(t) if len(cfg.storeOffChainDataReturns) > 0 { - dbMock.On("StoreOffChainData", mock.Anything, sequence.OffChainData()).Return( + dbMock.On("StoreOffChainData", mock.Anything, cfg.sequence.OffChainData()).Return( cfg.storeOffChainDataReturns...).Once() } @@ -68,15 +64,15 @@ func TestDataCom_SignSequence(t *testing.T) { sqr.Start(context.Background()) if cfg.sender != nil { - signature, err := sequence.Sign(cfg.sender) + signature, err := cfg.sequence.Sign(cfg.sender) require.NoError(t, err) signedSequence = &types.SignedSequence{ - Sequence: sequence, + Sequence: cfg.sequence, Signature: signature, } } else { signedSequence = &types.SignedSequence{ - Sequence: sequence, + Sequence: cfg.sequence, Signature: []byte{}, } } @@ -106,6 +102,10 @@ func TestDataCom_SignSequence(t *testing.T) { testFn(t, testConfig{ expectedError: "failed to verify sender", + sequence: types.Sequence{ + types.ArgBytes{0, 1}, + types.ArgBytes{2, 3}, + }, }) }) @@ -115,6 +115,10 @@ func TestDataCom_SignSequence(t *testing.T) { testFn(t, testConfig{ sender: privateKey, expectedError: "unauthorized", + sequence: types.Sequence{ + types.ArgBytes{0, 1}, + types.ArgBytes{2, 3}, + }, }) }) @@ -124,6 +128,23 @@ func TestDataCom_SignSequence(t *testing.T) { testFn(t, testConfig{ sender: privateKey, expectedError: "unauthorized", + sequence: types.Sequence{ + types.ArgBytes{0, 1}, + types.ArgBytes{2, 3}, + }, + }) + }) + + t.Run("Duplicates found", func(t *testing.T) { + t.Parallel() + + testFn(t, testConfig{ + sender: otherPrivateKey, + expectedError: "duplicate key: 0x49d03a195e239b52779866b33024210fc7dc66e9c2998975c0aa45c1702549d5", + sequence: types.Sequence{ + types.ArgBytes{0, 1}, + types.ArgBytes{0, 1}, + }, }) }) @@ -134,6 +155,10 @@ func TestDataCom_SignSequence(t *testing.T) { sender: otherPrivateKey, expectedError: "failed to store offchain data", storeOffChainDataReturns: []interface{}{errors.New("error")}, + sequence: types.Sequence{ + types.ArgBytes{0, 1}, + types.ArgBytes{2, 3}, + }, }) }) @@ -150,6 +175,10 @@ func TestDataCom_SignSequence(t *testing.T) { signer: key, storeOffChainDataReturns: []interface{}{nil}, expectedError: "failed to sign", + sequence: types.Sequence{ + types.ArgBytes{0, 1}, + types.ArgBytes{2, 3}, + }, }) }) @@ -159,6 +188,10 @@ func TestDataCom_SignSequence(t *testing.T) { testFn(t, testConfig{ sender: otherPrivateKey, storeOffChainDataReturns: []interface{}{nil}, + sequence: types.Sequence{ + types.ArgBytes{0, 1}, + types.ArgBytes{2, 3}, + }, }) }) } From 3cc6e749eb7efc6d411d1572bd84704e1ec69122 Mon Sep 17 00:00:00 2001 From: begmaroman Date: Tue, 13 Aug 2024 21:12:26 +0100 Subject: [PATCH 02/10] Remove duplicates offchain data when storing in DB --- db/db.go | 3 ++ services/datacom/datacom.go | 13 ------- services/datacom/datacom_test.go | 13 ------- types/types.go | 13 +++++++ types/types_test.go | 59 ++++++++++++++++++++++++++++++++ 5 files changed, 75 insertions(+), 26 deletions(-) diff --git a/db/db.go b/db/db.go index 2068315..c4e4bed 100644 --- a/db/db.go +++ b/db/db.go @@ -374,6 +374,9 @@ func buildBatchKeysInsertQuery(bks []types.BatchKey) (string, []interface{}) { func buildOffchainDataInsertQuery(ods []types.OffChainData) (string, []interface{}) { const columnsAffected = 3 + // Remove duplicates from the given offchain data + ods = types.RemoveDuplicateOffChainData(ods) + args := make([]interface{}, len(ods)*columnsAffected) values := make([]string, len(ods)) for i, od := range ods { diff --git a/services/datacom/datacom.go b/services/datacom/datacom.go index 0f97891..35ff0d7 100644 --- a/services/datacom/datacom.go +++ b/services/datacom/datacom.go @@ -55,19 +55,6 @@ func (d *Endpoints) signSequence(signedSequence types.SignedSequenceInterface) ( return "0x0", rpc.NewRPCError(rpc.DefaultErrorCode, "unauthorized") } - // Make sure there are no duplicates in the given offchain data list - existingData := make(map[string]struct{}) - offChainData := signedSequence.OffChainData() - for _, data := range offChainData { - key := data.Key.Hex() - if _, ok := existingData[key]; ok { - // The given key already exist in the offchain data list - return "0x0", rpc.NewRPCError(rpc.DefaultErrorCode, fmt.Sprintf("duplicate key: %s", key)) - } - - existingData[key] = struct{}{} - } - // Store off-chain data by hash (hash(L2Data): L2Data) if err = d.db.StoreOffChainData(context.Background(), signedSequence.OffChainData()); err != nil { return "0x0", rpc.NewRPCError(rpc.DefaultErrorCode, diff --git a/services/datacom/datacom_test.go b/services/datacom/datacom_test.go index 21669b6..8261f43 100644 --- a/services/datacom/datacom_test.go +++ b/services/datacom/datacom_test.go @@ -135,19 +135,6 @@ func TestDataCom_SignSequence(t *testing.T) { }) }) - t.Run("Duplicates found", func(t *testing.T) { - t.Parallel() - - testFn(t, testConfig{ - sender: otherPrivateKey, - expectedError: "duplicate key: 0x49d03a195e239b52779866b33024210fc7dc66e9c2998975c0aa45c1702549d5", - sequence: types.Sequence{ - types.ArgBytes{0, 1}, - types.ArgBytes{0, 1}, - }, - }) - }) - t.Run("Fail to store off chain data", func(t *testing.T) { t.Parallel() diff --git a/types/types.go b/types/types.go index 146c195..6d262d7 100644 --- a/types/types.go +++ b/types/types.go @@ -37,6 +37,19 @@ type OffChainData struct { BatchNum uint64 } +// RemoveDuplicateOffChainData removes duplicate off chain data +func RemoveDuplicateOffChainData(ods []OffChainData) []OffChainData { + seen := make(map[common.Hash]struct{}) + result := []OffChainData{} + for _, od := range ods { + if _, ok := seen[od.Key]; !ok { + seen[od.Key] = struct{}{} + result = append(result, od) + } + } + return result +} + // ArgUint64 helps to marshal uint64 values provided in the RPC requests type ArgUint64 uint64 diff --git a/types/types_test.go b/types/types_test.go index f49bd2e..38a87ae 100644 --- a/types/types_test.go +++ b/types/types_test.go @@ -3,6 +3,9 @@ package types import ( "testing" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) @@ -39,3 +42,59 @@ func TestIsHexValid(t *testing.T) { }) } } + +func TestRemoveDuplicateOffChainData(t *testing.T) { + type args struct { + ods []OffChainData + } + tests := []struct { + name string + args args + want []OffChainData + }{ + { + name: "no duplicates", + args: args{ + ods: []OffChainData{ + { + Key: common.BytesToHash([]byte("key1")), + }, + { + Key: common.BytesToHash([]byte("key2")), + }, + }, + }, + want: []OffChainData{ + { + Key: common.BytesToHash([]byte("key1")), + }, + { + Key: common.BytesToHash([]byte("key2")), + }, + }, + }, + { + name: "with duplicates", + args: args{ + ods: []OffChainData{ + { + Key: common.BytesToHash([]byte("key1")), + }, + { + Key: common.BytesToHash([]byte("key1")), + }, + }, + }, + want: []OffChainData{ + { + Key: common.BytesToHash([]byte("key1")), + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equalf(t, tt.want, RemoveDuplicateOffChainData(tt.args.ods), "RemoveDuplicateOffChainData(%v)", tt.args.ods) + }) + } +} From e42be0329b16706a02be886f7c9846b5b7a9ced9 Mon Sep 17 00:00:00 2001 From: begmaroman Date: Tue, 13 Aug 2024 21:13:31 +0100 Subject: [PATCH 03/10] Fixed linter --- types/types_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/types/types_test.go b/types/types_test.go index 38a87ae..c8e3493 100644 --- a/types/types_test.go +++ b/types/types_test.go @@ -5,7 +5,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) From bc9b29371211aa4a0d06cd9823677bf90d4b424e Mon Sep 17 00:00:00 2001 From: begmaroman Date: Wed, 14 Aug 2024 10:03:14 +0100 Subject: [PATCH 04/10] Fixed tests --- db/db.go | 2 ++ db/db_test.go | 58 +++++++++++++++++++++++++-------------------------- 2 files changed, 31 insertions(+), 29 deletions(-) diff --git a/db/db.go b/db/db.go index c4e4bed..2ddfe4f 100644 --- a/db/db.go +++ b/db/db.go @@ -375,7 +375,9 @@ func buildOffchainDataInsertQuery(ods []types.OffChainData) (string, []interface const columnsAffected = 3 // Remove duplicates from the given offchain data + fmt.Println("ods 1", ods) ods = types.RemoveDuplicateOffChainData(ods) + fmt.Println("ods 2", ods) args := make([]interface{}, len(ods)*columnsAffected) values := make([]string, len(ods)) diff --git a/db/db_test.go b/db/db_test.go index 8087dc5..4f26888 100644 --- a/db/db_test.go +++ b/db/db_test.go @@ -175,7 +175,7 @@ func Test_DB_StoreUnresolvedBatchKeys(t *testing.T) { name: "one value inserted", bk: []types.BatchKey{{ Number: 1, - Hash: common.HexToHash("key1"), + Hash: common.BytesToHash([]byte("key1")), }}, expectedQuery: `INSERT INTO data_node.unresolved_batches (num, hash) VALUES ($1, $2) ON CONFLICT (num, hash) DO NOTHING`, }, @@ -183,10 +183,10 @@ func Test_DB_StoreUnresolvedBatchKeys(t *testing.T) { name: "several values inserted", bk: []types.BatchKey{{ Number: 1, - Hash: common.HexToHash("key1"), + Hash: common.BytesToHash([]byte("key1")), }, { Number: 2, - Hash: common.HexToHash("key2"), + Hash: common.BytesToHash([]byte("key2")), }}, expectedQuery: `INSERT INTO data_node.unresolved_batches (num, hash) VALUES ($1, $2),($3, $4) ON CONFLICT (num, hash) DO NOTHING`, }, @@ -194,7 +194,7 @@ func Test_DB_StoreUnresolvedBatchKeys(t *testing.T) { name: "error returned", bk: []types.BatchKey{{ Number: 1, - Hash: common.HexToHash("key1"), + Hash: common.BytesToHash([]byte("key1")), }}, expectedQuery: `INSERT INTO data_node.unresolved_batches (num, hash) VALUES ($1, $2) ON CONFLICT (num, hash) DO NOTHING`, returnErr: errors.New("test error"), @@ -262,14 +262,14 @@ func Test_DB_GetUnresolvedBatchKeys(t *testing.T) { name: "successfully selected data", bks: []types.BatchKey{{ Number: 1, - Hash: common.HexToHash("key1"), + Hash: common.BytesToHash([]byte("key1")), }}, }, { name: "error returned", bks: []types.BatchKey{{ Number: 1, - Hash: common.HexToHash("key1"), + Hash: common.BytesToHash([]byte("key1")), }}, returnErr: errors.New("test error"), }, @@ -332,7 +332,7 @@ func Test_DB_DeleteUnresolvedBatchKeys(t *testing.T) { name: "value deleted", bks: []types.BatchKey{{ Number: 1, - Hash: common.HexToHash("key1"), + Hash: common.BytesToHash([]byte("key1")), }}, expectedQuery: `DELETE FROM data_node.unresolved_batches WHERE (num, hash) IN (($1, $2))`, }, @@ -340,10 +340,10 @@ func Test_DB_DeleteUnresolvedBatchKeys(t *testing.T) { name: "multiple values deleted", bks: []types.BatchKey{{ Number: 1, - Hash: common.HexToHash("key1"), + Hash: common.BytesToHash([]byte("key1")), }, { Number: 2, - Hash: common.HexToHash("key2"), + Hash: common.BytesToHash([]byte("key2")), }}, expectedQuery: `DELETE FROM data_node.unresolved_batches WHERE (num, hash) IN (($1, $2),($3, $4))`, }, @@ -351,7 +351,7 @@ func Test_DB_DeleteUnresolvedBatchKeys(t *testing.T) { name: "error returned", bks: []types.BatchKey{{ Number: 1, - Hash: common.HexToHash("key1"), + Hash: common.BytesToHash([]byte("key1")), }}, expectedQuery: `DELETE FROM data_node.unresolved_batches WHERE (num, hash) IN (($1, $2))`, returnErr: errors.New("test error"), @@ -416,7 +416,7 @@ func Test_DB_StoreOffChainData(t *testing.T) { { name: "one value inserted", ods: []types.OffChainData{{ - Key: common.HexToHash("key1"), + Key: common.BytesToHash([]byte("key1")), Value: []byte("value1"), }}, expectedQuery: `INSERT INTO data_node.offchain_data (key, value, batch_num) VALUES ($1, $2, $3) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, batch_num = EXCLUDED.batch_num`, @@ -424,10 +424,10 @@ func Test_DB_StoreOffChainData(t *testing.T) { { name: "several values inserted", ods: []types.OffChainData{{ - Key: common.HexToHash("key1"), + Key: common.BytesToHash([]byte("key1")), Value: []byte("value1"), }, { - Key: common.HexToHash("key2"), + Key: common.BytesToHash([]byte("key2")), Value: []byte("value2"), }}, expectedQuery: `INSERT INTO data_node.offchain_data (key, value, batch_num) VALUES ($1, $2, $3),($4, $5, $6) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, batch_num = EXCLUDED.batch_num`, @@ -435,7 +435,7 @@ func Test_DB_StoreOffChainData(t *testing.T) { { name: "error returned", ods: []types.OffChainData{{ - Key: common.HexToHash("key1"), + Key: common.BytesToHash([]byte("key1")), Value: []byte("value1"), }}, expectedQuery: `INSERT INTO data_node.offchain_data (key, value, batch_num) VALUES ($1, $2, $3) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, batch_num = EXCLUDED.batch_num`, @@ -499,13 +499,13 @@ func Test_DB_GetOffChainData(t *testing.T) { { name: "successfully selected value", od: []types.OffChainData{{ - Key: common.HexToHash("key1"), + Key: common.BytesToHash([]byte("key1")), Value: []byte("value1"), BatchNum: 1, }}, key: common.BytesToHash([]byte("key1")), expected: &types.OffChainData{ - Key: common.HexToHash("key1"), + Key: common.BytesToHash([]byte("key1")), Value: []byte("value1"), BatchNum: 1, }, @@ -513,7 +513,7 @@ func Test_DB_GetOffChainData(t *testing.T) { { name: "error returned", od: []types.OffChainData{{ - Key: common.HexToHash("key1"), + Key: common.BytesToHash([]byte("key1")), Value: []byte("value1"), }}, key: common.BytesToHash([]byte("key1")), @@ -522,7 +522,7 @@ func Test_DB_GetOffChainData(t *testing.T) { { name: "no rows", od: []types.OffChainData{{ - Key: common.HexToHash("key1"), + Key: common.BytesToHash([]byte("key1")), Value: []byte("value1"), }}, key: common.BytesToHash([]byte("undefined")), @@ -587,7 +587,7 @@ func Test_DB_ListOffChainData(t *testing.T) { { name: "successfully selected one value", od: []types.OffChainData{{ - Key: common.HexToHash("key1"), + Key: common.BytesToHash([]byte("key1")), Value: []byte("value1"), }}, keys: []common.Hash{ @@ -605,11 +605,11 @@ func Test_DB_ListOffChainData(t *testing.T) { { name: "successfully selected two values", od: []types.OffChainData{{ - Key: common.HexToHash("key1"), + Key: common.BytesToHash([]byte("key1")), Value: []byte("value1"), BatchNum: 1, }, { - Key: common.HexToHash("key2"), + Key: common.BytesToHash([]byte("key2")), Value: []byte("value2"), BatchNum: 2, }}, @@ -634,7 +634,7 @@ func Test_DB_ListOffChainData(t *testing.T) { { name: "error returned", od: []types.OffChainData{{ - Key: common.HexToHash("key1"), + Key: common.BytesToHash([]byte("key1")), Value: []byte("value1"), }}, keys: []common.Hash{ @@ -646,7 +646,7 @@ func Test_DB_ListOffChainData(t *testing.T) { { name: "no rows", od: []types.OffChainData{{ - Key: common.HexToHash("key1"), + Key: common.BytesToHash([]byte("key1")), Value: []byte("value1"), }}, keys: []common.Hash{ @@ -722,10 +722,10 @@ func Test_DB_CountOffchainData(t *testing.T) { { name: "two values found", od: []types.OffChainData{{ - Key: common.HexToHash("key1"), + Key: common.BytesToHash([]byte("key1")), Value: []byte("value1"), }, { - Key: common.HexToHash("key1"), + Key: common.BytesToHash([]byte("key1")), Value: []byte("value2"), }}, count: 2, @@ -737,7 +737,7 @@ func Test_DB_CountOffchainData(t *testing.T) { { name: "error returned", od: []types.OffChainData{{ - Key: common.HexToHash("key1"), + Key: common.BytesToHash([]byte("key1")), Value: []byte("value1"), }}, returnErr: errors.New("test error"), @@ -797,11 +797,11 @@ func Test_DB_DetectOffchainDataGaps(t *testing.T) { { name: "one gap found", seed: []types.OffChainData{{ - Key: common.HexToHash("key1"), + Key: common.BytesToHash([]byte("key1")), Value: []byte("value1"), BatchNum: 1, }, { - Key: common.HexToHash("key2"), + Key: common.BytesToHash([]byte("key2")), Value: []byte("value2"), BatchNum: 2, }, { @@ -816,7 +816,7 @@ func Test_DB_DetectOffchainDataGaps(t *testing.T) { { name: "error returned", seed: []types.OffChainData{{ - Key: common.HexToHash("key1"), + Key: common.BytesToHash([]byte("key1")), Value: []byte("value1"), }}, returnErr: errors.New("test error"), From 4877a490f60f2af9d15443285adf0e912097a119 Mon Sep 17 00:00:00 2001 From: begmaroman Date: Wed, 14 Aug 2024 10:12:27 +0100 Subject: [PATCH 05/10] Fixed linter --- pkg/backoff/backoff.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/backoff/backoff.go b/pkg/backoff/backoff.go index 9bae533..9476a2a 100644 --- a/pkg/backoff/backoff.go +++ b/pkg/backoff/backoff.go @@ -3,9 +3,9 @@ package backoff import "time" // Exponential performs exponential backoff attempts on a given action -func Exponential(action func() error, max uint, wait time.Duration) error { +func Exponential(action func() error, attempts uint, wait time.Duration) error { var err error - for i := uint(0); i < max; i++ { + for i := uint(0); i < attempts; i++ { if err = action(); err == nil { return nil } From 3007e02237d6258170da49bcbf44e976ef36d063 Mon Sep 17 00:00:00 2001 From: begmaroman Date: Wed, 14 Aug 2024 15:29:36 +0100 Subject: [PATCH 06/10] Fixed nits --- db/db.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/db/db.go b/db/db.go index 2ddfe4f..c4e4bed 100644 --- a/db/db.go +++ b/db/db.go @@ -375,9 +375,7 @@ func buildOffchainDataInsertQuery(ods []types.OffChainData) (string, []interface const columnsAffected = 3 // Remove duplicates from the given offchain data - fmt.Println("ods 1", ods) ods = types.RemoveDuplicateOffChainData(ods) - fmt.Println("ods 2", ods) args := make([]interface{}, len(ods)*columnsAffected) values := make([]string, len(ods)) From bf1e2f95da6a63383f5d4a76654abbc89739b70b Mon Sep 17 00:00:00 2001 From: bros Date: Thu, 15 Aug 2024 12:44:08 +0000 Subject: [PATCH 07/10] wip --- go.mod | 1 + go.sum | 2 ++ services/datacom/datacom.go | 3 ++ types/sequencebanana.go | 60 +++++++++++++++++++------------------ 4 files changed, 37 insertions(+), 29 deletions(-) diff --git a/go.mod b/go.mod index 2747956..7ed9e87 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/ethereum/go-ethereum v1.13.14 github.com/gorilla/websocket v1.5.0 github.com/hermeznetwork/tracerr v0.3.2 + github.com/iden3/go-iden3-crypto v0.0.16 github.com/invopop/jsonschema v0.7.0 github.com/jmoiron/sqlx v1.2.0 github.com/lib/pq v1.10.7 diff --git a/go.sum b/go.sum index 90b3279..61e7b3e 100644 --- a/go.sum +++ b/go.sum @@ -162,6 +162,8 @@ github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFck github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 h1:i462o439ZjprVSFSZLZxcsoAe592sZB1rci2Z8j4wdk= github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/iden3/go-iden3-crypto v0.0.16 h1:zN867xiz6HgErXVIV/6WyteGcOukE9gybYTorBMEdsk= +github.com/iden3/go-iden3-crypto v0.0.16/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E= github.com/invopop/jsonschema v0.7.0 h1:2vgQcBz1n256N+FpX3Jq7Y17AjYt46Ig3zIWyy770So= github.com/invopop/jsonschema v0.7.0/go.mod h1:O9uiLokuu0+MGFlyiaqtWxwqJm41/+8Nj0lD7A36YH0= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= diff --git a/services/datacom/datacom.go b/services/datacom/datacom.go index 35ff0d7..e474b36 100644 --- a/services/datacom/datacom.go +++ b/services/datacom/datacom.go @@ -6,9 +6,11 @@ import ( "fmt" "github.com/0xPolygon/cdk-data-availability/db" + "github.com/0xPolygon/cdk-data-availability/log" "github.com/0xPolygon/cdk-data-availability/rpc" "github.com/0xPolygon/cdk-data-availability/sequencer" "github.com/0xPolygon/cdk-data-availability/types" + "github.com/ethereum/go-ethereum/common" ) // APIDATACOM is the namespace of the datacom service @@ -41,6 +43,7 @@ func (d *Endpoints) SignSequence(signedSequence types.SignedSequence) (interface // After storing the data that will be sent hashed to the contract, it returns the signature. // This endpoint is only accessible to the sequencer func (d *Endpoints) SignSequenceBanana(signedSequence types.SignedSequenceBanana) (interface{}, rpc.Error) { + log.Debugf("signing sequence, hash to sign: %s", common.BytesToHash(signedSequence.Sequence.HashToSign())) return d.signSequence(&signedSequence) } diff --git a/types/sequencebanana.go b/types/sequencebanana.go index 605f7cd..32c146f 100644 --- a/types/sequencebanana.go +++ b/types/sequencebanana.go @@ -3,10 +3,11 @@ package types import ( "crypto/ecdsa" "errors" + "math/big" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" - solsha3 "github.com/miguelmota/go-solidity-sha3" + "github.com/iden3/go-iden3-crypto/keccak256" ) // Batch represents the batch data that the sequencer will send to L1 @@ -30,39 +31,40 @@ type SequenceBanana struct { // HashToSign returns the accumulated input hash of the sequence. // Note that this is equivalent to what happens on the smart contract func (s *SequenceBanana) HashToSign() []byte { - currentHash := s.OldAccInputHash.Bytes() + v1 := s.OldAccInputHash.Bytes() for _, b := range s.Batches { - types := []string{ - "bytes32", // oldAccInputHash - "bytes32", // currentTransactionsHash - "bytes32", // forcedGlobalExitRoot or l1InfoRoot - "uint64", // forcedTimestamp - "address", // coinbase - "bytes32", // forcedBlockHashL1 - } - var values []interface{} + v2 := b.L2Data + var v3, v4 []byte if b.ForcedTimestamp > 0 { - values = []interface{}{ - currentHash, - crypto.Keccak256(b.L2Data), - b.ForcedGER, - b.ForcedTimestamp, - b.Coinbase, - b.ForcedBlockHashL1, - } + v3 = b.ForcedGER.Bytes() + v4 = big.NewInt(0).SetUint64(uint64(b.ForcedTimestamp)).Bytes() } else { - values = []interface{}{ - currentHash, - crypto.Keccak256(b.L2Data), - s.L1InfoRoot, - s.MaxSequenceTimestamp, - b.Coinbase, - common.Hash{}, - } + v3 = b.ForcedGER.Bytes() + v4 = big.NewInt(0).SetUint64(uint64(b.ForcedTimestamp)).Bytes() + } + v5 := b.Coinbase.Bytes() + v6 := b.ForcedBlockHashL1.Bytes() + + // Add 0s to make values 32 bytes long + for len(v1) < 32 { + v1 = append([]byte{0}, v1...) + } + v2 = keccak256.Hash(v2) + for len(v3) < 32 { + v3 = append([]byte{0}, v3...) + } + for len(v4) < 8 { + v4 = append([]byte{0}, v4...) + } + for len(v5) < 20 { + v5 = append([]byte{0}, v5...) + } + for len(v6) < 32 { + v6 = append([]byte{0}, v6...) } - currentHash = solsha3.SoliditySHA3(types, values) + v1 = keccak256.Hash(v1, v2, v3, v4, v5, v6) } - return currentHash + return v1 } // Sign returns a signed sequence by the private key. From d1436f1a29c8e099833aec9c8c77c4caf4a2005c Mon Sep 17 00:00:00 2001 From: bros Date: Thu, 15 Aug 2024 12:44:33 +0000 Subject: [PATCH 08/10] wip --- types/sequencebanana.go | 1 + 1 file changed, 1 insertion(+) diff --git a/types/sequencebanana.go b/types/sequencebanana.go index 32c146f..755ea68 100644 --- a/types/sequencebanana.go +++ b/types/sequencebanana.go @@ -64,6 +64,7 @@ func (s *SequenceBanana) HashToSign() []byte { } v1 = keccak256.Hash(v1, v2, v3, v4, v5, v6) } + return v1 } From 230aa34389caa01bbd5ccc64af331e1d14af6963 Mon Sep 17 00:00:00 2001 From: bros Date: Thu, 15 Aug 2024 12:50:53 +0000 Subject: [PATCH 09/10] wip --- types/sequencebanana.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/types/sequencebanana.go b/types/sequencebanana.go index 755ea68..de91c1e 100644 --- a/types/sequencebanana.go +++ b/types/sequencebanana.go @@ -36,8 +36,8 @@ func (s *SequenceBanana) HashToSign() []byte { v2 := b.L2Data var v3, v4 []byte if b.ForcedTimestamp > 0 { - v3 = b.ForcedGER.Bytes() - v4 = big.NewInt(0).SetUint64(uint64(b.ForcedTimestamp)).Bytes() + v3 = s.L1InfoRoot.Bytes() + v4 = big.NewInt(0).SetUint64(uint64(s.MaxSequenceTimestamp)).Bytes() } else { v3 = b.ForcedGER.Bytes() v4 = big.NewInt(0).SetUint64(uint64(b.ForcedTimestamp)).Bytes() From f3d73dfba97a4a1fec0bec6f1af28913ae21df5f Mon Sep 17 00:00:00 2001 From: bros Date: Thu, 15 Aug 2024 12:52:41 +0000 Subject: [PATCH 10/10] wip --- types/sequencebanana.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/types/sequencebanana.go b/types/sequencebanana.go index de91c1e..c4d3ea6 100644 --- a/types/sequencebanana.go +++ b/types/sequencebanana.go @@ -36,11 +36,11 @@ func (s *SequenceBanana) HashToSign() []byte { v2 := b.L2Data var v3, v4 []byte if b.ForcedTimestamp > 0 { - v3 = s.L1InfoRoot.Bytes() - v4 = big.NewInt(0).SetUint64(uint64(s.MaxSequenceTimestamp)).Bytes() - } else { v3 = b.ForcedGER.Bytes() v4 = big.NewInt(0).SetUint64(uint64(b.ForcedTimestamp)).Bytes() + } else { + v3 = s.L1InfoRoot.Bytes() + v4 = big.NewInt(0).SetUint64(uint64(s.MaxSequenceTimestamp)).Bytes() } v5 := b.Coinbase.Bytes() v6 := b.ForcedBlockHashL1.Bytes()