|
- package main
-
- import log "github.com/sirupsen/logrus"
-
- //import "io/ioutil"
- import "fmt"
- import "strconv"
-
- //steem block fetcher
- const appPrefix = "sbf"
-
- type SteemDataStorer interface {
- SetCurrentNetworkBlockHeight(BlockNumber) error
- SetCurrentLocalBlockHeight(BlockNumber) error
- UpdateCurrentLocalBlockHeight()
- CurrentLocalBlockHeight() BlockNumber
- CurrentNetworkBlockHeight() BlockNumber
- HaveOpsForBlock(BlockNumber) bool
- StoreBlockOps(BlockNumber, *[]byte) error
- }
-
- // SteemDataStore is the object with which the rest of this tool interacts
- type SteemDataStore struct {
- kv KVStorer
- }
-
- func NewSteemDataStore(hostname string) SteemDataStorer {
- self := new(SteemDataStore)
- self.kv = NewRedisKVStore(hostname)
- self.init()
- return self
- }
-
- func (self *SteemDataStore) init() {
- self.UpdateCurrentLocalBlockHeight()
- }
-
- func (self *SteemDataStore) UpdateCurrentLocalBlockHeight() {
- cur := self.CurrentLocalBlockHeight()
- next := self.FindHighestContiguousBlockInDb(cur)
- if next != cur {
- err := self.SetCurrentLocalBlockHeight(next)
- log.Infof("current highest contig block in db is now %d", next)
- if err != nil {
- log.Panic(err)
- }
- return
- }
- }
-
- func (self *SteemDataStore) SetCurrentLocalBlockHeight(blockNum BlockNumber) error {
- keyname := fmt.Sprintf("%s.meta.CurrentLocalBlockHeight", appPrefix)
- value := fmt.Sprintf("%d", blockNum)
- return self.kv.Put(&keyname, &value)
- }
-
- func (self *SteemDataStore) SetCurrentNetworkBlockHeight(blockNum BlockNumber) error {
- keyname := fmt.Sprintf("%s.meta.CurrentNetworkBlockHeight", appPrefix)
- value := fmt.Sprintf("%d", blockNum)
- return self.kv.Put(&keyname, &value)
- }
-
- func (self *SteemDataStore) FindHighestContiguousBlockInDb(from BlockNumber) BlockNumber {
- last := from
-
- var keyname string
- var try BlockNumber
-
- for {
- try = BlockNumber(uint64(last) + 1)
- keyname = fmt.Sprintf("%s.ops_in_block.%d", appPrefix, try)
- exists, err := self.kv.Exists(&keyname)
- if err != nil {
- log.Panic(err)
- }
- if exists == false {
- log.Debugf("cannot find block %d in db, highest found is %d", try, last)
- return last
- } else {
- last = try
- }
- }
- }
-
- func (self *SteemDataStore) StoreBlockOps(blockNum BlockNumber, blockOps *[]byte) error {
- keyname := fmt.Sprintf("%s.ops_in_block.%d", appPrefix, blockNum)
- value := string(*blockOps)
- return self.kv.Put(&keyname, &value)
- }
-
- func (self *SteemDataStore) HaveOpsForBlock(blockNum BlockNumber) bool {
- keyname := fmt.Sprintf("%s.ops_in_block.%d", appPrefix, blockNum)
- exists, _ := self.kv.Exists(&keyname)
- return exists
- }
-
- func (self *SteemDataStore) CurrentNetworkBlockHeight() BlockNumber {
- keyname := fmt.Sprintf("%s.meta.CurrentNetworkBlockHeight", appPrefix)
- val, err := self.kv.Get(&keyname)
- if err != nil {
- // assume this is key not found, initialize key to default
- self.SetCurrentNetworkBlockHeight(0)
- // retry
- return self.CurrentNetworkBlockHeight()
- }
- intval, err := strconv.ParseUint(*val, 10, 64)
- return BlockNumber(intval)
- }
-
- func (self *SteemDataStore) CurrentLocalBlockHeight() BlockNumber {
- keyname := fmt.Sprintf("%s.meta.CurrentLocalBlockHeight", appPrefix)
- val, err := self.kv.Get(&keyname)
- if err != nil {
- // assume this is key not found, initialize key to default
- self.SetCurrentLocalBlockHeight(0)
- // retry
- return self.CurrentLocalBlockHeight()
- }
- intval, err := strconv.ParseUint(*val, 10, 64)
- return BlockNumber(intval)
- }
|