Skip to content

Commit

Permalink
Merge pull request #136 from dogecoinfoundation/rc-wait-initial-sync
Browse files Browse the repository at this point in the history
Wait for Initial Block Download in core
  • Loading branch information
tjstebbing authored Sep 24, 2024
2 parents f8056b0 + 030ae63 commit 67e263b
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 4 deletions.
29 changes: 25 additions & 4 deletions pkg/chaintracker/chainfollower.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ import (
)

const (
RETRY_DELAY = 5 * time.Second // for RPC and Database errors.
WRONG_CHAIN_DELAY = 5 * time.Minute // for "Wrong Chain" error (essentially stop)
CONFLICT_DELAY = 250 * time.Millisecond // for Database conflicts (concurrent transactions)
BLOCKS_PER_COMMIT = 10 // number of blocks per database commit.
RETRY_DELAY = 5 * time.Second // for RPC and Database errors.
WRONG_CHAIN_DELAY = 5 * time.Minute // for "Wrong Chain" error (essentially stop)
WAIT_INITIAL_BLOCK = 30 * time.Second // for Initial Block Download
CONFLICT_DELAY = 250 * time.Millisecond // for Database conflicts (concurrent transactions)
BLOCKS_PER_COMMIT = 10 // number of blocks per database commit.
)

type ChainFollower struct {
Expand Down Expand Up @@ -154,6 +155,14 @@ func (c *ChainFollower) fetchStartingPos() ChainPos {
continue
}
c.chain = chain
// Wait for Core to be fully synced, otherwise fetchBlockCount will give
// us an early block and we'll follow the whole chain.
info := c.fetchBlockchainInfo()
if info.InitialBlockDownload {
log.Println("ChainFollower: waiting for Core initial block download")
c.sleepForRetry(nil, WAIT_INITIAL_BLOCK)
continue
}
if state.BestBlockHash != "" {
// Resume sync.
// Make sure we're syncing the same blockchain as before.
Expand Down Expand Up @@ -688,6 +697,18 @@ func (c *ChainFollower) fetchBlockHash(height int64) string {
}
}

func (c *ChainFollower) fetchBlockchainInfo() giga.RpcBlockchainInfo {
for {
info, err := c.l1.GetBlockchainInfo()
if err != nil {
log.Println("ChainFollower: error retrieving blockchain info (will retry):", err)
c.sleepForRetry(err, 0)
} else {
return info
}
}
}

func (c *ChainFollower) fetchBlockCount() int64 {
for {
count, err := c.l1.GetBlockCount()
Expand Down
9 changes: 9 additions & 0 deletions pkg/core/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ func (l *L1CoreRPC) request(method string, params []any, result any) error {
if err != nil {
return fmt.Errorf("json-rpc read response: %v", err)
}
// check for error response
if res.StatusCode != 200 {
return fmt.Errorf("json-rpc error status: %v", res.StatusCode)
}
// cannot use json.NewDecoder: "The decoder introduces its own buffering
// and may read data from r beyond the JSON values requested."
var rpcres rpcResponse
Expand Down Expand Up @@ -149,6 +153,11 @@ func (l *L1CoreRPC) GetBlockCount() (blockCount int64, err error) {
return
}

func (l *L1CoreRPC) GetBlockchainInfo() (info giga.RpcBlockchainInfo, err error) {
err = l.request("getblockchaininfo", []any{}, &info)
return
}

func (l *L1CoreRPC) GetTransaction(txnHash string) (txn giga.RawTxn, err error) {
decode := true // to get back JSON rather than HEX
err = l.request("getrawtransaction", []any{txnHash, decode}, &txn)
Expand Down
20 changes: 20 additions & 0 deletions pkg/dogecoin.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type L1 interface {
GetBlockHash(height int64) (string, error)
GetBestBlockHash() (string, error)
GetBlockCount() (int64, error)
GetBlockchainInfo() (RpcBlockchainInfo, error)
GetTransaction(txnHash string) (RawTxn, error)
Send(txnHex string) (txid string, err error)
EstimateFee(confirmTarget int) (feePerKB CoinAmount, err error)
Expand Down Expand Up @@ -171,3 +172,22 @@ type RpcBlockHeader struct {
PreviousBlockHash string `json:"previousblockhash"` // (string) The hash of the previous block (hex)
NextBlockHash string `json:"nextblockhash"` // (string) The hash of the next block (hex)
}

// RpcBlockchainInfo from Core
type RpcBlockchainInfo struct {
Chain string `json:"chain"` // (string) current network name (main, test, regtest)
Blocks int64 `json:"blocks"` // (numeric) the height of the most-work fully-validated chain. The genesis block has height 0
Headers int64 `json:"headers"` // (numeric) the current number of headers we have validated
BestBlockHash string `json:"bestblockhash"` // (string) the hash of the currently best block
Difficulty float64 `json:"difficulty"` // (numeric) the current difficulty
MedianTime int64 `json:"mediantime"` // (numeric) median time for the current best block
VerificationProgress float64 `json:"verificationprogress"` // (numeric) estimate of verification progress [0..1]
InitialBlockDownload bool `json:"initialblockdownload"` // (boolean) (debug information) estimate of whether this node is in Initial Block Download mode
ChainWord string `json:"chainwork"` // (string) total amount of work in active chain, in hexadecimal
SizeOnDisk int64 `json:"size_on_disk"` // (numeric) the estimated size of the block and undo files on disk
Pruned bool `json:"pruned"` // (boolean) if the blocks are subject to pruning
PruneHeight int64 `json:"pruneheight"` // (numeric) lowest-height complete block stored (only present if pruning is enabled)
AutomaticPruning bool `json:"automatic_pruning"` // (boolean) whether automatic pruning is enabled (only present if pruning is enabled)
PruneTargetSize int64 `json:"prune_target_size"` // (numeric) the target size used by pruning (only present if automatic pruning is enabled)

}
7 changes: 7 additions & 0 deletions pkg/dogecoin/libdogecoin.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,13 @@ func (l L1Libdogecoin) GetBlockCount() (blockCount int64, err error) {
return 0, fmt.Errorf("not implemented")
}

func (l L1Libdogecoin) GetBlockchainInfo() (info giga.RpcBlockchainInfo, err error) {
if l.fallback != nil {
return l.fallback.GetBlockchainInfo()
}
return giga.RpcBlockchainInfo{}, fmt.Errorf("not implemented")
}

func (l L1Libdogecoin) GetTransaction(txnHash string) (txn giga.RawTxn, err error) {
if l.fallback != nil {
return l.fallback.GetTransaction(txnHash)
Expand Down
4 changes: 4 additions & 0 deletions pkg/dogecoin/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ func (l L1Mock) GetBlockCount() (blockCount int64, err error) {
return 100, nil
}

func (l L1Mock) GetBlockchainInfo() (info giga.RpcBlockchainInfo, err error) {
return giga.RpcBlockchainInfo{}, fmt.Errorf("not implemented")
}

func (l L1Mock) GetTransaction(txnHash string) (txn giga.RawTxn, err error) {
return giga.RawTxn{}, nil
}
Expand Down

0 comments on commit 67e263b

Please sign in to comment.