"sync"
"time"
- "github.com/bytom/blockchain/txdb"
- "github.com/bytom/blockchain/txdb/storage"
+ "github.com/bytom/consensus"
+ "github.com/bytom/database"
+ "github.com/bytom/database/storage"
"github.com/bytom/errors"
"github.com/bytom/protocol/bc"
- "github.com/bytom/protocol/bc/legacy"
+ "github.com/bytom/protocol/bc/types"
"github.com/bytom/protocol/state"
)
ErrTheDistantFuture = errors.New("block height too far in future")
)
-// Store provides storage for blockchain data: blocks and state tree
-// snapshots.
-//
-// Note, this is different from a state snapshot. A state snapshot
-// provides access to the state at a given point in time -- outputs
-// and issuance memory. The Chain type uses Store to load state
-// from storage and persist validated data.
-type Store interface {
- BlockExist(*bc.Hash) bool
-
- GetBlock(*bc.Hash) (*legacy.Block, error)
- GetMainchain(*bc.Hash) (map[uint64]*bc.Hash, error)
- GetStoreStatus() txdb.BlockStoreStateJSON
- GetTransactionsUtxo(*state.UtxoViewpoint, []*bc.Tx) error
- GetUtxo(*bc.Hash) (*storage.UtxoEntry, error)
-
- SaveBlock(*legacy.Block) error
- SaveChainStatus(*legacy.Block, *state.UtxoViewpoint, map[uint64]*bc.Hash) error
-}
-
// OrphanManage is use to handle all the orphan block
type OrphanManage struct {
//TODO: add orphan cached block limit
- orphan map[bc.Hash]*legacy.Block
+ orphan map[bc.Hash]*types.Block
preOrphans map[bc.Hash][]*bc.Hash
mtx sync.RWMutex
}
// NewOrphanManage return a new orphan block
func NewOrphanManage() *OrphanManage {
return &OrphanManage{
- orphan: make(map[bc.Hash]*legacy.Block),
+ orphan: make(map[bc.Hash]*types.Block),
preOrphans: make(map[bc.Hash][]*bc.Hash),
}
}
}
// Add will add the block to OrphanManage
-func (o *OrphanManage) Add(block *legacy.Block) {
+func (o *OrphanManage) Add(block *types.Block) {
blockHash := block.Hash()
o.mtx.Lock()
defer o.mtx.Unlock()
}
// Get return the orphan block by hash
-func (o *OrphanManage) Get(hash *bc.Hash) (*legacy.Block, bool) {
+func (o *OrphanManage) Get(hash *bc.Hash) (*types.Block, bool) {
o.mtx.RLock()
block, ok := o.orphan[*hash]
o.mtx.RUnlock()
state struct {
cond sync.Cond
- block *legacy.Block
+ block *types.Block
hash *bc.Hash
mainChain map[uint64]*bc.Hash
}
- store Store
+ store database.Store
}
// NewChain returns a new Chain using store as the underlying storage.
-func NewChain(initialBlockHash bc.Hash, store Store, txPool *TxPool) (*Chain, error) {
+func NewChain(initialBlockHash bc.Hash, store database.Store, txPool *TxPool) (*Chain, error) {
c := &Chain{
InitialBlockHash: initialBlockHash,
orphanManage: NewOrphanManage(),
return c.state.hash
}
-func (c *Chain) inMainchain(block *legacy.Block) bool {
+func (c *Chain) inMainchain(block *types.Block) bool {
hash, ok := c.state.mainChain[block.Height]
if !ok {
return false
return *h == hash
}
-// TimestampMS returns the latest known block timestamp.
+// Timestamp returns the latest known block timestamp.
func (c *Chain) Timestamp() uint64 {
c.state.cond.L.Lock()
defer c.state.cond.L.Unlock()
}
// BestBlock returns the chain tail block
-func (c *Chain) BestBlock() *legacy.Block {
+func (c *Chain) BestBlock() *types.Block {
c.state.cond.L.Lock()
defer c.state.cond.L.Unlock()
return c.state.block
return c.store.GetUtxo(hash)
}
+// GetSeed return the seed for the given block
+func (c *Chain) GetSeed(height uint64, preBlock *bc.Hash) (*bc.Hash, error) {
+ if height == 0 {
+ return consensus.InitialSeed, nil
+ } else if height%consensus.SeedPerRetarget == 0 {
+ return preBlock, nil
+ }
+ return c.store.GetSeed(preBlock)
+}
+
+// GetTransactionStatus return the transaction status of give block
+func (c *Chain) GetTransactionStatus(hash *bc.Hash) (*bc.TransactionStatus, error) {
+ return c.store.GetTransactionStatus(hash)
+}
+
// GetTransactionsUtxo return all the utxos that related to the txs' inputs
func (c *Chain) GetTransactionsUtxo(view *state.UtxoViewpoint, txs []*bc.Tx) error {
return c.store.GetTransactionsUtxo(view, txs)
}
// This function must be called with mu lock in above level
-func (c *Chain) setState(block *legacy.Block, view *state.UtxoViewpoint, m map[uint64]*bc.Hash) error {
+func (c *Chain) setState(block *types.Block, view *state.UtxoViewpoint, m map[uint64]*bc.Hash) error {
blockHash := block.Hash()
c.state.block = block
c.state.hash = &blockHash