github.com/status-im/status-go@v1.1.0/services/wallet/blockchainstate/blockchainstate.go (about) 1 package blockchainstate 2 3 import ( 4 "context" 5 "sync" 6 "time" 7 8 "github.com/status-im/status-go/services/wallet/common" 9 ) 10 11 type LatestBlockData struct { 12 blockNumber uint64 13 timestamp time.Time 14 blockDuration time.Duration 15 } 16 17 type BlockChainState struct { 18 blkMu sync.RWMutex 19 latestBlockNumbers map[uint64]LatestBlockData 20 sinceFn func(time.Time) time.Duration 21 } 22 23 func NewBlockChainState() *BlockChainState { 24 return &BlockChainState{ 25 blkMu: sync.RWMutex{}, 26 latestBlockNumbers: make(map[uint64]LatestBlockData), 27 sinceFn: time.Since, 28 } 29 } 30 31 func (s *BlockChainState) GetEstimatedLatestBlockNumber(ctx context.Context, chainID uint64) (uint64, error) { 32 blockNumber, _ := s.estimateLatestBlockNumber(chainID) 33 return blockNumber, nil 34 } 35 36 func (s *BlockChainState) SetLastBlockNumber(chainID uint64, blockNumber uint64) { 37 blockDuration, found := common.AverageBlockDurationForChain[common.ChainID(chainID)] 38 if !found { 39 blockDuration = common.AverageBlockDurationForChain[common.ChainID(common.UnknownChainID)] 40 } 41 s.setLatestBlockDataForChain(chainID, LatestBlockData{ 42 blockNumber: blockNumber, 43 timestamp: time.Now(), 44 blockDuration: blockDuration, 45 }) 46 } 47 48 func (s *BlockChainState) setLatestBlockDataForChain(chainID uint64, latestBlockData LatestBlockData) { 49 s.blkMu.Lock() 50 defer s.blkMu.Unlock() 51 s.latestBlockNumbers[chainID] = latestBlockData 52 } 53 54 func (s *BlockChainState) estimateLatestBlockNumber(chainID uint64) (uint64, bool) { 55 s.blkMu.RLock() 56 defer s.blkMu.RUnlock() 57 blockData, ok := s.latestBlockNumbers[chainID] 58 if !ok { 59 return 0, false 60 } 61 timeDiff := s.sinceFn(blockData.timestamp) 62 return blockData.blockNumber + uint64((timeDiff / blockData.blockDuration)), true 63 }