Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix duplicate key error on host batch insertion #2292

Merged
merged 6 commits into from
Feb 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion go/host/storage/hostdb/batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func AddBatch(dbtx *dbTransaction, statements *SQLStatements, batch *common.ExtB
extBatch, // ext_batch
)
if err != nil {
if strings.Contains(strings.ToLower(err.Error()), "unique") {
if IsRowExistsError(err) {
return errutil.ErrAlreadyExists
}
return fmt.Errorf("host failed to insert batch: %w", err)
Expand Down Expand Up @@ -497,3 +497,7 @@ func fetchBatchTxs(db *sql.DB, whereQuery string, batchHash []byte) (*common.Tra
Total: uint64(len(transactions)),
}, nil
}

func IsRowExistsError(err error) bool {
return strings.Contains(strings.ToLower(err.Error()), "unique") || strings.Contains(strings.ToLower(err.Error()), "duplicate key")
}
87 changes: 36 additions & 51 deletions go/host/storage/hostdb/batch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"errors"
"math/big"
"testing"
"time"

gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
Expand All @@ -17,8 +16,8 @@ import (
// An arbitrary number to put in the header, to check that the header is retrieved correctly from the DB.

func TestCanStoreAndRetrieveBatchHeader(t *testing.T) {
db, _ := createSQLiteDB(t)
batch := createBatch(batchNumber, []common.L2TxHash{})
db, _ := CreateSQLiteDB(t)
batch := CreateBatch(batchNumber, []common.L2TxHash{})
dbtx, _ := db.NewDBTransaction()
err := AddBatch(dbtx, db.GetSQLStatement(), &batch)
if err != nil {
Expand All @@ -35,7 +34,7 @@ func TestCanStoreAndRetrieveBatchHeader(t *testing.T) {
}

func TestUnknownBatchHeaderReturnsNotFound(t *testing.T) {
db, _ := createSQLiteDB(t)
db, _ := CreateSQLiteDB(t)
header := types.Header{}

_, err := GetBatchHeader(db, header.Hash())
Expand All @@ -45,15 +44,15 @@ func TestUnknownBatchHeaderReturnsNotFound(t *testing.T) {
}

func TestHigherNumberBatchBecomesBatchHeader(t *testing.T) { //nolint:dupl
db, _ := createSQLiteDB(t)
batchOne := createBatch(batchNumber, []common.L2TxHash{})
db, _ := CreateSQLiteDB(t)
batchOne := CreateBatch(batchNumber, []common.L2TxHash{})
dbtx, _ := db.NewDBTransaction()
err := AddBatch(dbtx, db.GetSQLStatement(), &batchOne)
if err != nil {
t.Errorf("could not store batch. Cause: %s", err)
}

batchTwo := createBatch(batchNumber+1, []common.L2TxHash{})
batchTwo := CreateBatch(batchNumber+1, []common.L2TxHash{})
if err != nil {
t.Errorf("could not create batch. Cause: %s", err)
}
Expand All @@ -75,15 +74,15 @@ func TestHigherNumberBatchBecomesBatchHeader(t *testing.T) { //nolint:dupl
}

func TestLowerNumberBatchDoesNotBecomeBatchHeader(t *testing.T) { //nolint:dupl
db, _ := createSQLiteDB(t)
db, _ := CreateSQLiteDB(t)
dbtx, _ := db.NewDBTransaction()
batchOne := createBatch(batchNumber, []common.L2TxHash{})
batchOne := CreateBatch(batchNumber, []common.L2TxHash{})
err := AddBatch(dbtx, db.GetSQLStatement(), &batchOne)
if err != nil {
t.Errorf("could not store batch. Cause: %s", err)
}

batchTwo := createBatch(batchNumber-1, []common.L2TxHash{})
batchTwo := CreateBatch(batchNumber-1, []common.L2TxHash{})
if err != nil {
t.Errorf("could not create batch. Cause: %s", err)
}
Expand All @@ -104,16 +103,16 @@ func TestLowerNumberBatchDoesNotBecomeBatchHeader(t *testing.T) { //nolint:dupl
}

func TestHeadBatchHeaderIsNotSetInitially(t *testing.T) {
db, _ := createSQLiteDB(t)
db, _ := CreateSQLiteDB(t)
_, err := GetHeadBatchHeader(db)
if !errors.Is(err, errutil.ErrNotFound) {
t.Errorf("head batch was set, but no batchs had been written")
}
}

func TestCanRetrieveBatchHashByNumber(t *testing.T) {
db, _ := createSQLiteDB(t)
batch := createBatch(batchNumber, []common.L2TxHash{})
db, _ := CreateSQLiteDB(t)
batch := CreateBatch(batchNumber, []common.L2TxHash{})
dbtx, _ := db.NewDBTransaction()
err := AddBatch(dbtx, db.GetSQLStatement(), &batch)
if err != nil {
Expand All @@ -131,7 +130,7 @@ func TestCanRetrieveBatchHashByNumber(t *testing.T) {
}

func TestUnknownBatchNumberReturnsNotFound(t *testing.T) {
db, _ := createSQLiteDB(t)
db, _ := CreateSQLiteDB(t)
header := types.Header{Number: big.NewInt(10)}

_, err := GetBatchHashByNumber(db, header.Number)
Expand All @@ -141,9 +140,9 @@ func TestUnknownBatchNumberReturnsNotFound(t *testing.T) {
}

func TestCanRetrieveBatchNumberByTxHash(t *testing.T) {
db, _ := createSQLiteDB(t)
db, _ := CreateSQLiteDB(t)
txHash := gethcommon.BytesToHash([]byte("magicString"))
batch := createBatch(batchNumber, []common.L2TxHash{txHash})
batch := CreateBatch(batchNumber, []common.L2TxHash{txHash})
dbtx, _ := db.NewDBTransaction()
err := AddBatch(dbtx, db.GetSQLStatement(), &batch)
if err != nil {
Expand All @@ -168,7 +167,7 @@ func TestCanRetrieveBatchNumberByTxHash(t *testing.T) {
}

func TestUnknownBatchTxHashReturnsNotFound(t *testing.T) {
db, _ := createSQLiteDB(t)
db, _ := CreateSQLiteDB(t)

_, err := GetBatchNumber(db, gethcommon.BytesToHash([]byte("magicString")))
if !errors.Is(err, errutil.ErrNotFound) {
Expand All @@ -177,9 +176,9 @@ func TestUnknownBatchTxHashReturnsNotFound(t *testing.T) {
}

func TestCanRetrieveBatchTransactions(t *testing.T) {
db, _ := createSQLiteDB(t)
db, _ := CreateSQLiteDB(t)
txHashes := []common.L2TxHash{gethcommon.BytesToHash([]byte("magicStringOne")), gethcommon.BytesToHash([]byte("magicStringTwo"))}
batch := createBatch(batchNumber, txHashes)
batch := CreateBatch(batchNumber, txHashes)
dbtx, _ := db.NewDBTransaction()
err := AddBatch(dbtx, db.GetSQLStatement(), &batch)
if err != nil {
Expand All @@ -202,7 +201,7 @@ func TestCanRetrieveBatchTransactions(t *testing.T) {
}

func TestTransactionsForUnknownBatchReturnsNotFound(t *testing.T) {
db, _ := createSQLiteDB(t)
db, _ := CreateSQLiteDB(t)

_, err := GetBatchNumber(db, gethcommon.BytesToHash([]byte("magicString")))
if !errors.Is(err, errutil.ErrNotFound) {
Expand All @@ -211,17 +210,17 @@ func TestTransactionsForUnknownBatchReturnsNotFound(t *testing.T) {
}

func TestGetLatestBatch(t *testing.T) {
db, _ := createSQLiteDB(t)
db, _ := CreateSQLiteDB(t)
txHashesOne := []common.L2TxHash{gethcommon.BytesToHash([]byte("magicStringOne")), gethcommon.BytesToHash([]byte("magicStringTwo"))}
batchOne := createBatch(batchNumber, txHashesOne)
batchOne := CreateBatch(batchNumber, txHashesOne)
dbtx, _ := db.NewDBTransaction()
err := AddBatch(dbtx, db.GetSQLStatement(), &batchOne)
if err != nil {
t.Errorf("could not store batch. Cause: %s", err)
}

txHashesTwo := []common.L2TxHash{gethcommon.BytesToHash([]byte("magicStringThree")), gethcommon.BytesToHash([]byte("magicStringFour"))}
batchTwo := createBatch(batchNumber+1, txHashesTwo)
batchTwo := CreateBatch(batchNumber+1, txHashesTwo)

err = AddBatch(dbtx, db.GetSQLStatement(), &batchTwo)
if err != nil {
Expand All @@ -240,9 +239,9 @@ func TestGetLatestBatch(t *testing.T) {
}

func TestGetBatchByHeight(t *testing.T) {
db, _ := createSQLiteDB(t)
batch1 := createBatch(batchNumber, []common.L2TxHash{})
batch2 := createBatch(batchNumber+5, []common.L2TxHash{})
db, _ := CreateSQLiteDB(t)
batch1 := CreateBatch(batchNumber, []common.L2TxHash{})
batch2 := CreateBatch(batchNumber+5, []common.L2TxHash{})
dbtx, _ := db.NewDBTransaction()
err := AddBatch(dbtx, db.GetSQLStatement(), &batch1)
if err != nil {
Expand All @@ -263,25 +262,25 @@ func TestGetBatchByHeight(t *testing.T) {
}

func TestGetBatchListing(t *testing.T) {
db, _ := createSQLiteDB(t)
db, _ := CreateSQLiteDB(t)
txHashesOne := []common.L2TxHash{gethcommon.BytesToHash([]byte("magicStringOne")), gethcommon.BytesToHash([]byte("magicStringTwo"))}
batchOne := createBatch(batchNumber, txHashesOne)
batchOne := CreateBatch(batchNumber, txHashesOne)
dbtx, _ := db.NewDBTransaction()
err := AddBatch(dbtx, db.GetSQLStatement(), &batchOne)
if err != nil {
t.Errorf("could not store batch. Cause: %s", err)
}

txHashesTwo := []common.L2TxHash{gethcommon.BytesToHash([]byte("magicStringThree")), gethcommon.BytesToHash([]byte("magicStringFour"))}
batchTwo := createBatch(batchNumber+1, txHashesTwo)
batchTwo := CreateBatch(batchNumber+1, txHashesTwo)

err = AddBatch(dbtx, db.GetSQLStatement(), &batchTwo)
if err != nil {
t.Errorf("could not store batch. Cause: %s", err)
}

txHashesThree := []common.L2TxHash{gethcommon.BytesToHash([]byte("magicStringFive")), gethcommon.BytesToHash([]byte("magicStringSix"))}
batchThree := createBatch(batchNumber+2, txHashesThree)
batchThree := CreateBatch(batchNumber+2, txHashesThree)

err = AddBatch(dbtx, db.GetSQLStatement(), &batchThree)
if err != nil {
Expand Down Expand Up @@ -329,25 +328,25 @@ func TestGetBatchListing(t *testing.T) {
}

func TestGetBatchListingDeprecated(t *testing.T) {
db, _ := createSQLiteDB(t)
db, _ := CreateSQLiteDB(t)
txHashesOne := []common.L2TxHash{gethcommon.BytesToHash([]byte("magicStringOne")), gethcommon.BytesToHash([]byte("magicStringTwo"))}
batchOne := createBatch(batchNumber, txHashesOne)
batchOne := CreateBatch(batchNumber, txHashesOne)
dbtx, _ := db.NewDBTransaction()
err := AddBatch(dbtx, db.GetSQLStatement(), &batchOne)
if err != nil {
t.Errorf("could not store batch. Cause: %s", err)
}

txHashesTwo := []common.L2TxHash{gethcommon.BytesToHash([]byte("magicStringThree")), gethcommon.BytesToHash([]byte("magicStringFour"))}
batchTwo := createBatch(batchNumber+1, txHashesTwo)
batchTwo := CreateBatch(batchNumber+1, txHashesTwo)

err = AddBatch(dbtx, db.GetSQLStatement(), &batchTwo)
if err != nil {
t.Errorf("could not store batch. Cause: %s", err)
}

txHashesThree := []common.L2TxHash{gethcommon.BytesToHash([]byte("magicStringFive")), gethcommon.BytesToHash([]byte("magicStringSix"))}
batchThree := createBatch(batchNumber+2, txHashesThree)
batchThree := CreateBatch(batchNumber+2, txHashesThree)

err = AddBatch(dbtx, db.GetSQLStatement(), &batchThree)
if err != nil {
Expand Down Expand Up @@ -411,17 +410,17 @@ func TestGetBatchListingDeprecated(t *testing.T) {
}

func TestGetBatchTransactions(t *testing.T) {
db, _ := createSQLiteDB(t)
db, _ := CreateSQLiteDB(t)
txHashesOne := []common.L2TxHash{gethcommon.BytesToHash([]byte("magicStringOne")), gethcommon.BytesToHash([]byte("magicStringTwo"))}
batchOne := createBatch(batchNumber, txHashesOne)
batchOne := CreateBatch(batchNumber, txHashesOne)
dbtx, _ := db.NewDBTransaction()
err := AddBatch(dbtx, db.GetSQLStatement(), &batchOne)
if err != nil {
t.Errorf("could not store batch. Cause: %s", err)
}

txHashesTwo := []common.L2TxHash{gethcommon.BytesToHash([]byte("magicStringThree")), gethcommon.BytesToHash([]byte("magicStringFour")), gethcommon.BytesToHash([]byte("magicStringFive"))}
batchTwo := createBatch(batchNumber+1, txHashesTwo)
batchTwo := CreateBatch(batchNumber+1, txHashesTwo)

err = AddBatch(dbtx, db.GetSQLStatement(), &batchTwo)
if err != nil {
Expand All @@ -446,17 +445,3 @@ func TestGetBatchTransactions(t *testing.T) {
t.Errorf("batch transactions were not retrieved correctly")
}
}

func createBatch(batchNum int64, txHashes []common.L2BatchHash) common.ExtBatch {
header := common.BatchHeader{
SequencerOrderNo: big.NewInt(batchNum),
Number: big.NewInt(batchNum),
Time: uint64(time.Now().Unix()),
}
batch := common.ExtBatch{
Header: &header,
TxHashes: txHashes,
}

return batch
}
4 changes: 2 additions & 2 deletions go/host/storage/hostdb/block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
)

func TestCanStoreAndRetrieveBlock(t *testing.T) {
db, _ := createSQLiteDB(t)
db, _ := CreateSQLiteDB(t)
block1 := createBlock(batchNumber)
block2 := createBlock(batchNumber + 1)

Expand Down Expand Up @@ -62,7 +62,7 @@ func TestCanStoreAndRetrieveBlock(t *testing.T) {
}

func TestAddBlockWithForeignKeyConstraint(t *testing.T) {
db, _ := createSQLiteDB(t)
db, _ := CreateSQLiteDB(t)
dbtx, _ := db.NewDBTransaction()
statements := db.GetSQLStatement()
metadata := createRollupMetadata(batchNumber - 10)
Expand Down
22 changes: 11 additions & 11 deletions go/host/storage/hostdb/rollup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
)

func TestCanStoreAndRetrieveRollup(t *testing.T) {
db, err := createSQLiteDB(t)
db, err := CreateSQLiteDB(t)
if err != nil {
t.Fatalf("unable to initialise test db: %s", err)
}
Expand Down Expand Up @@ -53,7 +53,7 @@ func TestCanStoreAndRetrieveRollup(t *testing.T) {
}

func TestGetRollupByBlockHash(t *testing.T) {
db, err := createSQLiteDB(t)
db, err := CreateSQLiteDB(t)
if err != nil {
t.Fatalf("unable to initialise test db: %s", err)
}
Expand Down Expand Up @@ -83,7 +83,7 @@ func TestGetRollupByBlockHash(t *testing.T) {
}

func TestGetLatestRollup(t *testing.T) {
db, err := createSQLiteDB(t)
db, err := CreateSQLiteDB(t)
if err != nil {
t.Fatalf("unable to initialise test db: %s", err)
}
Expand Down Expand Up @@ -128,7 +128,7 @@ func TestGetLatestRollup(t *testing.T) {
}

func TestGetRollupBySeqNo(t *testing.T) {
db, err := createSQLiteDB(t)
db, err := CreateSQLiteDB(t)
if err != nil {
t.Fatalf("unable to initialise test db: %s", err)
}
Expand Down Expand Up @@ -183,7 +183,7 @@ func TestGetRollupBySeqNo(t *testing.T) {
}

func TestGetRollupListing(t *testing.T) {
db, err := createSQLiteDB(t)
db, err := CreateSQLiteDB(t)
if err != nil {
t.Fatalf("unable to initialise test db: %s", err)
}
Expand Down Expand Up @@ -286,7 +286,7 @@ func TestGetRollupListing(t *testing.T) {
}

func TestGetRollupByHash(t *testing.T) {
db, err := createSQLiteDB(t)
db, err := CreateSQLiteDB(t)
if err != nil {
t.Fatalf("unable to initialise test db: %s", err)
}
Expand Down Expand Up @@ -333,9 +333,9 @@ func TestGetRollupByHash(t *testing.T) {
}

func TestGetRollupBatches(t *testing.T) {
db, _ := createSQLiteDB(t)
db, _ := CreateSQLiteDB(t)
txHashesOne := []common.L2TxHash{gethcommon.BytesToHash([]byte("magicStringOne")), gethcommon.BytesToHash([]byte("magicStringTwo"))}
batchOne := createBatch(batchNumber, txHashesOne)
batchOne := CreateBatch(batchNumber, txHashesOne)
block := types.NewBlock(&types.Header{}, nil, nil, nil)
dbtx, _ := db.NewDBTransaction()
err := AddBlock(dbtx.Tx, db.GetSQLStatement(), block.Header())
Expand All @@ -350,23 +350,23 @@ func TestGetRollupBatches(t *testing.T) {
}

txHashesTwo := []gethcommon.Hash{gethcommon.BytesToHash([]byte("magicStringThree")), gethcommon.BytesToHash([]byte("magicStringFour"))}
batchTwo := createBatch(batchNumber+1, txHashesTwo)
batchTwo := CreateBatch(batchNumber+1, txHashesTwo)

err = AddBatch(dbtx, db.GetSQLStatement(), &batchTwo)
if err != nil {
t.Errorf("could not store batch. Cause: %s", err)
}

txHashesThree := []gethcommon.Hash{gethcommon.BytesToHash([]byte("magicStringFive")), gethcommon.BytesToHash([]byte("magicStringSix"))}
batchThree := createBatch(batchNumber+2, txHashesThree)
batchThree := CreateBatch(batchNumber+2, txHashesThree)

err = AddBatch(dbtx, db.GetSQLStatement(), &batchThree)
if err != nil {
t.Errorf("could not store batch. Cause: %s", err)
}

txHashesFour := []gethcommon.Hash{gethcommon.BytesToHash([]byte("magicStringSeven")), gethcommon.BytesToHash([]byte("magicStringEight"))}
batchFour := createBatch(batchNumber+3, txHashesFour)
batchFour := CreateBatch(batchNumber+3, txHashesFour)

err = AddBatch(dbtx, db.GetSQLStatement(), &batchFour)
if err != nil {
Expand Down
Loading
Loading