Skip to content

Commit

Permalink
e2pg: backfill task use separate pg lock
Browse files Browse the repository at this point in the history
Add the backfill bit to the task's lock id.
  • Loading branch information
ryandotsmith committed Nov 6, 2023
1 parent 6aac935 commit 2d84c53
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 1 deletion.
17 changes: 16 additions & 1 deletion e2pg/e2pg.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,21 @@ func (t *Task) initRows(n uint64, h []byte) error {
return nil
}

// lockid accepts a uint64 because, per eip155, a chain id can
// be: floor(MAX_UINT64 / 2) - 36. Since pg_advisory_xact_lock
// requires a 32 bit id, and since we are using a bit to indicate
// wheather a task is backfill or not, we simply panic for large chain
// ids. If this ever becomes a problem we can find another solution.
func lockid(x uint64, backfill bool) uint32 {
if x > ((1 << 31) - 1) {
panic("lockid input too big")
}
if backfill {
return uint32((x << 1) | 1)
}
return uint32((x << 1) &^ 1)
}

var (
ErrNothingNew = errors.New("no new blocks")
ErrReorg = errors.New("reorg")
Expand Down Expand Up @@ -286,7 +301,7 @@ func (task *Task) Converge(notx bool) error {
pg = wpg.NewTxLocker(pgTx)
//crc32(task) == 1384045349
const lockq = `select pg_advisory_xact_lock(1384045349, $1)`
_, err = pg.Exec(task.ctx, lockq, task.chainID)
_, err = pg.Exec(task.ctx, lockq, lockid(task.chainID, task.backfill))
if err != nil {
return fmt.Errorf("task lock %d: %w", task.chainID, err)
}
Expand Down
17 changes: 17 additions & 0 deletions e2pg/e2pg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -756,3 +756,20 @@ func TestValidateChain(t *testing.T) {
diff.Test(t, t.Errorf, tc.want, validateChain(tc.parent, tc.blks))
}
}

func TestLockID(t *testing.T) {
cases := []struct {
chid uint64
backfill bool
want uint32
}{
{1, true, 0b00000000000000000000000000000011},
{1, false, 0b00000000000000000000000000000010},
{1024, true, 0b00000000000000000000100000000001},
{1024, false, 0b00000000000000000000100000000000},
}
for _, tc := range cases {
got := lockid(tc.chid, tc.backfill)
diff.Test(t, t.Errorf, tc.want, got)
}
}

0 comments on commit 2d84c53

Please sign in to comment.