Read sapling activation height from RPC
This commit is contained in:
parent
b2389b6c12
commit
7bf4a8407b
|
@ -8,13 +8,13 @@ import (
|
|||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/adityapk00/btcd/rpcclient"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/adityapk00/lightwalletd/frontend"
|
||||
|
@ -26,6 +26,7 @@ var log *logrus.Entry
|
|||
var logger = logrus.New()
|
||||
var db *sql.DB
|
||||
|
||||
// Options is a struct holding command line options
|
||||
type Options struct {
|
||||
dbPath string
|
||||
logLevel uint64
|
||||
|
@ -115,26 +116,35 @@ func main() {
|
|||
if err != nil {
|
||||
log.WithFields(logrus.Fields{
|
||||
"error": err,
|
||||
}).Warn("unable to get current height from local db storage")
|
||||
|
||||
}).Warn("Unable to get current height from local db storage. This is OK if you're starting this for the first time.")
|
||||
}
|
||||
|
||||
// Get the sapling activation height from the RPC
|
||||
saplingHeight, err := getSaplingActivationHeight(rpcClient)
|
||||
if err != nil {
|
||||
log.WithFields(logrus.Fields{
|
||||
"error": err,
|
||||
}).Warn("Unable to get sapling activation height")
|
||||
}
|
||||
|
||||
log.WithField("saplingHeight", saplingHeight).Info("Got sapling height ", saplingHeight)
|
||||
|
||||
//ingest from Sapling testnet height
|
||||
if height < 280000 {
|
||||
height = 280000
|
||||
if height < saplingHeight {
|
||||
height = saplingHeight
|
||||
log.WithFields(logrus.Fields{
|
||||
"error": err,
|
||||
}).Warn("invalid current height read from local db storage")
|
||||
}
|
||||
|
||||
timeout_count := 0
|
||||
reorg_count := -1
|
||||
timeoutCount := 0
|
||||
reorgCount := -1
|
||||
hash := ""
|
||||
phash := ""
|
||||
// Start listening for new blocks
|
||||
for {
|
||||
if reorg_count > 0 {
|
||||
reorg_count = -1
|
||||
if reorgCount > 0 {
|
||||
reorgCount = -1
|
||||
height -= 10
|
||||
}
|
||||
block, err := getBlock(rpcClient, height)
|
||||
|
@ -144,35 +154,35 @@ func main() {
|
|||
"height": height,
|
||||
"error": err,
|
||||
}).Warn("error with getblock")
|
||||
timeout_count++
|
||||
if timeout_count == 3 {
|
||||
timeoutCount++
|
||||
if timeoutCount == 3 {
|
||||
log.WithFields(logrus.Fields{
|
||||
"timeouts": timeout_count,
|
||||
"timeouts": timeoutCount,
|
||||
}).Warn("unable to issue RPC call to zcashd node 3 times")
|
||||
break
|
||||
}
|
||||
}
|
||||
if block != nil {
|
||||
handleBlock(db, block)
|
||||
if timeout_count > 0 {
|
||||
timeout_count--
|
||||
if timeoutCount > 0 {
|
||||
timeoutCount--
|
||||
}
|
||||
phash = hex.EncodeToString(block.GetPrevHash())
|
||||
//check for reorgs once we have inital block hash from startup
|
||||
if hash != phash && reorg_count != -1 {
|
||||
reorg_count++
|
||||
if hash != phash && reorgCount != -1 {
|
||||
reorgCount++
|
||||
log.WithFields(logrus.Fields{
|
||||
"height": height,
|
||||
"hash": hash,
|
||||
"phash": phash,
|
||||
"reorg": reorg_count,
|
||||
"reorg": reorgCount,
|
||||
}).Warn("REORG")
|
||||
} else {
|
||||
hash = hex.EncodeToString(block.GetDisplayHash())
|
||||
}
|
||||
if reorg_count == -1 {
|
||||
if reorgCount == -1 {
|
||||
hash = hex.EncodeToString(block.GetDisplayHash())
|
||||
reorg_count =0
|
||||
reorgCount = 0
|
||||
}
|
||||
height++
|
||||
} else {
|
||||
|
@ -182,6 +192,36 @@ func main() {
|
|||
}
|
||||
}
|
||||
|
||||
func getSaplingActivationHeight(rpcClient *rpcclient.Client) (int, error) {
|
||||
result, rpcErr := rpcClient.RawRequest("getblockchaininfo", make([]json.RawMessage, 0))
|
||||
|
||||
var err error
|
||||
var errCode int64
|
||||
|
||||
// For some reason, the error responses are not JSON
|
||||
if rpcErr != nil {
|
||||
errParts := strings.SplitN(rpcErr.Error(), ":", 2)
|
||||
errCode, err = strconv.ParseInt(errParts[0], 10, 32)
|
||||
//Check to see if we are requesting a height the zcashd doesn't have yet
|
||||
if err == nil && errCode == -8 {
|
||||
return -1, nil
|
||||
}
|
||||
return -1, errors.Wrap(rpcErr, "error requesting block")
|
||||
}
|
||||
|
||||
var f interface{}
|
||||
err = json.Unmarshal(result, &f)
|
||||
if err != nil {
|
||||
return -1, errors.Wrap(err, "error reading JSON response")
|
||||
}
|
||||
|
||||
upgradeJSON := f.(map[string]interface{})["upgrades"]
|
||||
saplingJSON := upgradeJSON.(map[string]interface{})["76b809bb"] // Sapling ID
|
||||
saplingHeight := saplingJSON.(map[string]interface{})["activationheight"].(float64)
|
||||
|
||||
return int(saplingHeight), nil
|
||||
}
|
||||
|
||||
func getBlock(rpcClient *rpcclient.Client, height int) (*parser.Block, error) {
|
||||
params := make([]json.RawMessage, 2)
|
||||
params[0] = json.RawMessage("\"" + strconv.Itoa(height) + "\"")
|
||||
|
@ -204,7 +244,7 @@ func getBlock(rpcClient *rpcclient.Client, height int) (*parser.Block, error) {
|
|||
|
||||
var blockDataHex string
|
||||
err = json.Unmarshal(result, &blockDataHex)
|
||||
if err != nil{
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error reading JSON response")
|
||||
}
|
||||
|
||||
|
@ -224,7 +264,6 @@ func getBlock(rpcClient *rpcclient.Client, height int) (*parser.Block, error) {
|
|||
return block, nil
|
||||
}
|
||||
|
||||
|
||||
func handleBlock(db *sql.DB, block *parser.Block) {
|
||||
prevBlockHash := hex.EncodeToString(block.GetPrevHash())
|
||||
blockHash := hex.EncodeToString(block.GetEncodableHash())
|
||||
|
|
|
@ -58,7 +58,7 @@ func CreateTables(conn *sql.DB) error {
|
|||
// TODO consider max/count queries instead of state table. bit of a coupling assumption though.
|
||||
|
||||
func GetCurrentHeight(ctx context.Context, db *sql.DB) (int, error) {
|
||||
var height int
|
||||
var height int = -1
|
||||
query := "SELECT current_height FROM state WHERE rowid = 1"
|
||||
err := db.QueryRowContext(ctx, query).Scan(&height)
|
||||
return height, err
|
||||
|
|
Loading…
Reference in New Issue