Skip to content

Commit 5435243

Browse files
committed
feat: improved dnr sync logic
Signed-off-by: Soumya Ghosh Dastidar <[email protected]>
1 parent 456f680 commit 5435243

File tree

4 files changed

+131
-7
lines changed

4 files changed

+131
-7
lines changed

cmd/geth/dbcmd.go

+81
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ Remove blockchain and state databases`,
6161
Category: "DATABASE COMMANDS",
6262
Subcommands: []cli.Command{
6363
dbInspectCmd,
64+
dbDeleteDNR,
65+
dbGetDNR,
6466
dbStatCmd,
6567
dbCompactCmd,
6668
dbGetCmd,
@@ -85,6 +87,25 @@ Remove blockchain and state databases`,
8587
Usage: "Inspect the storage size for each type of data in the database",
8688
Description: `This commands iterates the entire database. If the optional 'prefix' and 'start' arguments are provided, then the iteration is limited to the given subset of data.`,
8789
}
90+
dbDeleteDNR = cli.Command{
91+
Action: utils.MigrateFlags(deleteDNRData),
92+
Name: "delete-dnr",
93+
ArgsUsage: "<epoch (optional)>",
94+
Flags: utils.GroupFlags([]cli.Flag{
95+
utils.SyncModeFlag,
96+
}, utils.NetworkFlags, utils.DatabasePathFlags),
97+
Usage: "Deletes all dnr entries from db",
98+
Description: `This commands iterates the entire database and deletes all dnr entries`,
99+
}
100+
dbGetDNR = cli.Command{
101+
Action: utils.MigrateFlags(getDNRKeys),
102+
Name: "get-dnr-data",
103+
Flags: utils.GroupFlags([]cli.Flag{
104+
utils.SyncModeFlag,
105+
}, utils.NetworkFlags, utils.DatabasePathFlags),
106+
Usage: "Deletes all dnr entries from db",
107+
Description: `This commands iterates the entire database and deletes all dnr entries`,
108+
}
88109
dbCheckStateContentCmd = cli.Command{
89110
Action: utils.MigrateFlags(checkStateContent),
90111
Name: "check-state-content",
@@ -301,6 +322,66 @@ func inspect(ctx *cli.Context) error {
301322
return rawdb.InspectDatabase(db, prefix, start)
302323
}
303324

325+
func deleteDNRData(ctx *cli.Context) error {
326+
var (
327+
epoch []byte
328+
)
329+
if ctx.NArg() > 1 {
330+
return fmt.Errorf("Max 1 arguments: %v", ctx.Command.ArgsUsage)
331+
}
332+
if ctx.NArg() >= 1 {
333+
if d, err := hexutil.Decode(ctx.Args().Get(0)); err != nil {
334+
return fmt.Errorf("failed to hex-decode 'prefix': %v", err)
335+
} else {
336+
epoch = d
337+
}
338+
}
339+
stack, _ := makeConfigNode(ctx)
340+
defer stack.Close()
341+
342+
db := utils.MakeChainDatabase(ctx, stack, false)
343+
defer db.Close()
344+
345+
if epoch != nil {
346+
key := "dnr-" + string(epoch)
347+
if err := db.Delete([]byte(key)); err != nil {
348+
log.Error("failed to delete dnr key", "key", string(key))
349+
return err
350+
}
351+
} else {
352+
iter := db.NewIterator([]byte("dnr-"), nil)
353+
for iter.Next() {
354+
key := iter.Key()
355+
log.Info("deleting dnr key ", "key", string(key))
356+
if err := db.Delete(key); err != nil {
357+
log.Error("failed to delete dnr key", "key", string(key))
358+
return err
359+
}
360+
}
361+
}
362+
log.Info("deleted dnr data")
363+
return nil
364+
}
365+
366+
func getDNRKeys(ctx *cli.Context) error {
367+
if ctx.NArg() > 0 {
368+
return fmt.Errorf("No arguments: %v", ctx.Command.ArgsUsage)
369+
}
370+
stack, _ := makeConfigNode(ctx)
371+
defer stack.Close()
372+
373+
db := utils.MakeChainDatabase(ctx, stack, true)
374+
defer db.Close()
375+
376+
iter := db.NewIterator([]byte("dnr-"), nil)
377+
for iter.Next() {
378+
key := iter.Key()
379+
log.Info("dnr key ", "key", string(key))
380+
}
381+
382+
return nil
383+
}
384+
304385
func checkStateContent(ctx *cli.Context) error {
305386
var (
306387
prefix []byte

consensus/clique/clique.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ func (c *Clique) snapshot(chain consensus.ChainHeaderReader, number uint64, hash
382382
// If an on-disk checkpoint snapshot can be found, use that
383383
if epoch {
384384
if s, err := loadSnapshot(c.config, c.signatures, c.db, number); err == nil {
385-
log.Warn("Loaded voting snapshot from disk", "block", number, "hash", hash, "snap", snap)
385+
log.Warn("Loaded voting snapshot from disk", "block", number, "hash", hash, "snap", s)
386386
snap = s
387387
break
388388
} else {
@@ -642,7 +642,7 @@ func (c *Clique) Seal(chain consensus.ChainHeaderReader, block *types.Block, res
642642
log.Warn("failed to update snapshot", "error", err)
643643
return
644644
}
645-
log.Info("epoch stored", "header_no,", header.Number.Uint64(), "hash", header.Hash())
645+
log.Info("epoch stored", "header_no", header.Number.Uint64(), "hash", header.Hash())
646646
}
647647
default:
648648
log.Warn("Sealing result is not read by miner", "sealhash", SealHash(header))

consensus/clique/ren.go

+39-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"encoding/json"
66
"fmt"
77
"math/big"
8+
"os"
9+
"strconv"
810
"sync"
911
"time"
1012

@@ -17,7 +19,7 @@ import (
1719
"github.com/ethereum/go-ethereum/common"
1820
)
1921

20-
const BlockBuffer = 100
22+
const SyncBlockBuffer = 100
2123
const LogSubnetUpdated = "0x203322e912486658ef4fc95d5da32dcbed12f5fceac274c0b6618c5874bb892f"
2224
const LogNewEpoch = "0xaf2fc4796f2932ce294c3684deffe5098d3ef65dc2dd64efa80ef94eed88b01e"
2325

@@ -53,6 +55,15 @@ func NewDNR(config *params.CliqueConfig, db ethdb.Database) *DNR {
5355
}
5456

5557
func (d *DNR) Watch(ctx context.Context, db ethdb.Database) {
58+
syncWait := int64(30)
59+
syncPeriodEnv := os.Getenv("SYNC_WAIT_PERIOD")
60+
if syncPeriodEnv != "" {
61+
if tempPeriod, err := strconv.ParseInt(syncPeriodEnv, 10, 64); err == nil {
62+
log.Info("custom dnr sync period", "period", syncPeriodEnv)
63+
syncWait = tempPeriod
64+
}
65+
}
66+
5667
d.syncLock.Lock()
5768
d.synced = false
5869
d.syncLock.Unlock()
@@ -63,6 +74,12 @@ func (d *DNR) Watch(ctx context.Context, db ethdb.Database) {
6374
}
6475
lastBlock := d.LastEpochBlock
6576

77+
lastSyncedBlock, err := GetLastSyncedBlock(db)
78+
79+
if err == nil && lastBlock < lastSyncedBlock {
80+
lastBlock = lastSyncedBlock
81+
}
82+
6683
log.Warn("starting watch...", "existing_validators", d.Validators, "last_epoch", d.LastEpochBlock, "dnr_addr", d.config.DNR)
6784

6885
for {
@@ -144,7 +161,15 @@ func (d *DNR) Watch(ctx context.Context, db ethdb.Database) {
144161

145162
lastBlock = lastBlockNumber.Uint64()
146163

147-
time.Sleep(time.Second * 30)
164+
if (lastBlock - lastSyncedBlock) >= 2*SyncBlockBuffer {
165+
if err := StoreLastSyncedBlock(db, lastBlock-SyncBlockBuffer); err != nil {
166+
log.Warn("failed to store last synced dnr block", "new_block", lastBlock, "synced_to", lastSyncedBlock)
167+
} else {
168+
lastSyncedBlock = lastBlock - SyncBlockBuffer
169+
}
170+
}
171+
172+
time.Sleep(time.Second * time.Duration(syncWait))
148173
}
149174
}
150175

@@ -197,3 +222,15 @@ func GetDNR(db ethdb.Database, epoch uint64) (*DNR, error) {
197222
}
198223
return &dnr, nil
199224
}
225+
226+
func StoreLastSyncedBlock(db ethdb.Database, block uint64) error {
227+
return db.Put([]byte("dnr-last-sync"), new(big.Int).SetUint64(block).Bytes())
228+
}
229+
230+
func GetLastSyncedBlock(db ethdb.Database) (uint64, error) {
231+
blob, err := db.Get([]byte("dnr-last-sync"))
232+
if err != nil {
233+
return 0, err
234+
}
235+
return new(big.Int).SetBytes(blob).Uint64(), nil
236+
}

consensus/clique/snapshot.go

+9-3
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,14 @@ import (
2020
"bytes"
2121
"encoding/json"
2222
"fmt"
23+
"sort"
24+
2325
"github.com/ethereum/go-ethereum/common"
2426
"github.com/ethereum/go-ethereum/core/types"
2527
"github.com/ethereum/go-ethereum/ethdb"
2628
"github.com/ethereum/go-ethereum/log"
2729
"github.com/ethereum/go-ethereum/params"
2830
lru "github.com/hashicorp/golang-lru"
29-
"sort"
3031
)
3132

3233
// Vote represents a single vote that an authorized signer made to modify the
@@ -173,10 +174,15 @@ func (s *Snapshot) signers() []common.Address {
173174
// inturn returns if a signer at a given block height is in-turn or not.
174175
func (s *Snapshot) inturn(number uint64, signer common.Address) bool {
175176
signers, offset := s.signers(), 0
176-
for offset < len(signers) && signers[offset] != signer {
177+
signerCount := len(signers)
178+
if signerCount == 0 {
179+
log.Warn("no signers in the validator list, blocks cannot be produced")
180+
return false
181+
}
182+
for offset < signerCount && signers[offset] != signer {
177183
offset++
178184
}
179-
return (number % uint64(len(signers))) == uint64(offset)
185+
return (number % uint64(signerCount)) == uint64(offset)
180186
}
181187

182188
// signers retrieves the list of authorized signers in ascending order.

0 commit comments

Comments
 (0)