github.com/elastos/Elastos.ELA.SideChain.ETH@v0.2.2/chainbridge-core/blockstore/blockstore.go (about) 1 // Copyright 2021 ChainSafe Systems 2 // SPDX-License-Identifier: LGPL-3.0-only 3 4 package blockstore 5 6 import ( 7 "bytes" 8 "errors" 9 "fmt" 10 "math/big" 11 12 "github.com/elastos/Elastos.ELA.SideChain.ESC/chainbridge-core/config" 13 "github.com/syndtr/goleveldb/leveldb" 14 ) 15 16 type KeyValueReaderWriter interface { 17 KeyValueReader 18 KeyValueWriter 19 } 20 21 type KeyValueReader interface { 22 GetByKey(key []byte) ([]byte, error) 23 } 24 25 type KeyValueWriter interface { 26 SetByKey(key []byte, value []byte) error 27 } 28 29 var ( 30 ErrNotFound = errors.New("key not found") 31 ) 32 33 func StoreBlock(db KeyValueWriter, block *big.Int, chainID uint64) error { 34 key := bytes.Buffer{} 35 keyS := fmt.Sprintf("chain:%s:block", string(chainID)) 36 key.WriteString(keyS) 37 err := db.SetByKey(key.Bytes(), block.Bytes()) 38 if err != nil { 39 return err 40 } 41 return nil 42 } 43 44 func GetLastStoredBlock(db KeyValueReader, chainID uint64) (*big.Int, error) { 45 key := bytes.Buffer{} 46 keyS := fmt.Sprintf("chain:%s:block", string(chainID)) 47 key.WriteString(keyS) 48 v, err := db.GetByKey(key.Bytes()) 49 if err != nil { 50 if errors.Is(err, leveldb.ErrNotFound) { 51 return big.NewInt(0), nil 52 } 53 return nil, err 54 } 55 block := big.NewInt(0).SetBytes(v) 56 return block, nil 57 } 58 59 // SetupBlockstore queries the blockstore for the latest known block. If the latest block is 60 // greater than config.StartBlock, then config.StartBlock is replaced with the latest known block. 61 func SetupBlockstore(generalConfig *config.GeneralChainConfig, kvdb KeyValueReaderWriter, startBlock *big.Int) (*big.Int, error) { 62 latestBlock, err := GetLastStoredBlock(kvdb, generalConfig.Id) 63 if err != nil { 64 return nil, err 65 } 66 67 if !generalConfig.FreshStart { 68 if latestBlock.Cmp(startBlock) == 1 { 69 return latestBlock, nil 70 } else { 71 return startBlock, nil 72 } 73 } 74 return startBlock, nil 75 }