Skip to content

Commit 1a3a63d

Browse files
author
Abdul Rabbani
committed
Find Gaps and at them to known_gaps
This contains all the logic needed to add a gap to the `known_gaps` table. We can now add this code to various parts of the application to calculate if a gap has occured.
1 parent ce66532 commit 1a3a63d

File tree

6 files changed

+144
-44
lines changed

6 files changed

+144
-44
lines changed

statediff/indexer/database/dump/indexer.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -497,10 +497,6 @@ func (sdi *StateDiffIndexer) Close() error {
497497
return sdi.dump.Close()
498498
}
499499

500-
func (sdi *StateDiffIndexer) PushKnownGaps(startingBlockNumber *big.Int, endingBlockNumber *big.Int, checkedOut bool, processingKey int64) error {
500+
func (sdi *StateDiffIndexer) FindAndUpdateGaps(latestBlockOnChain *big.Int, expectedDifference *big.Int, processingKey int64) error {
501501
return nil
502502
}
503-
504-
func (sdi *StateDiffIndexer) QueryDb(queryString string) (string, error) {
505-
return "", nil
506-
}

statediff/indexer/database/file/indexer.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -479,10 +479,6 @@ func (sdi *StateDiffIndexer) Close() error {
479479
return sdi.fileWriter.Close()
480480
}
481481

482-
func (sdi *StateDiffIndexer) PushKnownGaps(startingBlockNumber *big.Int, endingBlockNumber *big.Int, checkedOut bool, processingKey int64) error {
482+
func (sdi *StateDiffIndexer) FindAndUpdateGaps(latestBlockOnChain *big.Int, expectedDifference *big.Int, processingKey int64) error {
483483
return nil
484484
}
485-
486-
func (sdi *StateDiffIndexer) QueryDb(queryString string) (string, error) {
487-
return "", nil
488-
}

statediff/indexer/database/sql/indexer.go

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,7 @@ func (sdi *StateDiffIndexer) Close() error {
555555
}
556556

557557
// Update the known gaps table with the gap information.
558-
func (sdi *StateDiffIndexer) PushKnownGaps(startingBlockNumber *big.Int, endingBlockNumber *big.Int, checkedOut bool, processingKey int64) error {
558+
func (sdi *StateDiffIndexer) pushKnownGaps(startingBlockNumber *big.Int, endingBlockNumber *big.Int, checkedOut bool, processingKey int64) error {
559559
knownGap := models.KnownGapsModel{
560560
StartingBlockNumber: startingBlockNumber.String(),
561561
EndingBlockNumber: endingBlockNumber.String(),
@@ -570,13 +570,64 @@ func (sdi *StateDiffIndexer) PushKnownGaps(startingBlockNumber *big.Int, endingB
570570

571571
// This is a simple wrapper function which will run QueryRow on the DB
572572
func (sdi *StateDiffIndexer) QueryDb(queryString string) (string, error) {
573-
var name string
574-
err := sdi.dbWriter.db.QueryRow(context.Background(), queryString).Scan(&name)
575-
// err := sdi.dbWriter.db.QueryRow(context.Background(), "SELECT ename FROM emp ORDER BY sal DESC LIMIT 1;").Scan(&name)
573+
var ret string
574+
err := sdi.dbWriter.db.QueryRow(context.Background(), queryString).Scan(&ret)
576575
if err != nil {
576+
log.Error("Can't properly query the DB for query: ", queryString)
577577
return "", err
578578
}
579-
fmt.Println(name)
579+
return ret, nil
580+
}
581+
582+
// This function is a simple wrapper which will call QueryDb but the return value will be
583+
// a big int instead of a string
584+
func (sdi *StateDiffIndexer) QueryDbToBigInt(queryString string) (*big.Int, error) {
585+
ret := new(big.Int)
586+
res, err := sdi.QueryDb(queryString)
587+
if err != nil {
588+
return ret, err
589+
}
590+
ret, ok := ret.SetString(res, 10)
591+
if !ok {
592+
log.Error("Can't turn the res ", res, "into a bigInt")
593+
return ret, fmt.Errorf("Can't turn %s into a bigInt", res)
594+
}
595+
return ret, nil
596+
}
580597

581-
return name, nil
598+
// Users provide the latestBlockInDb and the latestBlockOnChain
599+
// as well as the expected difference. This function does some simple math.
600+
// The expected difference for the time being is going to be 1, but as we run
601+
// More geth nodes, the expected difference might fluctuate.
602+
func isGap(latestBlockInDb *big.Int, latestBlockOnChain *big.Int, expectedDifference *big.Int) bool {
603+
latestBlock := big.NewInt(0)
604+
if latestBlock.Add(latestBlockOnChain, expectedDifference) != latestBlockInDb {
605+
return true
606+
}
607+
return false
608+
609+
}
610+
611+
// This function will check for Gaps and update the DB if gaps are found.
612+
// The processingKey will currently be set to 0, but as we start to leverage horizontal scaling
613+
// It might be a useful parameter to update depending on the geth node.
614+
func (sdi *StateDiffIndexer) FindAndUpdateGaps(latestBlockOnChain *big.Int, expectedDifference *big.Int, processingKey int64) error {
615+
dbQueryString := "SELECT MAX(block_number) FROM eth.header_cids"
616+
latestBlockInDb, err := sdi.QueryDbToBigInt(dbQueryString)
617+
if err != nil {
618+
return err
619+
}
620+
621+
gapExists := isGap(latestBlockInDb, latestBlockOnChain, expectedDifference)
622+
if gapExists {
623+
startBlock := big.NewInt(0)
624+
endBlock := big.NewInt(0)
625+
startBlock.Add(latestBlockInDb, expectedDifference)
626+
endBlock.Sub(latestBlockOnChain, expectedDifference)
627+
628+
log.Warn("Found Gaps starting at, ", startBlock, " and ending at, ", endBlock)
629+
sdi.pushKnownGaps(startBlock, endBlock, false, processingKey)
630+
}
631+
632+
return nil
582633
}

statediff/indexer/database/sql/indexer_shared_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package sql_test
22

33
import (
44
"bytes"
5+
"context"
56
"fmt"
7+
"math/big"
68
"os"
79
"testing"
810

@@ -11,8 +13,10 @@ import (
1113
"github.com/stretchr/testify/require"
1214

1315
"github.com/ethereum/go-ethereum/core/types"
16+
"github.com/ethereum/go-ethereum/params"
1417
"github.com/ethereum/go-ethereum/rlp"
1518
"github.com/ethereum/go-ethereum/statediff/indexer/database/sql"
19+
"github.com/ethereum/go-ethereum/statediff/indexer/database/sql/postgres"
1620
"github.com/ethereum/go-ethereum/statediff/indexer/interfaces"
1721
"github.com/ethereum/go-ethereum/statediff/indexer/ipld"
1822
"github.com/ethereum/go-ethereum/statediff/indexer/mocks"
@@ -22,6 +26,7 @@ var (
2226
db sql.Database
2327
err error
2428
ind interfaces.StateDiffIndexer
29+
chainConf = params.MainnetChainConfig
2530
ipfsPgGet = `SELECT data FROM public.blocks
2631
WHERE key = $1`
2732
tx1, tx2, tx3, tx4, tx5, rct1, rct2, rct3, rct4, rct5 []byte
@@ -148,8 +153,60 @@ func checkTxClosure(t *testing.T, idle, inUse, open int64) {
148153
require.Equal(t, open, db.Stats().Open())
149154
}
150155

156+
func setupDb(t *testing.T) (*sql.StateDiffIndexer, error) {
157+
db, err = postgres.SetupSQLXDB()
158+
if err != nil {
159+
t.Fatal(err)
160+
}
161+
stateDiff, err := sql.NewStateDiffIndexer(context.Background(), chainConf, db)
162+
return stateDiff, err
163+
}
164+
151165
func tearDown(t *testing.T) {
152166
sql.TearDownDB(t, db)
153167
err := ind.Close()
154168
require.NoError(t, err)
155169
}
170+
func TestKnownGapsUpsert(t *testing.T) {
171+
testKnownGapsUpsert(t)
172+
173+
}
174+
func testKnownGapsUpsert(t *testing.T) {
175+
gapDifference := big.NewInt(10) // Set a difference between latestBlock in DB and on Chain
176+
expectedDifference := big.NewInt(1) // Set what the expected difference between latestBlock in DB and on Chain should be
177+
178+
stateDiff, err := setupDb(t)
179+
if err != nil {
180+
t.Fatal(err)
181+
}
182+
183+
// Get the latest block from the DB
184+
latestBlockInDb, err := stateDiff.QueryDbToBigInt("SELECT MAX(block_number) FROM eth.header_cids")
185+
if err != nil {
186+
t.Fatal("Can't find a block in the eth.header_cids table.. Please put one there")
187+
}
188+
189+
// Add the gapDifference for testing purposes
190+
latestBlockOnChain := big.NewInt(0)
191+
latestBlockOnChain.Add(latestBlockInDb, gapDifference)
192+
193+
t.Log("The latest block on the chain is: ", latestBlockOnChain)
194+
t.Log("The latest block on the DB is: ", latestBlockInDb)
195+
196+
gapUpsertErr := stateDiff.FindAndUpdateGaps(latestBlockOnChain, expectedDifference, 0)
197+
require.NoError(t, gapUpsertErr)
198+
199+
// Calculate what the start and end block should be in known_gaps
200+
// And check to make sure it is properly inserted
201+
startBlock := big.NewInt(0)
202+
endBlock := big.NewInt(0)
203+
startBlock.Add(latestBlockInDb, expectedDifference)
204+
endBlock.Sub(latestBlockOnChain, expectedDifference)
205+
206+
queryString := fmt.Sprintf("SELECT starting_block_number from eth.known_gaps WHERE starting_block_number = %d AND ending_block_number = %d", startBlock, endBlock)
207+
208+
_, queryErr := stateDiff.QueryDb(queryString) // Figure out the string.
209+
t.Logf("Updated Known Gaps table starting from, %d, and ending at, %d", startBlock, endBlock)
210+
require.NoError(t, queryErr)
211+
212+
}

statediff/indexer/database/sql/mainnet_tests/indexer_test.go

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -117,29 +117,30 @@ func tearDown(t *testing.T) {
117117
require.NoError(t, err)
118118
}
119119

120-
func TestKnownGapsUpsert(t *testing.T) {
121-
var startBlockNumber int64 = 111
122-
var endBlockNumber int64 = 121
123-
ind, err := setupDb(t)
124-
if err != nil {
125-
t.Fatal(err)
126-
}
127-
require.NoError(t, err)
128-
129-
testKnownGapsUpsert(t, startBlockNumber, endBlockNumber, ind)
130-
//str, err := ind.QueryDb("SELECT MAX(block_number) FROM eth.header_cids") // Figure out the string.
131-
queryString := fmt.Sprintf("SELECT starting_block_number from eth.known_gaps WHERE starting_block_number = %d AND ending_block_number = %d", startBlockNumber, endBlockNumber)
132-
_, queryErr := ind.QueryDb(queryString) // Figure out the string.
133-
require.NoError(t, queryErr)
134-
135-
}
136-
func testKnownGapsUpsert(t *testing.T, startBlockNumber int64, endBlockNumber int64, ind interfaces.StateDiffIndexer) {
137-
startBlock := big.NewInt(startBlockNumber)
138-
endBlock := big.NewInt(endBlockNumber)
139-
140-
processGapError := ind.PushKnownGaps(startBlock, endBlock, false, 1)
141-
if processGapError != nil {
142-
t.Fatal(processGapError)
143-
}
144-
require.NoError(t, processGapError)
145-
}
120+
//func TestKnownGapsUpsert(t *testing.T) {
121+
// var startBlockNumber int64 = 111
122+
// var endBlockNumber int64 = 121
123+
// ind, err := setupDb(t)
124+
// if err != nil {
125+
// t.Fatal(err)
126+
// }
127+
// require.NoError(t, err)
128+
//
129+
// testKnownGapsUpsert(t, startBlockNumber, endBlockNumber, ind)
130+
// //str, err := ind.QueryDb("SELECT MAX(block_number) FROM eth.header_cids") // Figure out the string.
131+
// queryString := fmt.Sprintf("SELECT starting_block_number from eth.known_gaps WHERE starting_block_number = %d AND ending_block_number = %d", startBlockNumber, endBlockNumber)
132+
// _, queryErr := ind.QueryDb(queryString) // Figure out the string.
133+
// require.NoError(t, queryErr)
134+
//
135+
//}
136+
//func testKnownGapsUpsert(t *testing.T, startBlockNumber int64, endBlockNumber int64, ind interfaces.StateDiffIndexer) {
137+
// startBlock := big.NewInt(startBlockNumber)
138+
// endBlock := big.NewInt(endBlockNumber)
139+
//
140+
// processGapError := ind.PushKnownGaps(startBlock, endBlock, false, 1)
141+
// if processGapError != nil {
142+
// t.Fatal(processGapError)
143+
// }
144+
// require.NoError(t, processGapError)
145+
//}
146+
//

statediff/indexer/interfaces/interfaces.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ type StateDiffIndexer interface {
3232
PushStateNode(tx Batch, stateNode sdtypes.StateNode, headerID string) error
3333
PushCodeAndCodeHash(tx Batch, codeAndCodeHash sdtypes.CodeAndCodeHash) error
3434
ReportDBMetrics(delay time.Duration, quit <-chan bool)
35-
PushKnownGaps(startingBlockNumber *big.Int, endingBlockNumber *big.Int, checkedOut bool, processingKey int64) error
36-
QueryDb(queryString string) (string, error)
35+
FindAndUpdateGaps(latestBlockOnChain *big.Int, expectedDifference *big.Int, processingKey int64) error
3736
io.Closer
3837
}
3938

0 commit comments

Comments
 (0)