Skip to content

Commit

Permalink
Lock state.block table when performing non-atomic read/write
Browse files Browse the repository at this point in the history
This should prevent the duplicate key errors we have seen in
production from the preconfirmations node, which runs two
simultaneous tasks that both update the blocks table.
  • Loading branch information
jbearer committed Oct 9, 2023
1 parent db400e3 commit 1db2c87
Showing 1 changed file with 9 additions and 0 deletions.
9 changes: 9 additions & 0 deletions state/pgstatestorage.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,15 @@ func (p *PostgresStorage) ResetTrustedState(ctx context.Context, batchNum uint64
// AddBlock adds a new block to the State Store
func (p *PostgresStorage) AddBlock(ctx context.Context, block *Block, dbTx pgx.Tx) error {
e := p.getExecQuerier(dbTx)

// This operation will both read the state.block table (to check if the block we're adding
// already exists) and modify it. These two actions do not happen atomically; without
// protection, another transaction may complete and modify the state.block table in between.
// Thus, we first need to acquire a lock that prevents concurrent updates to the table.
if _, err := e.Exec(ctx, "LOCK TABLE state.block IN EXCLUSIVE MODE"); err != nil {
return err
}

_, err := e.Exec(ctx, addBlockSQL, block.BlockNumber, block.BlockHash.String(), block.ParentHash.String(), block.ReceivedAt)
return err
}
Expand Down

0 comments on commit 1db2c87

Please sign in to comment.