From 50f69e0c2def7dcc9202917f1279a8b4daec93c1 Mon Sep 17 00:00:00 2001 From: Alonso Rodriguez Date: Sat, 21 Dec 2024 23:16:53 +0100 Subject: [PATCH] Cherrypick/v0.6.0 rc5 (#722) * fix globalIndex (#719) * primary key modified (#721) --- db/pgstorage/migrations/0014.sql | 9 ++++ db/pgstorage/migrations/0014_test.go | 81 ++++++++++++++++++++++++++++ etherman/etherman.go | 2 +- etherman/etherman_test.go | 50 +++++++++++++++-- 4 files changed, 138 insertions(+), 4 deletions(-) create mode 100644 db/pgstorage/migrations/0014.sql create mode 100644 db/pgstorage/migrations/0014_test.go diff --git a/db/pgstorage/migrations/0014.sql b/db/pgstorage/migrations/0014.sql new file mode 100644 index 00000000..b171d111 --- /dev/null +++ b/db/pgstorage/migrations/0014.sql @@ -0,0 +1,9 @@ +-- +migrate Up + +ALTER TABLE sync.claim DROP CONSTRAINT claim_pkey; +ALTER TABLE sync.claim ADD PRIMARY KEY (index, rollup_index, network_id, mainnet_flag); + +-- +migrate Down + +ALTER TABLE sync.claim DROP CONSTRAINT claim_pkey; +ALTER TABLE sync.claim ADD PRIMARY KEY (index, rollup_index, network_id); \ No newline at end of file diff --git a/db/pgstorage/migrations/0014_test.go b/db/pgstorage/migrations/0014_test.go new file mode 100644 index 00000000..dcf50600 --- /dev/null +++ b/db/pgstorage/migrations/0014_test.go @@ -0,0 +1,81 @@ +package migrations_test + +import ( + "database/sql" + "errors" + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +type migrationTest0014 struct{} + +const conflictingDepositNet1ToNet3 = ` +INSERT INTO sync.claim (block_id, network_id, index, mainnet_flag, rollup_index, orig_addr, dest_addr, tx_hash) +VALUES(69, 3, 0, false, 0, decode('00','hex'), decode('00','hex'), decode('00','hex')); +` // Rollup 1 to Rollup 3 + +func (m migrationTest0014) InsertData(db *sql.DB) error { + block := "INSERT INTO sync.block (id, block_num, block_hash, parent_hash, network_id, received_at) VALUES(69, 2803824, decode('27474F16174BBE50C294FE13C190B92E42B2368A6D4AEB8A4A015F52816296C3','hex'), decode('C9B5033799ADF3739383A0489EFBE8A0D4D5E4478778A4F4304562FD51AE4C07','hex'), 3, '0001-01-01 01:00:00.000');" + if _, err := db.Exec(block); err != nil { + return err + } + const originalDepositSQL = ` + INSERT INTO sync.claim (block_id, network_id, index, mainnet_flag, rollup_index, orig_addr, dest_addr, tx_hash) + VALUES(69, 3, 0, true, 0, decode('00','hex'), decode('00','hex'), decode('00','hex')); + ` // L1 to Rollup 3 + if _, err := db.Exec(originalDepositSQL); err != nil { + return err + } + _, err := db.Exec(conflictingDepositNet1ToNet3) + if err == nil || !strings.Contains(err.Error(), "ERROR: duplicate key value violates unique constraint \"claim_pkey\" (SQLSTATE 23505)") { + return errors.New("should violate primary key") + } + + return nil +} + +func (m migrationTest0014) RunAssertsAfterMigrationUp(t *testing.T, db *sql.DB) { + // check that original row still in there + selectClaim := `SELECT block_id, network_id, index, mainnet_flag, rollup_index FROM sync.claim;` + row := db.QueryRow(selectClaim) + var ( + block_id, network_id, index, rollup_index int + mainnet_flag bool + ) + assert.NoError(t, row.Scan(&block_id, &network_id, &index, &mainnet_flag, &rollup_index)) + assert.Equal(t, 69, block_id) + assert.Equal(t, 3, network_id) + assert.Equal(t, 0, index) + assert.Equal(t, true, mainnet_flag) + assert.Equal(t, 0, rollup_index) + + // Add deposit that originally would have caused pkey violation + _, err := db.Exec(conflictingDepositNet1ToNet3) + assert.NoError(t, err) + + // Remove conflicting deposit so it's possible to run the migration down + _, err = db.Exec("DELETE FROM sync.claim WHERE mainnet_flag = false;") + assert.NoError(t, err) +} + +func (m migrationTest0014) RunAssertsAfterMigrationDown(t *testing.T, db *sql.DB) { + // check that original row still in there + selectClaim := `SELECT block_id, network_id, index, mainnet_flag, rollup_index FROM sync.claim;` + row := db.QueryRow(selectClaim) + var ( + block_id, network_id, index, rollup_index int + mainnet_flag bool + ) + assert.NoError(t, row.Scan(&block_id, &network_id, &index, &mainnet_flag, &rollup_index)) + assert.Equal(t, 69, block_id) + assert.Equal(t, 3, network_id) + assert.Equal(t, 0, index) + assert.Equal(t, true, mainnet_flag) + assert.Equal(t, 0, rollup_index) +} + +func TestMigration0014(t *testing.T) { + runMigrationTest(t, 14, migrationTest0014{}) +} diff --git a/etherman/etherman.go b/etherman/etherman.go index 4d6576dc..3d773d94 100644 --- a/etherman/etherman.go +++ b/etherman/etherman.go @@ -675,7 +675,7 @@ func DecodeGlobalIndex(globalIndex *big.Int) (bool, uint32, uint32, error) { } mainnetFlag := big.NewInt(0).SetBytes([]byte{gIBytes[23]}).Uint64() == 1 rollupIndex := big.NewInt(0).SetBytes(gIBytes[24:28]) - localRootIndex := big.NewInt(0).SetBytes(gIBytes[29:32]) + localRootIndex := big.NewInt(0).SetBytes(gIBytes[28:32]) if rollupIndex.Uint64() > math.MaxUint32 { return false, 0, 0, fmt.Errorf("invalid rollupIndex length. Should be fit into uint32 type") } diff --git a/etherman/etherman_test.go b/etherman/etherman_test.go index f3019d93..ae6ea3ba 100644 --- a/etherman/etherman_test.go +++ b/etherman/etherman_test.go @@ -2,6 +2,7 @@ package etherman import ( "context" + "math" "math/big" "testing" @@ -181,6 +182,18 @@ func TestDecodeGlobalIndex(t *testing.T) { assert.Equal(t, true, mainnetFlag) assert.Equal(t, uint32(0), rollupIndex) assert.Equal(t, uint32(0), localExitRootIndex) + + globalIndex, _ = big.NewInt(0).SetString("18446744073709551615", 0) + + gi = globalIndex.FillBytes(buf[:]) + for _, n := range gi { + t.Logf("%08b ", n) + } + mainnetFlag, rollupIndex, localExitRootIndex, err = DecodeGlobalIndex(globalIndex) + require.NoError(t, err) + assert.Equal(t, false, mainnetFlag) + assert.Equal(t, uint32(math.MaxUint32), rollupIndex) + assert.Equal(t, uint32(math.MaxUint32), localExitRootIndex) } func TestVerifyBatchEvent(t *testing.T) { @@ -238,7 +251,9 @@ func TestGenerateGlobalIndex(t *testing.T) { mainnetFlag, rollupIndex, localExitRootIndex := false, uint32(1), uint32(11) globalIndexGenerated := GenerateGlobalIndex(mainnetFlag, rollupIndex, localExitRootIndex) t.Log("First test number:") - for _, n := range globalIndexGenerated.Bytes() { + var buf [32]byte + gIBytes := globalIndexGenerated.FillBytes(buf[:]) + for _, n := range gIBytes { t.Logf("%08b ", n) } assert.Equal(t, globalIndex, globalIndexGenerated) @@ -247,7 +262,8 @@ func TestGenerateGlobalIndex(t *testing.T) { mainnetFlag, rollupIndex, localExitRootIndex = false, uint32(2), uint32(12) globalIndexGenerated = GenerateGlobalIndex(mainnetFlag, rollupIndex, localExitRootIndex) t.Log("Second test number:") - for _, n := range globalIndexGenerated.Bytes() { + gIBytes = globalIndexGenerated.FillBytes(buf[:]) + for _, n := range gIBytes { t.Logf("%08b ", n) } assert.Equal(t, globalIndex, globalIndexGenerated) @@ -256,7 +272,35 @@ func TestGenerateGlobalIndex(t *testing.T) { mainnetFlag, rollupIndex, localExitRootIndex = true, uint32(0), uint32(11) globalIndexGenerated = GenerateGlobalIndex(mainnetFlag, rollupIndex, localExitRootIndex) t.Log("Third test number:") - for _, n := range globalIndexGenerated.Bytes() { + gIBytes = globalIndexGenerated.FillBytes(buf[:]) + for _, n := range gIBytes { + t.Logf("%08b ", n) + } + assert.Equal(t, globalIndex, globalIndexGenerated) + + globalIndex, _ = big.NewInt(0).SetString("18446744073709551615", 0) + globalIndexGenerated = GenerateGlobalIndex(false, math.MaxUint32, math.MaxUint32) + t.Log("Fourth test number:") + gIBytes = globalIndexGenerated.FillBytes(buf[:]) + for _, n := range gIBytes { + t.Logf("%08b ", n) + } + assert.Equal(t, globalIndex, globalIndexGenerated) + + globalIndex = big.NewInt(0) + globalIndexGenerated = GenerateGlobalIndex(false, uint32(0), uint32(0)) + t.Log("Fourth test number:") + gIBytes = globalIndexGenerated.FillBytes(buf[:]) + for _, n := range gIBytes { + t.Logf("%08b ", n) + } + assert.Equal(t, globalIndex.String(), globalIndexGenerated.String()) + + globalIndex, _ = big.NewInt(0).SetString("18446744073709551616", 0) + globalIndexGenerated = GenerateGlobalIndex(true, uint32(0), uint32(0)) + t.Log("Fourth test number:") + gIBytes = globalIndexGenerated.FillBytes(buf[:]) + for _, n := range gIBytes { t.Logf("%08b ", n) } assert.Equal(t, globalIndex, globalIndexGenerated)