You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
3.3KB

  1. package main
  2. import log "github.com/sirupsen/logrus"
  3. //import "io/ioutil"
  4. import "fmt"
  5. import "strconv"
  6. //steem block fetcher
  7. const appPrefix = "sbf"
  8. type SteemDataStorer interface {
  9. SetCurrentNetworkBlockHeight(BlockNumber) error
  10. SetCurrentLocalBlockHeight(BlockNumber) error
  11. UpdateCurrentLocalBlockHeight()
  12. CurrentLocalBlockHeight() BlockNumber
  13. CurrentNetworkBlockHeight() BlockNumber
  14. HaveOpsForBlock(BlockNumber) bool
  15. StoreBlockOps(BlockNumber, *[]byte) error
  16. }
  17. // SteemDataStore is the object with which the rest of this tool interacts
  18. type SteemDataStore struct {
  19. kv KVStorer
  20. }
  21. func NewSteemDataStore(hostname string) SteemDataStorer {
  22. self := new(SteemDataStore)
  23. self.kv = NewRedisKVStore(hostname)
  24. self.init()
  25. return self
  26. }
  27. func (self *SteemDataStore) init() {
  28. self.UpdateCurrentLocalBlockHeight()
  29. }
  30. func (self *SteemDataStore) UpdateCurrentLocalBlockHeight() {
  31. cur := self.CurrentLocalBlockHeight()
  32. next := self.FindHighestContiguousBlockInDb(cur)
  33. if next != cur {
  34. err := self.SetCurrentLocalBlockHeight(next)
  35. log.Infof("current highest contig block in db is now %d", next)
  36. if err != nil {
  37. log.Panic(err)
  38. }
  39. return
  40. }
  41. }
  42. func (self *SteemDataStore) SetCurrentLocalBlockHeight(blockNum BlockNumber) error {
  43. keyname := fmt.Sprintf("%s.meta.CurrentLocalBlockHeight", appPrefix)
  44. value := fmt.Sprintf("%d", blockNum)
  45. return self.kv.Put(&keyname, &value)
  46. }
  47. func (self *SteemDataStore) SetCurrentNetworkBlockHeight(blockNum BlockNumber) error {
  48. keyname := fmt.Sprintf("%s.meta.CurrentNetworkBlockHeight", appPrefix)
  49. value := fmt.Sprintf("%d", blockNum)
  50. return self.kv.Put(&keyname, &value)
  51. }
  52. func (self *SteemDataStore) FindHighestContiguousBlockInDb(from BlockNumber) BlockNumber {
  53. last := from
  54. var keyname string
  55. var try BlockNumber
  56. for {
  57. try = BlockNumber(uint64(last) + 1)
  58. keyname = fmt.Sprintf("%s.ops_in_block.%d", appPrefix, try)
  59. exists, err := self.kv.Exists(&keyname)
  60. if err != nil {
  61. log.Panic(err)
  62. }
  63. if exists == false {
  64. log.Debugf("cannot find block %d in db, highest found is %d", try, last)
  65. return last
  66. } else {
  67. last = try
  68. }
  69. }
  70. }
  71. func (self *SteemDataStore) StoreBlockOps(blockNum BlockNumber, blockOps *[]byte) error {
  72. keyname := fmt.Sprintf("%s.ops_in_block.%d", appPrefix, blockNum)
  73. value := string(*blockOps)
  74. return self.kv.Put(&keyname, &value)
  75. }
  76. func (self *SteemDataStore) HaveOpsForBlock(blockNum BlockNumber) bool {
  77. keyname := fmt.Sprintf("%s.ops_in_block.%d", appPrefix, blockNum)
  78. exists, _ := self.kv.Exists(&keyname)
  79. return exists
  80. }
  81. func (self *SteemDataStore) CurrentNetworkBlockHeight() BlockNumber {
  82. keyname := fmt.Sprintf("%s.meta.CurrentNetworkBlockHeight", appPrefix)
  83. val, err := self.kv.Get(&keyname)
  84. if err != nil {
  85. // assume this is key not found, initialize key to default
  86. self.SetCurrentNetworkBlockHeight(0)
  87. // retry
  88. return self.CurrentNetworkBlockHeight()
  89. }
  90. intval, err := strconv.ParseUint(*val, 10, 64)
  91. return BlockNumber(intval)
  92. }
  93. func (self *SteemDataStore) CurrentLocalBlockHeight() BlockNumber {
  94. keyname := fmt.Sprintf("%s.meta.CurrentLocalBlockHeight", appPrefix)
  95. val, err := self.kv.Get(&keyname)
  96. if err != nil {
  97. // assume this is key not found, initialize key to default
  98. self.SetCurrentLocalBlockHeight(0)
  99. // retry
  100. return self.CurrentLocalBlockHeight()
  101. }
  102. intval, err := strconv.ParseUint(*val, 10, 64)
  103. return BlockNumber(intval)
  104. }