OSDN Git Service

update master (#487)
[bytom/bytom.git] / protocol / protocol.go
index f6d607f..38f405d 100755 (executable)
@@ -5,11 +5,12 @@ import (
        "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"
 )
 
@@ -22,30 +23,10 @@ var (
        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
 }
@@ -53,7 +34,7 @@ type OrphanManage struct {
 // 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),
        }
 }
@@ -67,7 +48,7 @@ func (o *OrphanManage) BlockExist(hash *bc.Hash) bool {
 }
 
 // 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()
@@ -105,7 +86,7 @@ func (o *OrphanManage) Delete(hash *bc.Hash) {
 }
 
 // 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()
@@ -125,15 +106,15 @@ type Chain struct {
 
        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(),
@@ -176,7 +157,7 @@ func (c *Chain) BestBlockHash() *bc.Hash {
        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
@@ -196,7 +177,7 @@ func (c *Chain) InMainChain(height uint64, hash bc.Hash) bool {
        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()
@@ -207,7 +188,7 @@ func (c *Chain) Timestamp() uint64 {
 }
 
 // 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
@@ -218,13 +199,28 @@ func (c *Chain) GetUtxo(hash *bc.Hash) (*storage.UtxoEntry, error) {
        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