OSDN Git Service

merge with master baby
authorpaladz <453256728@qq.com>
Thu, 21 Sep 2017 06:59:02 +0000 (14:59 +0800)
committerpaladz <453256728@qq.com>
Thu, 21 Sep 2017 06:59:02 +0000 (14:59 +0800)
23 files changed:
blockchain/pool.go
blockchain/reactor.go
consensus/general.go [new file with mode: 0644]
consensus/general_test.go [moved from protocol/bc/blockheader_test.go with 55% similarity]
mining/README.md [deleted file]
mining/cpuminer/README.md [deleted file]
mining/cpuminer/cpuminer.go [changed mode: 0755->0644]
mining/cpuminer/log.go [deleted file]
mining/log.go [deleted file]
mining/mining.go [changed mode: 0755->0644]
mining/policy.go [deleted file]
node/node.go
protocol/bc/blockheader.go
protocol/block.go
protocol/mempool.go [moved from blockchain/mempool.go with 88% similarity]
protocol/mempool_test.go [moved from blockchain/mempool_test.go with 79% similarity]
protocol/validation/validation.go
rpc/chainhash/chainhash.go [deleted file]
rpc/chainhash/hashfunc.go [deleted file]
rpc/core/difficulty.go [deleted file]
rpc/core/generate.go [deleted file]
rpc/wire/blockheader.go [deleted file]
rpc/wire/difficulty.go [deleted file]

index 8f85c95..3537cb8 100644 (file)
@@ -5,8 +5,8 @@ import (
        "sync"
        "time"
 
-//     "github.com/blockchain/types"
-    "github.com/bytom/protocol/bc/legacy"
+       //      "github.com/blockchain/types"
+       "github.com/bytom/protocol/bc/legacy"
        . "github.com/tendermint/tmlibs/common"
        flow "github.com/tendermint/tmlibs/flowrate"
        "github.com/tendermint/tmlibs/log"
@@ -40,8 +40,8 @@ type BlockPool struct {
        mtx sync.Mutex
        // block requests
        requesters map[uint64]*bpRequester
-       height     uint64   // the lowest key in requesters.
-       numPending int32 // number of requests pending assignment or block response
+       height     uint64 // the lowest key in requesters.
+       numPending int32  // number of requests pending assignment or block response
        // peers
        peers map[string]*bpPeer
 
@@ -133,7 +133,7 @@ func (pool *BlockPool) IsCaughtUp() bool {
        height := pool.height
 
        // Need at least 1 peer to be considered caught up.
-       if len(pool.peers) == 0 {
+       if len(pool.peers) == 0 && time.Now().Sub(pool.startTime) > 60*time.Second {
                pool.Logger.Debug("Blockpool has no peers")
                return false
        }
@@ -309,8 +309,8 @@ func (pool *BlockPool) debug() string {
        defer pool.mtx.Unlock()
 
        str := ""
-    var h uint64
-       for h = pool.height; h < pool.height+ uint64(len(pool.requesters)); h++ {
+       var h uint64
+       for h = pool.height; h < pool.height+uint64(len(pool.requesters)); h++ {
                if pool.requesters[h] == nil {
                        str += Fmt("H(%v):X ", h)
                } else {
index a47ddca..fd27b1b 100644 (file)
@@ -3,31 +3,30 @@ package blockchain
 import (
        "bytes"
        "context"
-       "reflect"
-    "time"
-       "net/http"
        "fmt"
+       "net/http"
+       "reflect"
+       "time"
 
-       wire "github.com/tendermint/go-wire"
-       "github.com/bytom/p2p"
-       "github.com/bytom/types"
-    "github.com/bytom/protocol/bc/legacy"
-    "github.com/bytom/protocol"
-       "github.com/bytom/blockchain/query"
-       "github.com/bytom/encoding/json"
-       cmn "github.com/tendermint/tmlibs/common"
-       "github.com/bytom/blockchain/txdb"
        "github.com/bytom/blockchain/account"
        "github.com/bytom/blockchain/asset"
+       "github.com/bytom/blockchain/txbuilder"
+       "github.com/bytom/blockchain/txdb"
        "github.com/bytom/blockchain/txfeed"
+       "github.com/bytom/encoding/json"
+       "github.com/bytom/errors"
+       "github.com/bytom/generated/dashboard"
        "github.com/bytom/log"
-       //"github.com/bytom/net/http/gzip"
+       "github.com/bytom/mining/cpuminer"
        "github.com/bytom/net/http/httpjson"
-       //"github.com/bytom/net/http/limit"
        "github.com/bytom/net/http/static"
-       "github.com/bytom/generated/dashboard"
-       "github.com/bytom/errors"
-       "github.com/bytom/blockchain/txbuilder"
+       "github.com/bytom/p2p"
+       "github.com/bytom/protocol"
+       "github.com/bytom/protocol/bc/legacy"
+       "github.com/bytom/protocol/validation"
+       "github.com/bytom/types"
+       wire "github.com/tendermint/go-wire"
+       cmn "github.com/tendermint/tmlibs/common"
 )
 
 const (
@@ -46,26 +45,27 @@ const (
        // check if we should switch to consensus reactor
        switchToConsensusIntervalSeconds = 1
        maxBlockchainResponseSize        = 22020096 + 2
-       crosscoreRPCPrefix = "/rpc/"
+       crosscoreRPCPrefix               = "/rpc/"
 )
 
 // BlockchainReactor handles long-term catchup syncing.
 type BlockchainReactor struct {
        p2p.BaseReactor
 
-       chain        *protocol.Chain
-       store        *txdb.Store
-       accounts         *account.Manager
-       assets       *asset.Registry
-       txFeeds          *txfeed.TxFeed
-       indexer         *query.Indexer
-       pool         *BlockPool
-       mux          *http.ServeMux
-       handler      http.Handler
-       fastSync     bool
-       requestsCh   chan BlockRequest
-       timeoutsCh   chan string
-       submitter    txbuilder.Submitter
+       chain      *protocol.Chain
+       store      *txdb.Store
+       accounts   *account.Manager
+       assets     *asset.Registry
+       txFeeds    *txfeed.TxFeed
+       pool       *BlockPool
+       txPool     *protocol.TxPool
+       mining     *cpuminer.CPUMiner
+       mux        *http.ServeMux
+       handler    http.Handler
+       fastSync   bool
+       requestsCh chan BlockRequest
+       timeoutsCh chan string
+       submitter  txbuilder.Submitter
 
        evsw types.EventSwitch
 }
@@ -94,7 +94,7 @@ func batchRecover(ctx context.Context, v *interface{}) {
 }
 
 func jsonHandler(f interface{}) http.Handler {
-    h, err := httpjson.Handler(f, errorFormatter.Write)
+       h, err := httpjson.Handler(f, errorFormatter.Write)
        if err != nil {
                panic(err)
        }
@@ -106,12 +106,12 @@ func alwaysError(err error) http.Handler {
 }
 
 func (bcr *BlockchainReactor) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
-    bcr.handler.ServeHTTP(rw, req)
+       bcr.handler.ServeHTTP(rw, req)
 }
 
 func (bcr *BlockchainReactor) info(ctx context.Context) (map[string]interface{}, error) {
-    //if a.config == nil {
-               // never configured
+       //if a.config == nil {
+       // never configured
        log.Printf(ctx, "-------info-----")
        return map[string]interface{}{
                "is_configured": false,
@@ -124,7 +124,7 @@ func (bcr *BlockchainReactor) info(ctx context.Context) (map[string]interface{},
 }
 
 func (bcr *BlockchainReactor) createblockkey(ctx context.Context) {
-       log.Printf(ctx,"creat-block-key")
+       log.Printf(ctx, "creat-block-key")
 }
 
 func webAssetsHandler(next http.Handler) http.Handler {
@@ -138,7 +138,7 @@ func webAssetsHandler(next http.Handler) http.Handler {
 }
 
 func maxBytes(h http.Handler) http.Handler {
-    const maxReqSize = 1e7 // 10MB
+       const maxReqSize = 1e7 // 10MB
        return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
                // A block can easily be bigger than maxReqSize, but everything
                // else should be pretty small.
@@ -153,44 +153,44 @@ func (bcr *BlockchainReactor) BuildHander() {
        m := bcr.mux
        m.Handle("/create-account", jsonHandler(bcr.createAccount))
        m.Handle("/create-asset", jsonHandler(bcr.createAsset))
-       m.Handle("/update-account-tags",jsonHandler(bcr.updateAccountTags))
-       m.Handle("/update-asset-tags",jsonHandler(bcr.updateAssetTags))
+       m.Handle("/update-account-tags", jsonHandler(bcr.updateAccountTags))
+       m.Handle("/update-asset-tags", jsonHandler(bcr.updateAssetTags))
        m.Handle("/build-transaction", jsonHandler(bcr.build))
-       m.Handle("/create-control-program",jsonHandler(bcr.createControlProgram))
+       m.Handle("/create-control-program", jsonHandler(bcr.createControlProgram))
        m.Handle("/create-account-receiver", jsonHandler(bcr.createAccountReceiver))
        m.Handle("/create-transaction-feed", jsonHandler(bcr.createTxFeed))
        m.Handle("/get-transaction-feed", jsonHandler(bcr.getTxFeed))
        m.Handle("/update-transaction-feed", jsonHandler(bcr.updateTxFeed))
        m.Handle("/delete-transaction-feed", jsonHandler(bcr.deleteTxFeed))
        m.Handle("/list-accounts", jsonHandler(bcr.listAccounts))
-        m.Handle("/list-assets", jsonHandler(bcr.listAssets))
-        m.Handle("/list-transaction-feeds", jsonHandler(bcr.listTxFeeds))
-        m.Handle("/list-transactions", jsonHandler(bcr.listTransactions))
-        m.Handle("/list-balances", jsonHandler(bcr.listBalances))
-        m.Handle("/list-unspent-outputs", jsonHandler(bcr.listUnspentOutputs))
+       m.Handle("/list-assets", jsonHandler(bcr.listAssets))
+       m.Handle("/list-transaction-feeds", jsonHandler(bcr.listTxFeeds))
+       m.Handle("/list-transactions", jsonHandler(bcr.listTransactions))
+       m.Handle("/list-balances", jsonHandler(bcr.listBalances))
+       m.Handle("/list-unspent-outputs", jsonHandler(bcr.listUnspentOutputs))
        m.Handle("/", alwaysError(errors.New("not Found")))
        m.Handle("/info", jsonHandler(bcr.info))
        m.Handle("/create-block-key", jsonHandler(bcr.createblockkey))
        m.Handle("/submit-transaction", jsonHandler(bcr.submit))
 
-    latencyHandler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
+       latencyHandler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
                if l := latency(m, req); l != nil {
                        defer l.RecordSince(time.Now())
                }
                m.ServeHTTP(w, req)
-               })
+       })
        handler := maxBytes(latencyHandler) // TODO(tessr): consider moving this to non-core specific mux
        handler = webAssetsHandler(handler)
-/*     handler = healthHandler(handler)
-       for _, l := range a.requestLimits {
-               handler = limit.Handler(handler, alwaysError(errRateLimited), l.perSecond, l.burst, l.key)
-       }
-       handler = gzip.Handler{Handler: handler}
-       handler = coreCounter(handler)
-       handler = timeoutContextHandler(handler)
-       if a.config != nil && a.config.BlockchainId != nil {
-               handler = blockchainIDHandler(handler, a.config.BlockchainId.String())
-       }
+       /*      handler = healthHandler(handler)
+               for _, l := range a.requestLimits {
+                       handler = limit.Handler(handler, alwaysError(errRateLimited), l.perSecond, l.burst, l.key)
+               }
+               handler = gzip.Handler{Handler: handler}
+               handler = coreCounter(handler)
+               handler = timeoutContextHandler(handler)
+               if a.config != nil && a.config.BlockchainId != nil {
+                       handler = blockchainIDHandler(handler, a.config.BlockchainId.String())
+               }
        */
        bcr.handler = handler
 }
@@ -235,40 +235,43 @@ type page struct {
        LastPage bool         `json:"last_page"`
 }
 
-func NewBlockchainReactor(store *txdb.Store, chain *protocol.Chain, accounts *account.Manager, assets *asset.Registry, fastSync bool) *BlockchainReactor {
-    requestsCh    := make(chan BlockRequest, defaultChannelCapacity)
-    timeoutsCh    := make(chan string, defaultChannelCapacity)
-    pool := NewBlockPool(
-        store.Height()+1,
-        requestsCh,
-        timeoutsCh,
-    )
-    bcR := &BlockchainReactor {
-        chain:         chain,
-        store:         store,
-               accounts:      accounts,
-               assets:            assets,
-        pool:          pool,
-               mux:           http.NewServeMux(),
-        fastSync:      fastSync,
-        requestsCh:    requestsCh,
-        timeoutsCh:   timeoutsCh,
-    }
-    bcR.BaseReactor = *p2p.NewBaseReactor("BlockchainReactor", bcR)
-    return bcR
+func NewBlockchainReactor(store *txdb.Store, chain *protocol.Chain, txPool *protocol.TxPool, accounts *account.Manager, assets *asset.Registry, fastSync bool) *BlockchainReactor {
+       requestsCh := make(chan BlockRequest, defaultChannelCapacity)
+       timeoutsCh := make(chan string, defaultChannelCapacity)
+       pool := NewBlockPool(
+               store.Height()+1,
+               requestsCh,
+               timeoutsCh,
+       )
+       mining := cpuminer.NewCPUMiner(chain, txPool)
+       bcR := &BlockchainReactor{
+               chain:      chain,
+               store:      store,
+               accounts:   accounts,
+               assets:     assets,
+               pool:       pool,
+               txPool:     txPool,
+               mining:     mining,
+               mux:        http.NewServeMux(),
+               fastSync:   fastSync,
+               requestsCh: requestsCh,
+               timeoutsCh: timeoutsCh,
+       }
+       bcR.BaseReactor = *p2p.NewBaseReactor("BlockchainReactor", bcR)
+       return bcR
 }
 
 // OnStart implements BaseService
 func (bcR *BlockchainReactor) OnStart() error {
        bcR.BaseReactor.OnStart()
        bcR.BuildHander()
-    if bcR.fastSync {
-        _, err := bcR.pool.Start()
-        if err != nil {
-            return err
-        }
-        go bcR.poolRoutine()
-    }
+       if bcR.fastSync {
+               _, err := bcR.pool.Start()
+               if err != nil {
+                       return err
+               }
+               go bcR.poolRoutine()
+       }
        return nil
 }
 
@@ -290,7 +293,7 @@ func (bcR *BlockchainReactor) GetChannels() []*p2p.ChannelDescriptor {
 
 // AddPeer implements Reactor by sending our state to peer.
 func (bcR *BlockchainReactor) AddPeer(peer *p2p.Peer) {
-       if !peer.Send(BlockchainChannel, struct{ BlockchainMessage }{&bcStatusResponseMessage{bcR.store.Height()}}) {
+       if !peer.Send(BlockchainChannel, struct{ BlockchainMessage }{&bcStatusResponseMessage{bcR.chain.Height()}}) {
                // doing nothing, will try later in `poolRoutine`
        }
 }
@@ -313,34 +316,50 @@ func (bcR *BlockchainReactor) Receive(chID byte, src *p2p.Peer, msgBytes []byte)
        switch msg := msg.(type) {
        case *bcBlockRequestMessage:
                // Got a request for a block. Respond with block if we have it.
-               block, _:= bcR.store.GetBlock(msg.Height)
-               if block != nil {
-                       msg := &bcBlockResponseMessage{Block: block}
+               rawBlock, err := bcR.store.GetRawBlock(msg.Height)
+               //fmt.Printf("sent block %v \n", rawBlock)
+               if err == nil {
+                       msg := &bcBlockResponseMessage{RawBlock: rawBlock}
                        queued := src.TrySend(BlockchainChannel, struct{ BlockchainMessage }{msg})
                        if !queued {
                                // queue is full, just ignore.
                        }
                } else {
+                       fmt.Println("skip sent the block response due to block is nil")
                        // TODO peer is asking for things we don't have.
                }
        case *bcBlockResponseMessage:
                // Got a block.
-               bcR.pool.AddBlock(src.Key, msg.Block, len(msgBytes))
+               //fmt.Printf("receive block %v \n", msg.Block)
+               bcR.pool.AddBlock(src.Key, msg.GetBlock(), len(msgBytes))
        case *bcStatusRequestMessage:
                // Send peer our state.
-               queued := src.TrySend(BlockchainChannel, struct{ BlockchainMessage }{&bcStatusResponseMessage{bcR.store.Height()}})
+               queued := src.TrySend(BlockchainChannel, struct{ BlockchainMessage }{&bcStatusResponseMessage{bcR.chain.Height()}})
                if !queued {
                        // sorry
                }
        case *bcStatusResponseMessage:
                // Got a peer status. Unverified.
+               //fmt.Printf("reveive peer high is %d \n", msg.Height)
                bcR.pool.SetPeerHeight(src.Key, msg.Height)
+       case *bcTransactionMessage:
+               block, _ := bcR.chain.State()
+               tx := msg.GetTransaction()
+               if bcR.txPool.HaveTransaction(&tx.Tx.ID) {
+                       return
+               }
+
+               gas, err := validation.ValidateTx(tx.Tx, legacy.MapBlock(block))
+               if err != nil {
+                       return
+               }
+               bcR.txPool.AddTransaction(tx, tx.TxData.SerializedSize, block.BlockHeader.Height, uint64(gas))
+               go bcR.BroadcastTransaction(tx)
        default:
                bcR.Logger.Error(cmn.Fmt("Unknown message type %v", reflect.TypeOf(msg)))
        }
 }
 
-
 // Handle messages from the poolReactor telling the reactor what to do.
 // NOTE: Don't sleep in the FOR_LOOP or otherwise slow it down!
 // (Except for the SYNC_LOOP, which is the primary purpose and must be synchronous.)
@@ -375,46 +394,70 @@ FOR_LOOP:
                        // ask for status updates
                        go bcR.BroadcastStatusRequest()
                /*case _ = <-switchToConsensusTicker.C:
-                       height, numPending, _ := bcR.pool.GetStatus()
-                       outbound, inbound, _ := bcR.Switch.NumPeers()
-                       bcR.Logger.Info("Consensus ticker", "numPending", numPending, "total", len(bcR.pool.requesters),
-                               "outbound", outbound, "inbound", inbound)
-                       if bcR.pool.IsCaughtUp() {
-                               bcR.Logger.Info("Time to switch to consensus reactor!", "height", height)
-                               bcR.pool.Stop()
-
-                               conR := bcR.Switch.Reactor("CONSENSUS").(consensusReactor)
-                               conR.SwitchToConsensus(bcR.state)
-
-                               break FOR_LOOP
-                       }*/
+               height, numPending, _ := bcR.pool.GetStatus()
+               outbound, inbound, _ := bcR.Switch.NumPeers()
+               bcR.Logger.Info("Consensus ticker", "numPending", numPending, "total", len(bcR.pool.requesters),
+                       "outbound", outbound, "inbound", inbound)
+               if bcR.pool.IsCaughtUp() {
+                       bcR.Logger.Info("Time to switch to consensus reactor!", "height", height)
+                       bcR.pool.Stop()
+
+                       conR := bcR.Switch.Reactor("CONSENSUS").(consensusReactor)
+                       conR.SwitchToConsensus(bcR.state)
+
+                       break FOR_LOOP
+               }*/
                case _ = <-trySyncTicker.C: // chan time
                        // This loop can be slow as long as it's doing syncing work.
                SYNC_LOOP:
                        for i := 0; i < 10; i++ {
                                // See if there are any blocks to sync.
-                               first, second := bcR.pool.PeekTwoBlocks()
-                               bcR.Logger.Info("TrySync peeked", "first", first, "second", second)
-                               if first == nil || second == nil {
-                                       // We need both to sync the first block.
+                               block, _ := bcR.pool.PeekTwoBlocks()
+                               //bcR.Logger.Info("TrySync peeked", "first", first, "second", second)
+                               if block == nil {
+                                       //bcR.Logger.Info("skip sync loop, nothing need to be sync")
+                                       break SYNC_LOOP
+                               }
+
+                               //bcR.Logger.Info("start to sync block", block)
+                               bcR.pool.PopRequest()
+                               snap, err := bcR.chain.ApplyValidBlock(block)
+                               if err != nil {
+                                       fmt.Printf("Failed to apply valid block: %v \n", err)
                                        break SYNC_LOOP
                                }
-                           bcR.pool.PopRequest()
-                bcR.store.SaveBlock(first)
+                               err = bcR.chain.CommitAppliedBlock(nil, block, snap)
+                               if err != nil {
+                                       fmt.Printf("Failed to commit block: %v \n", err)
+                                       break SYNC_LOOP
+                               }
+                               bcR.Logger.Info("finish to sync commit block", block)
                        }
                        continue FOR_LOOP
                case <-bcR.Quit:
                        break FOR_LOOP
                }
+               if bcR.pool.IsCaughtUp() && !bcR.mining.IsMining() {
+                       bcR.Logger.Info("start to mining")
+                       bcR.mining.Start()
+               }
        }
 }
 
 // BroadcastStatusRequest broadcasts `BlockStore` height.
 func (bcR *BlockchainReactor) BroadcastStatusRequest() error {
-       bcR.Switch.Broadcast(BlockchainChannel, struct{ BlockchainMessage }{&bcStatusRequestMessage{bcR.store.Height()}})
+       bcR.Switch.Broadcast(BlockchainChannel, struct{ BlockchainMessage }{&bcStatusRequestMessage{bcR.chain.Height()}})
        return nil
 }
 
+func (bcR *BlockchainReactor) BroadcastTransaction(tx *legacy.Tx) error {
+       rawTx, err := tx.TxData.MarshalText()
+       if err == nil {
+               return err
+       }
+       bcR.Switch.Broadcast(BlockchainChannel, struct{ BlockchainMessage }{&bcTransactionMessage{rawTx}})
+       return nil
+}
 
 /*
 // SetEventSwitch implements events.Eventable
@@ -427,10 +470,11 @@ func (bcR *BlockchainReactor) SetEventSwitch(evsw types.EventSwitch) {
 // Messages
 
 const (
-       msgTypeBlockRequest   = byte(0x10)
-       msgTypeBlockResponse  = byte(0x11)
-       msgTypeStatusResponse = byte(0x20)
-       msgTypeStatusRequest  = byte(0x21)
+       msgTypeBlockRequest       = byte(0x10)
+       msgTypeBlockResponse      = byte(0x11)
+       msgTypeStatusResponse     = byte(0x20)
+       msgTypeStatusRequest      = byte(0x21)
+       msgTypeTransactionRequest = byte(0x30)
 )
 
 // BlockchainMessage is a generic message for this reactor.
@@ -442,6 +486,7 @@ var _ = wire.RegisterInterface(
        wire.ConcreteType{&bcBlockResponseMessage{}, msgTypeBlockResponse},
        wire.ConcreteType{&bcStatusResponseMessage{}, msgTypeStatusResponse},
        wire.ConcreteType{&bcStatusRequestMessage{}, msgTypeStatusRequest},
+       wire.ConcreteType{&bcTransactionMessage{}, msgTypeTransactionRequest},
 )
 
 // DecodeMessage decodes BlockchainMessage.
@@ -469,13 +514,37 @@ func (m *bcBlockRequestMessage) String() string {
 
 //-------------------------------------
 
+type bcTransactionMessage struct {
+       RawTx []byte
+}
+
+func (m *bcTransactionMessage) GetTransaction() *legacy.Tx {
+       tx := &legacy.Tx{}
+       tx.UnmarshalText(m.RawTx)
+       return tx
+}
+
+//-------------------------------------
+
+//-------------------------------------
+
 // NOTE: keep up-to-date with maxBlockchainResponseSize
 type bcBlockResponseMessage struct {
-       Block *legacy.Block
+       RawBlock []byte
+}
+
+func (m *bcBlockResponseMessage) GetBlock() *legacy.Block {
+       block := &legacy.Block{
+               BlockHeader:  legacy.BlockHeader{},
+               Transactions: []*legacy.Tx{},
+       }
+       block.UnmarshalText(m.RawBlock)
+       return block
 }
 
 func (m *bcBlockResponseMessage) String() string {
-       return cmn.Fmt("[bcBlockResponseMessage %v]", m.Block.Height)
+       block := m.GetBlock()
+       return cmn.Fmt("[bcBlockResponseMessage %v]", block.BlockHeader.Height)
 }
 
 //-------------------------------------
diff --git a/consensus/general.go b/consensus/general.go
new file mode 100644 (file)
index 0000000..d21bf85
--- /dev/null
@@ -0,0 +1,101 @@
+package consensus
+
+import (
+       "math/big"
+
+       "github.com/bytom/protocol/bc"
+)
+
+const (
+       subsidyReductionInterval = uint64(560640)
+       baseSubsidy              = uint64(624000000000)
+)
+
+// HashToBig converts a *bc.Hash into a big.Int that can be used to
+// perform math comparisons.
+func HashToBig(hash *bc.Hash) *big.Int {
+       buf := hash.Byte32()
+       blen := len(buf)
+       for i := 0; i < blen/2; i++ {
+               buf[i], buf[blen-1-i] = buf[blen-1-i], buf[i]
+       }
+
+       return new(big.Int).SetBytes(buf[:])
+}
+
+// CompactToBig converts a compact representation of a whole number N to an
+// unsigned 64-bit number.  The representation is similar to IEEE754 floating
+// point numbers.
+//
+//     -------------------------------------------------
+//     |   Exponent     |    Sign    |    Mantissa     |
+//     -------------------------------------------------
+//     | 8 bits [63-56] | 1 bit [55] | 55 bits [54-00] |
+//     -------------------------------------------------
+//
+//     N = (-1^sign) * mantissa * 256^(exponent-3)
+func CompactToBig(compact uint64) *big.Int {
+       // Extract the mantissa, sign bit, and exponent.
+       mantissa := compact & 0x007fffffffffffff
+       isNegative := compact&0x0080000000000000 != 0
+       exponent := uint(compact >> 56)
+
+       var bn *big.Int
+       if exponent <= 3 {
+               mantissa >>= 8 * (3 - exponent)
+               bn = big.NewInt(int64(mantissa))
+       } else {
+               bn = big.NewInt(int64(mantissa))
+               bn.Lsh(bn, 8*(exponent-3))
+       }
+
+       if isNegative {
+               bn = bn.Neg(bn)
+       }
+
+       return bn
+}
+
+// BigToCompact converts a whole number N to a compact representation using
+// an unsigned 64-bit number
+func BigToCompact(n *big.Int) uint64 {
+       if n.Sign() == 0 {
+               return 0
+       }
+
+       var mantissa uint64
+       exponent := uint(len(n.Bytes()))
+       if exponent <= 3 {
+               mantissa = uint64(n.Bits()[0])
+               mantissa <<= 8 * (3 - exponent)
+       } else {
+               tn := new(big.Int).Set(n)
+               mantissa = uint64(tn.Rsh(tn, 8*(exponent-3)).Bits()[0])
+       }
+
+       if mantissa&0x0080000000000000 != 0 {
+               mantissa >>= 8
+               exponent++
+       }
+
+       compact := uint64(exponent<<56) | mantissa
+       if n.Sign() < 0 {
+               compact |= 0x0080000000000000
+       }
+       return compact
+}
+
+func CheckProofOfWork(hash *bc.Hash, bits uint64) bool {
+       if HashToBig(hash).Cmp(CompactToBig(bits)) <= 0 {
+               return true
+       }
+       return false
+}
+
+func CalcNextRequiredDifficulty() uint64 {
+       return uint64(2161727821138738707)
+}
+
+func BlockSubsidy(height uint64) uint64 {
+       return baseSubsidy >> uint(height/subsidyReductionInterval)
+}
similarity index 55%
rename from protocol/bc/blockheader_test.go
rename to consensus/general_test.go
index ebbba71..9408951 100644 (file)
@@ -1,10 +1,19 @@
-package bc
+package consensus
 
 import (
+       "fmt"
+       "math/big"
        "testing"
 )
 
-func TestSubsidy(t *testing.T) {
+func TestCalcNextRequiredDifficulty(t *testing.T) {
+       //fmt.Println(CalcNextRequiredDifficulty())
+       x := big.NewInt(123)
+       y, _ := x.SetString("94847123945178081620347972471576132812524935594538618173381454864040345", 10)
+       fmt.Println(BigToCompact(y))
+}
+
+/*func TestSubsidy(t *testing.T) {
        cases := []struct {
                bh      *BlockHeader
                subsidy uint64
@@ -30,4 +39,4 @@ func TestSubsidy(t *testing.T) {
                        t.Errorf("got subsidy %s, want %s", subsidy, c.subsidy)
                }
        }
-}
+}*/
diff --git a/mining/README.md b/mining/README.md
deleted file mode 100755 (executable)
index fb3093c..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-mining\r
-======\r
-\r
-[![Build Status](http://img.shields.io/travis/btcsuite/btcd.svg)](https://travis-ci.org/btcsuite/btcd)\r
-[![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org)\r
-[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](http://godoc.org/github.com/btcsuite/btcd/mining)\r
-\r
-## Overview\r
-\r
-This package is currently a work in progress.\r
-\r
-## Installation and Updating\r
-\r
-```bash\r
-$ go get -u github.com/btcsuite/btcd/mining\r
-```\r
-\r
-## License\r
-\r
-Package mining is licensed under the [copyfree](http://copyfree.org) ISC\r
-License.\r
diff --git a/mining/cpuminer/README.md b/mining/cpuminer/README.md
deleted file mode 100755 (executable)
index 5042ce1..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-cpuminer\r
-========\r
-\r
-[![Build Status](http://img.shields.io/travis/btcsuite/btcd.svg)](https://travis-ci.org/btcsuite/btcd)\r
-[![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org)\r
-[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](http://godoc.org/github.com/btcsuite/btcd/mining/cpuminer)\r
-\r
-## Overview\r
-\r
-This package is currently a work in progress.  It works without issue since it\r
-is used in several of the integration tests, but the API is not really ready for\r
-public consumption as it has simply been refactored out of the main codebase for\r
-now.\r
-\r
-## Installation and Updating\r
-\r
-```bash\r
-$ go get -u github.com/btcsuite/btcd/mining/cpuminer\r
-```\r
-\r
-## License\r
-\r
-Package cpuminer is licensed under the [copyfree](http://copyfree.org) ISC\r
-License.\r
old mode 100755 (executable)
new mode 100644 (file)
index 7072adb..08e327a
-// Copyright (c) 2014-2016 The btcsuite developers\r
-// Use of this source code is governed by an ISC\r
-// license that can be found in the LICENSE file.\r
-\r
-package cpuminer\r
-\r
-import (\r
-       "errors"\r
-       "fmt"\r
-       "math/rand"\r
-       "runtime"\r
-       "sync"\r
-       "time"\r
-\r
-       "github.com/btcsuite/btcd/blockchain"\r
-       "github.com/btcsuite/btcd/chaincfg"\r
-       "github.com/btcsuite/btcd/chaincfg/chainhash"\r
-       "github.com/btcsuite/btcd/mining"\r
-       "github.com/btcsuite/btcd/wire"\r
-       "github.com/btcsuite/btcutil"\r
-)\r
-\r
-const (\r
-       // maxNonce is the maximum value a nonce can be in a block header.\r
-       maxNonce = ^uint32(0) // 2^32 - 1\r
-\r
-       // maxExtraNonce is the maximum value an extra nonce used in a coinbase\r
-       // transaction can be.\r
-       maxExtraNonce = ^uint64(0) // 2^64 - 1\r
-\r
-       // hpsUpdateSecs is the number of seconds to wait in between each\r
-       // update to the hashes per second monitor.\r
-       hpsUpdateSecs = 10\r
-\r
-       // hashUpdateSec is the number of seconds each worker waits in between\r
-       // notifying the speed monitor with how many hashes have been completed\r
-       // while they are actively searching for a solution.  This is done to\r
-       // reduce the amount of syncs between the workers that must be done to\r
-       // keep track of the hashes per second.\r
-       hashUpdateSecs = 15\r
-)\r
-\r
-var (\r
-       // defaultNumWorkers is the default number of workers to use for mining\r
-       // and is based on the number of processor cores.  This helps ensure the\r
-       // system stays reasonably responsive under heavy load.\r
-       defaultNumWorkers = uint32(runtime.NumCPU())\r
-)\r
-\r
-// Config is a descriptor containing the cpu miner configuration.\r
-type Config struct {\r
-       // ChainParams identifies which chain parameters the cpu miner is\r
-       // associated with.\r
-       ChainParams *chaincfg.Params\r
-\r
-       // BlockTemplateGenerator identifies the instance to use in order to\r
-       // generate block templates that the miner will attempt to solve.\r
-       BlockTemplateGenerator *mining.BlkTmplGenerator\r
-\r
-       // MiningAddrs is a list of payment addresses to use for the generated\r
-       // blocks.  Each generated block will randomly choose one of them.\r
-       MiningAddrs []btcutil.Address\r
-\r
-       // ProcessBlock defines the function to call with any solved blocks.\r
-       // It typically must run the provided block through the same set of\r
-       // rules and handling as any other block coming from the network.\r
-       ProcessBlock func(*btcutil.Block, blockchain.BehaviorFlags) (bool, error)\r
-\r
-       // ConnectedCount defines the function to use to obtain how many other\r
-       // peers the server is connected to.  This is used by the automatic\r
-       // persistent mining routine to determine whether or it should attempt\r
-       // mining.  This is useful because there is no point in mining when not\r
-       // connected to any peers since there would no be anyone to send any\r
-       // found blocks to.\r
-       ConnectedCount func() int32\r
-\r
-       // IsCurrent defines the function to use to obtain whether or not the\r
-       // block chain is current.  This is used by the automatic persistent\r
-       // mining routine to determine whether or it should attempt mining.\r
-       // This is useful because there is no point in mining if the chain is\r
-       // not current since any solved blocks would be on a side chain and and\r
-       // up orphaned anyways.\r
-       IsCurrent func() bool\r
-}\r
-\r
-// CPUMiner provides facilities for solving blocks (mining) using the CPU in\r
-// a concurrency-safe manner.  It consists of two main goroutines -- a speed\r
-// monitor and a controller for worker goroutines which generate and solve\r
-// blocks.  The number of goroutines can be set via the SetMaxGoRoutines\r
-// function, but the default is based on the number of processor cores in the\r
-// system which is typically sufficient.\r
-type CPUMiner struct {\r
-       sync.Mutex\r
-       g                 *mining.BlkTmplGenerator\r
-       cfg               Config\r
-       numWorkers        uint32\r
-       started           bool\r
-       discreteMining    bool\r
-       submitBlockLock   sync.Mutex\r
-       wg                sync.WaitGroup\r
-       workerWg          sync.WaitGroup\r
-       updateNumWorkers  chan struct{}\r
-       queryHashesPerSec chan float64\r
-       updateHashes      chan uint64\r
-       speedMonitorQuit  chan struct{}\r
-       quit              chan struct{}\r
-}\r
-\r
-// speedMonitor handles tracking the number of hashes per second the mining\r
-// process is performing.  It must be run as a goroutine.\r
-func (m *CPUMiner) speedMonitor() {\r
-       log.Tracef("CPU miner speed monitor started")\r
-\r
-       var hashesPerSec float64\r
-       var totalHashes uint64\r
-       ticker := time.NewTicker(time.Second * hpsUpdateSecs)\r
-       defer ticker.Stop()\r
-\r
-out:\r
-       for {\r
-               select {\r
-               // Periodic updates from the workers with how many hashes they\r
-               // have performed.\r
-               case numHashes := <-m.updateHashes:\r
-                       totalHashes += numHashes\r
-\r
-               // Time to update the hashes per second.\r
-               case <-ticker.C:\r
-                       curHashesPerSec := float64(totalHashes) / hpsUpdateSecs\r
-                       if hashesPerSec == 0 {\r
-                               hashesPerSec = curHashesPerSec\r
-                       }\r
-                       hashesPerSec = (hashesPerSec + curHashesPerSec) / 2\r
-                       totalHashes = 0\r
-                       if hashesPerSec != 0 {\r
-                               log.Debugf("Hash speed: %6.0f kilohashes/s",\r
-                                       hashesPerSec/1000)\r
-                       }\r
-\r
-               // Request for the number of hashes per second.\r
-               case m.queryHashesPerSec <- hashesPerSec:\r
-                       // Nothing to do.\r
-\r
-               case <-m.speedMonitorQuit:\r
-                       break out\r
-               }\r
-       }\r
-\r
-       m.wg.Done()\r
-       log.Tracef("CPU miner speed monitor done")\r
-}\r
-\r
-// submitBlock submits the passed block to network after ensuring it passes all\r
-// of the consensus validation rules.\r
-func (m *CPUMiner) submitBlock(block *btcutil.Block) bool {\r
-       m.submitBlockLock.Lock()\r
-       defer m.submitBlockLock.Unlock()\r
-\r
-       // Ensure the block is not stale since a new block could have shown up\r
-       // while the solution was being found.  Typically that condition is\r
-       // detected and all work on the stale block is halted to start work on\r
-       // a new block, but the check only happens periodically, so it is\r
-       // possible a block was found and submitted in between.\r
-       msgBlock := block.MsgBlock()\r
-       if !msgBlock.Header.PrevBlock.IsEqual(&m.g.BestSnapshot().Hash) {\r
-               log.Debugf("Block submitted via CPU miner with previous "+\r
-                       "block %s is stale", msgBlock.Header.PrevBlock)\r
-               return false\r
-       }\r
-\r
-       // Process this block using the same rules as blocks coming from other\r
-       // nodes.  This will in turn relay it to the network like normal.\r
-       isOrphan, err := m.cfg.ProcessBlock(block, blockchain.BFNone)\r
-       if err != nil {\r
-               // Anything other than a rule violation is an unexpected error,\r
-               // so log that error as an internal error.\r
-               if _, ok := err.(blockchain.RuleError); !ok {\r
-                       log.Errorf("Unexpected error while processing "+\r
-                               "block submitted via CPU miner: %v", err)\r
-                       return false\r
-               }\r
-\r
-               log.Debugf("Block submitted via CPU miner rejected: %v", err)\r
-               return false\r
-       }\r
-       if isOrphan {\r
-               log.Debugf("Block submitted via CPU miner is an orphan")\r
-               return false\r
-       }\r
-\r
-       // The block was accepted.\r
-       coinbaseTx := block.MsgBlock().Transactions[0].TxOut[0]\r
-       log.Infof("Block submitted via CPU miner accepted (hash %s, "+\r
-               "amount %v)", block.Hash(), btcutil.Amount(coinbaseTx.Value))\r
-       return true\r
-}\r
-\r
-// solveBlock attempts to find some combination of a nonce, extra nonce, and\r
-// current timestamp which makes the passed block hash to a value less than the\r
-// target difficulty.  The timestamp is updated periodically and the passed\r
-// block is modified with all tweaks during this process.  This means that\r
-// when the function returns true, the block is ready for submission.\r
-//\r
-// This function will return early with false when conditions that trigger a\r
-// stale block such as a new block showing up or periodically when there are\r
-// new transactions and enough time has elapsed without finding a solution.\r
-func (m *CPUMiner) solveBlock(msgBlock *wire.MsgBlock, blockHeight int32,\r
-       ticker *time.Ticker, quit chan struct{}) bool {\r
-\r
-       // Choose a random extra nonce offset for this block template and\r
-       // worker.\r
-       enOffset, err := wire.RandomUint64()\r
-       if err != nil {\r
-               log.Errorf("Unexpected error while generating random "+\r
-                       "extra nonce offset: %v", err)\r
-               enOffset = 0\r
-       }\r
-\r
-       // Create some convenience variables.\r
-       header := &msgBlock.Header\r
-       targetDifficulty := blockchain.CompactToBig(header.Bits)\r
-\r
-       // Initial state.\r
-       lastGenerated := time.Now()\r
-       lastTxUpdate := m.g.TxSource().LastUpdated()\r
-       hashesCompleted := uint64(0)\r
-\r
-       // Note that the entire extra nonce range is iterated and the offset is\r
-       // added relying on the fact that overflow will wrap around 0 as\r
-       // provided by the Go spec.\r
-       for extraNonce := uint64(0); extraNonce < maxExtraNonce; extraNonce++ {\r
-               // Update the extra nonce in the block template with the\r
-               // new value by regenerating the coinbase script and\r
-               // setting the merkle root to the new value.\r
-               m.g.UpdateExtraNonce(msgBlock, blockHeight, extraNonce+enOffset)\r
-\r
-               // Search through the entire nonce range for a solution while\r
-               // periodically checking for early quit and stale block\r
-               // conditions along with updates to the speed monitor.\r
-               for i := uint32(0); i <= maxNonce; i++ {\r
-                       select {\r
-                       case <-quit:\r
-                               return false\r
-\r
-                       case <-ticker.C:\r
-                               m.updateHashes <- hashesCompleted\r
-                               hashesCompleted = 0\r
-\r
-                               // The current block is stale if the best block\r
-                               // has changed.\r
-                               best := m.g.BestSnapshot()\r
-                               if !header.PrevBlock.IsEqual(&best.Hash) {\r
-                                       return false\r
-                               }\r
-\r
-                               // The current block is stale if the memory pool\r
-                               // has been updated since the block template was\r
-                               // generated and it has been at least one\r
-                               // minute.\r
-                               if lastTxUpdate != m.g.TxSource().LastUpdated() &&\r
-                                       time.Now().After(lastGenerated.Add(time.Minute)) {\r
-\r
-                                       return false\r
-                               }\r
-\r
-                               m.g.UpdateBlockTime(msgBlock)\r
-\r
-                       default:\r
-                               // Non-blocking select to fall through\r
-                       }\r
-\r
-                       // Update the nonce and hash the block header.  Each\r
-                       // hash is actually a double sha256 (two hashes), so\r
-                       // increment the number of hashes completed for each\r
-                       // attempt accordingly.\r
-                       header.Nonce = i\r
-                       hash := header.BlockHash()\r
-                       hashesCompleted += 2\r
-\r
-                       // The block is solved when the new block hash is less\r
-                       // than the target difficulty.  Yay!\r
-                       if blockchain.HashToBig(&hash).Cmp(targetDifficulty) <= 0 {\r
-                               m.updateHashes <- hashesCompleted\r
-                               return true\r
-                       }\r
-               }\r
-       }\r
-\r
-       return false\r
-}\r
-\r
-// generateBlocks is a worker that is controlled by the miningWorkerController.\r
-// It is self contained in that it creates block templates and attempts to solve\r
-// them while detecting when it is performing stale work and reacting\r
-// accordingly by generating a new block template.  When a block is solved, it\r
-// is submitted.\r
-//\r
-// It must be run as a goroutine.\r
-func (m *CPUMiner) generateBlocks(quit chan struct{}) {\r
-       log.Tracef("Starting generate blocks worker")\r
-\r
-       // Start a ticker which is used to signal checks for stale work and\r
-       // updates to the speed monitor.\r
-       ticker := time.NewTicker(time.Second * hashUpdateSecs)\r
-       defer ticker.Stop()\r
-out:\r
-       for {\r
-               // Quit when the miner is stopped.\r
-               select {\r
-               case <-quit:\r
-                       break out\r
-               default:\r
-                       // Non-blocking select to fall through\r
-               }\r
-\r
-               // Wait until there is a connection to at least one other peer\r
-               // since there is no way to relay a found block or receive\r
-               // transactions to work on when there are no connected peers.\r
-               if m.cfg.ConnectedCount() == 0 {\r
-                       time.Sleep(time.Second)\r
-                       continue\r
-               }\r
-\r
-               // No point in searching for a solution before the chain is\r
-               // synced.  Also, grab the same lock as used for block\r
-               // submission, since the current block will be changing and\r
-               // this would otherwise end up building a new block template on\r
-               // a block that is in the process of becoming stale.\r
-               m.submitBlockLock.Lock()\r
-               curHeight := m.g.BestSnapshot().Height\r
-               if curHeight != 0 && !m.cfg.IsCurrent() {\r
-                       m.submitBlockLock.Unlock()\r
-                       time.Sleep(time.Second)\r
-                       continue\r
-               }\r
-\r
-               // Choose a payment address at random.\r
-               rand.Seed(time.Now().UnixNano())\r
-               payToAddr := m.cfg.MiningAddrs[rand.Intn(len(m.cfg.MiningAddrs))]\r
-\r
-               // Create a new block template using the available transactions\r
-               // in the memory pool as a source of transactions to potentially\r
-               // include in the block.\r
-               template, err := m.g.NewBlockTemplate(payToAddr)\r
-               m.submitBlockLock.Unlock()\r
-               if err != nil {\r
-                       errStr := fmt.Sprintf("Failed to create new block "+\r
-                               "template: %v", err)\r
-                       log.Errorf(errStr)\r
-                       continue\r
-               }\r
-\r
-               // Attempt to solve the block.  The function will exit early\r
-               // with false when conditions that trigger a stale block, so\r
-               // a new block template can be generated.  When the return is\r
-               // true a solution was found, so submit the solved block.\r
-               if m.solveBlock(template.Block, curHeight+1, ticker, quit) {\r
-                       block := btcutil.NewBlock(template.Block)\r
-                       m.submitBlock(block)\r
-               }\r
-       }\r
-\r
-       m.workerWg.Done()\r
-       log.Tracef("Generate blocks worker done")\r
-}\r
-\r
-// miningWorkerController launches the worker goroutines that are used to\r
-// generate block templates and solve them.  It also provides the ability to\r
-// dynamically adjust the number of running worker goroutines.\r
-//\r
-// It must be run as a goroutine.\r
-func (m *CPUMiner) miningWorkerController() {\r
-       // launchWorkers groups common code to launch a specified number of\r
-       // workers for generating blocks.\r
-       var runningWorkers []chan struct{}\r
-       launchWorkers := func(numWorkers uint32) {\r
-               for i := uint32(0); i < numWorkers; i++ {\r
-                       quit := make(chan struct{})\r
-                       runningWorkers = append(runningWorkers, quit)\r
-\r
-                       m.workerWg.Add(1)\r
-                       go m.generateBlocks(quit)\r
-               }\r
-       }\r
-\r
-       // Launch the current number of workers by default.\r
-       runningWorkers = make([]chan struct{}, 0, m.numWorkers)\r
-       launchWorkers(m.numWorkers)\r
-\r
-out:\r
-       for {\r
-               select {\r
-               // Update the number of running workers.\r
-               case <-m.updateNumWorkers:\r
-                       // No change.\r
-                       numRunning := uint32(len(runningWorkers))\r
-                       if m.numWorkers == numRunning {\r
-                               continue\r
-                       }\r
-\r
-                       // Add new workers.\r
-                       if m.numWorkers > numRunning {\r
-                               launchWorkers(m.numWorkers - numRunning)\r
-                               continue\r
-                       }\r
-\r
-                       // Signal the most recently created goroutines to exit.\r
-                       for i := numRunning - 1; i >= m.numWorkers; i-- {\r
-                               close(runningWorkers[i])\r
-                               runningWorkers[i] = nil\r
-                               runningWorkers = runningWorkers[:i]\r
-                       }\r
-\r
-               case <-m.quit:\r
-                       for _, quit := range runningWorkers {\r
-                               close(quit)\r
-                       }\r
-                       break out\r
-               }\r
-       }\r
-\r
-       // Wait until all workers shut down to stop the speed monitor since\r
-       // they rely on being able to send updates to it.\r
-       m.workerWg.Wait()\r
-       close(m.speedMonitorQuit)\r
-       m.wg.Done()\r
-}\r
-\r
-// Start begins the CPU mining process as well as the speed monitor used to\r
-// track hashing metrics.  Calling this function when the CPU miner has\r
-// already been started will have no effect.\r
-//\r
-// This function is safe for concurrent access.\r
-func (m *CPUMiner) Start() {\r
-       m.Lock()\r
-       defer m.Unlock()\r
-\r
-       // Nothing to do if the miner is already running or if running in\r
-       // discrete mode (using GenerateNBlocks).\r
-       if m.started || m.discreteMining {\r
-               return\r
-       }\r
-\r
-       m.quit = make(chan struct{})\r
-       m.speedMonitorQuit = make(chan struct{})\r
-       m.wg.Add(2)\r
-       go m.speedMonitor()\r
-       go m.miningWorkerController()\r
-\r
-       m.started = true\r
-       log.Infof("CPU miner started")\r
-}\r
-\r
-// Stop gracefully stops the mining process by signalling all workers, and the\r
-// speed monitor to quit.  Calling this function when the CPU miner has not\r
-// already been started will have no effect.\r
-//\r
-// This function is safe for concurrent access.\r
-func (m *CPUMiner) Stop() {\r
-       m.Lock()\r
-       defer m.Unlock()\r
-\r
-       // Nothing to do if the miner is not currently running or if running in\r
-       // discrete mode (using GenerateNBlocks).\r
-       if !m.started || m.discreteMining {\r
-               return\r
-       }\r
-\r
-       close(m.quit)\r
-       m.wg.Wait()\r
-       m.started = false\r
-       log.Infof("CPU miner stopped")\r
-}\r
-\r
-// IsMining returns whether or not the CPU miner has been started and is\r
-// therefore currenting mining.\r
-//\r
-// This function is safe for concurrent access.\r
-func (m *CPUMiner) IsMining() bool {\r
-       m.Lock()\r
-       defer m.Unlock()\r
-\r
-       return m.started\r
-}\r
-\r
-// HashesPerSecond returns the number of hashes per second the mining process\r
-// is performing.  0 is returned if the miner is not currently running.\r
-//\r
-// This function is safe for concurrent access.\r
-func (m *CPUMiner) HashesPerSecond() float64 {\r
-       m.Lock()\r
-       defer m.Unlock()\r
-\r
-       // Nothing to do if the miner is not currently running.\r
-       if !m.started {\r
-               return 0\r
-       }\r
-\r
-       return <-m.queryHashesPerSec\r
-}\r
-\r
-// SetNumWorkers sets the number of workers to create which solve blocks.  Any\r
-// negative values will cause a default number of workers to be used which is\r
-// based on the number of processor cores in the system.  A value of 0 will\r
-// cause all CPU mining to be stopped.\r
-//\r
-// This function is safe for concurrent access.\r
-func (m *CPUMiner) SetNumWorkers(numWorkers int32) {\r
-       if numWorkers == 0 {\r
-               m.Stop()\r
-       }\r
-\r
-       // Don't lock until after the first check since Stop does its own\r
-       // locking.\r
-       m.Lock()\r
-       defer m.Unlock()\r
-\r
-       // Use default if provided value is negative.\r
-       if numWorkers < 0 {\r
-               m.numWorkers = defaultNumWorkers\r
-       } else {\r
-               m.numWorkers = uint32(numWorkers)\r
-       }\r
-\r
-       // When the miner is already running, notify the controller about the\r
-       // the change.\r
-       if m.started {\r
-               m.updateNumWorkers <- struct{}{}\r
-       }\r
-}\r
-\r
-// NumWorkers returns the number of workers which are running to solve blocks.\r
-//\r
-// This function is safe for concurrent access.\r
-func (m *CPUMiner) NumWorkers() int32 {\r
-       m.Lock()\r
-       defer m.Unlock()\r
-\r
-       return int32(m.numWorkers)\r
-}\r
-\r
-// GenerateNBlocks generates the requested number of blocks. It is self\r
-// contained in that it creates block templates and attempts to solve them while\r
-// detecting when it is performing stale work and reacting accordingly by\r
-// generating a new block template.  When a block is solved, it is submitted.\r
-// The function returns a list of the hashes of generated blocks.\r
-func (m *CPUMiner) GenerateNBlocks(n uint32) ([]*chainhash.Hash, error) {\r
-       m.Lock()\r
-\r
-       // Respond with an error if server is already mining.\r
-       if m.started || m.discreteMining {\r
-               m.Unlock()\r
-               return nil, errors.New("Server is already CPU mining. Please call " +\r
-                       "`setgenerate 0` before calling discrete `generate` commands.")\r
-       }\r
-\r
-       m.started = true\r
-       m.discreteMining = true\r
-\r
-       m.speedMonitorQuit = make(chan struct{})\r
-       m.wg.Add(1)\r
-       go m.speedMonitor()\r
-\r
-       m.Unlock()\r
-\r
-       log.Tracef("Generating %d blocks", n)\r
-\r
-       i := uint32(0)\r
-       blockHashes := make([]*chainhash.Hash, n)\r
-\r
-       // Start a ticker which is used to signal checks for stale work and\r
-       // updates to the speed monitor.\r
-       ticker := time.NewTicker(time.Second * hashUpdateSecs)\r
-       defer ticker.Stop()\r
-\r
-       for {\r
-               // Read updateNumWorkers in case someone tries a `setgenerate` while\r
-               // we're generating. We can ignore it as the `generate` RPC call only\r
-               // uses 1 worker.\r
-               select {\r
-               case <-m.updateNumWorkers:\r
-               default:\r
-               }\r
-\r
-               // Grab the lock used for block submission, since the current block will\r
-               // be changing and this would otherwise end up building a new block\r
-               // template on a block that is in the process of becoming stale.\r
-               m.submitBlockLock.Lock()\r
-               curHeight := m.g.BestSnapshot().Height\r
-\r
-               // Choose a payment address at random.\r
-               rand.Seed(time.Now().UnixNano())\r
-               payToAddr := m.cfg.MiningAddrs[rand.Intn(len(m.cfg.MiningAddrs))]\r
-\r
-               // Create a new block template using the available transactions\r
-               // in the memory pool as a source of transactions to potentially\r
-               // include in the block.\r
-               template, err := m.g.NewBlockTemplate(payToAddr)\r
-               m.submitBlockLock.Unlock()\r
-               if err != nil {\r
-                       errStr := fmt.Sprintf("Failed to create new block "+\r
-                               "template: %v", err)\r
-                       log.Errorf(errStr)\r
-                       continue\r
-               }\r
-\r
-               // Attempt to solve the block.  The function will exit early\r
-               // with false when conditions that trigger a stale block, so\r
-               // a new block template can be generated.  When the return is\r
-               // true a solution was found, so submit the solved block.\r
-               if m.solveBlock(template.Block, curHeight+1, ticker, nil) {\r
-                       block := btcutil.NewBlock(template.Block)\r
-                       m.submitBlock(block)\r
-                       blockHashes[i] = block.Hash()\r
-                       i++\r
-                       if i == n {\r
-                               log.Tracef("Generated %d blocks", i)\r
-                               m.Lock()\r
-                               close(m.speedMonitorQuit)\r
-                               m.wg.Wait()\r
-                               m.started = false\r
-                               m.discreteMining = false\r
-                               m.Unlock()\r
-                               return blockHashes, nil\r
-                       }\r
-               }\r
-       }\r
-}\r
-\r
-// New returns a new instance of a CPU miner for the provided configuration.\r
-// Use Start to begin the mining process.  See the documentation for CPUMiner\r
-// type for more details.\r
-func New(cfg *Config) *CPUMiner {\r
-       return &CPUMiner{\r
-               g:                 cfg.BlockTemplateGenerator,\r
-               cfg:               *cfg,\r
-               numWorkers:        defaultNumWorkers,\r
-               updateNumWorkers:  make(chan struct{}),\r
-               queryHashesPerSec: make(chan float64),\r
-               updateHashes:      make(chan uint64),\r
-       }\r
-}\r
+// Copyright (c) 2014-2016 The btcsuite developers
+// Use of this source code is governed by an ISC
+// license that can be found in the LICENSE file.
+
+package cpuminer
+
+import (
+       "fmt"
+       "sync"
+       "time"
+
+       "github.com/bytom/consensus"
+       "github.com/bytom/mining"
+       "github.com/bytom/protocol"
+       "github.com/bytom/protocol/bc/legacy"
+)
+
+const (
+       maxNonce          = ^uint64(0) // 2^32 - 1
+       defaultNumWorkers = 1
+       hashUpdateSecs    = 15
+)
+
+// CPUMiner provides facilities for solving blocks (mining) using the CPU in
+// a concurrency-safe manner.
+type CPUMiner struct {
+       sync.Mutex
+       chain             *protocol.Chain
+       txPool            *protocol.TxPool
+       numWorkers        uint64
+       started           bool
+       discreteMining    bool
+       wg                sync.WaitGroup
+       workerWg          sync.WaitGroup
+       updateNumWorkers  chan struct{}
+       queryHashesPerSec chan float64
+       updateHashes      chan uint64
+       speedMonitorQuit  chan struct{}
+       quit              chan struct{}
+}
+
+// solveBlock attempts to find some combination of a nonce, extra nonce, and
+// current timestamp which makes the passed block hash to a value less than the
+// target difficulty.
+func (m *CPUMiner) solveBlock(block *legacy.Block, ticker *time.Ticker, quit chan struct{}) bool {
+       header := &block.BlockHeader
+       targetDifficulty := consensus.CompactToBig(header.Bits)
+
+       for i := uint64(0); i <= maxNonce; i++ {
+               select {
+               case <-quit:
+                       return false
+
+               case <-ticker.C:
+                       if m.chain.Height() >= header.Height {
+                               return false
+                       }
+               default:
+                       // Non-blocking select to fall through
+               }
+
+               header.Nonce = i
+               hash := header.Hash()
+
+               // The block is solved when the new block hash is less
+               // than the target difficulty.  Yay!
+               //fmt.Printf("hash %v, targe %v \n ", consensus.HashToBig(&hash), targetDifficulty)
+               if consensus.HashToBig(&hash).Cmp(targetDifficulty) <= 0 {
+                       return true
+               }
+       }
+       return false
+}
+
+// generateBlocks is a worker that is controlled by the miningWorkerController.
+// It is self contained in that it creates block templates and attempts to solve
+// them while detecting when it is performing stale work and reacting
+// accordingly by generating a new block template.  When a block is solved, it
+// is submitted.
+//
+// It must be run as a goroutine.
+func (m *CPUMiner) generateBlocks(quit chan struct{}) {
+       ticker := time.NewTicker(time.Second * hashUpdateSecs)
+       defer ticker.Stop()
+
+out:
+       for {
+               select {
+               case <-quit:
+                       break out
+               default:
+               }
+
+               //TODO: No point in searching for a solution before the chain is synced
+
+               //TODO: get address from the wallet
+               payToAddr := []byte{}
+
+               // Create a new block template using the available transactions
+               // in the memory pool as a source of transactions to potentially
+               // include in the block.
+               block, err := mining.NewBlockTemplate(m.chain, m.txPool, payToAddr)
+               //fmt.Printf("finish to generate block template with heigh %d \n", block.BlockHeader.Height)
+               if err != nil {
+                       fmt.Printf("Failed to create new block template: %v \n", err)
+                       continue
+               }
+
+               if m.solveBlock(block, ticker, quit) {
+                       //fmt.Printf("====================================")
+                       //fmt.Println(block.BlockHeader.AssetsMerkleRoot)
+                       snap, err := m.chain.ApplyValidBlock(block)
+                       if err != nil {
+                               fmt.Printf("Failed to apply valid block: %v \n", err)
+                               continue
+                       }
+                       err = m.chain.CommitAppliedBlock(nil, block, snap)
+                       if err != nil {
+                               fmt.Printf("Failed to commit block: %v \n", err)
+                               continue
+                       }
+                       /*fmt.Println(block)
+                       x, err := m.chain.GetBlock(block.BlockHeader.Height)
+                       if err != nil {
+                               fmt.Println(err)
+                       }
+                       fmt.Println(x)
+                       fmt.Println(x == block)
+                       fmt.Println(block.Transactions)
+                       fmt.Println(x.Transactions)*/
+                       fmt.Printf("finish commit block heigh %d \n", block.BlockHeader.Height)
+               }
+       }
+
+       m.workerWg.Done()
+}
+
+// miningWorkerController launches the worker goroutines that are used to
+// generate block templates and solve them.  It also provides the ability to
+// dynamically adjust the number of running worker goroutines.
+//
+// It must be run as a goroutine.
+func (m *CPUMiner) miningWorkerController() {
+       // launchWorkers groups common code to launch a specified number of
+       // workers for generating blocks.
+       var runningWorkers []chan struct{}
+       launchWorkers := func(numWorkers uint64) {
+               for i := uint64(0); i < numWorkers; i++ {
+                       quit := make(chan struct{})
+                       runningWorkers = append(runningWorkers, quit)
+
+                       m.workerWg.Add(1)
+                       go m.generateBlocks(quit)
+               }
+       }
+
+       // Launch the current number of workers by default.
+       runningWorkers = make([]chan struct{}, 0, m.numWorkers)
+       launchWorkers(m.numWorkers)
+
+out:
+       for {
+               select {
+               // Update the number of running workers.
+               case <-m.updateNumWorkers:
+                       // No change.
+                       numRunning := uint64(len(runningWorkers))
+                       if m.numWorkers == numRunning {
+                               continue
+                       }
+
+                       // Add new workers.
+                       if m.numWorkers > numRunning {
+                               launchWorkers(m.numWorkers - numRunning)
+                               continue
+                       }
+
+                       // Signal the most recently created goroutines to exit.
+                       for i := numRunning - 1; i >= m.numWorkers; i-- {
+                               close(runningWorkers[i])
+                               runningWorkers[i] = nil
+                               runningWorkers = runningWorkers[:i]
+                       }
+
+               case <-m.quit:
+                       for _, quit := range runningWorkers {
+                               close(quit)
+                       }
+                       break out
+               }
+       }
+
+       // Wait until all workers shut down to stop the speed monitor since
+       // they rely on being able to send updates to it.
+       m.workerWg.Wait()
+       close(m.speedMonitorQuit)
+       m.wg.Done()
+}
+
+// Start begins the CPU mining process as well as the speed monitor used to
+// track hashing metrics.  Calling this function when the CPU miner has
+// already been started will have no effect.
+//
+// This function is safe for concurrent access.
+func (m *CPUMiner) Start() {
+       m.Lock()
+       defer m.Unlock()
+
+       // Nothing to do if the miner is already running or if running in
+       // discrete mode (using GenerateNBlocks).
+       if m.started || m.discreteMining {
+               return
+       }
+
+       m.quit = make(chan struct{})
+       m.speedMonitorQuit = make(chan struct{})
+       m.wg.Add(2)
+       go m.miningWorkerController()
+
+       m.started = true
+}
+
+// Stop gracefully stops the mining process by signalling all workers, and the
+// speed monitor to quit.  Calling this function when the CPU miner has not
+// already been started will have no effect.
+//
+// This function is safe for concurrent access.
+func (m *CPUMiner) Stop() {
+       m.Lock()
+       defer m.Unlock()
+
+       // Nothing to do if the miner is not currently running or if running in
+       // discrete mode (using GenerateNBlocks).
+       if !m.started || m.discreteMining {
+               return
+       }
+
+       close(m.quit)
+       m.wg.Wait()
+       m.started = false
+}
+
+// IsMining returns whether or not the CPU miner has been started and is
+// therefore currenting mining.
+//
+// This function is safe for concurrent access.
+func (m *CPUMiner) IsMining() bool {
+       m.Lock()
+       defer m.Unlock()
+
+       return m.started
+}
+
+// SetNumWorkers sets the number of workers to create which solve blocks.  Any
+// negative values will cause a default number of workers to be used which is
+// based on the number of processor cores in the system.  A value of 0 will
+// cause all CPU mining to be stopped.
+//
+// This function is safe for concurrent access.
+func (m *CPUMiner) SetNumWorkers(numWorkers int32) {
+       if numWorkers == 0 {
+               m.Stop()
+       }
+
+       // Don't lock until after the first check since Stop does its own
+       // locking.
+       m.Lock()
+       defer m.Unlock()
+
+       // Use default if provided value is negative.
+       if numWorkers < 0 {
+               m.numWorkers = defaultNumWorkers
+       } else {
+               m.numWorkers = uint64(numWorkers)
+       }
+
+       // When the miner is already running, notify the controller about the
+       // the change.
+       if m.started {
+               m.updateNumWorkers <- struct{}{}
+       }
+}
+
+// NumWorkers returns the number of workers which are running to solve blocks.
+//
+// This function is safe for concurrent access.
+func (m *CPUMiner) NumWorkers() int32 {
+       m.Lock()
+       defer m.Unlock()
+
+       return int32(m.numWorkers)
+}
+
+// New returns a new instance of a CPU miner for the provided configuration.
+// Use Start to begin the mining process.  See the documentation for CPUMiner
+// type for more details.
+func NewCPUMiner(c *protocol.Chain, txPool *protocol.TxPool) *CPUMiner {
+       return &CPUMiner{
+               chain:             c,
+               txPool:            txPool,
+               numWorkers:        defaultNumWorkers,
+               updateNumWorkers:  make(chan struct{}),
+               queryHashesPerSec: make(chan float64),
+               updateHashes:      make(chan uint64),
+       }
+}
diff --git a/mining/cpuminer/log.go b/mining/cpuminer/log.go
deleted file mode 100755 (executable)
index e1d54ba..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2016 The btcsuite developers\r
-// Use of this source code is governed by an ISC\r
-// license that can be found in the LICENSE file.\r
-\r
-package cpuminer\r
-\r
-import (\r
-       "github.com/btcsuite/btclog"\r
-)\r
-\r
-// log is a logger that is initialized with no output filters.  This\r
-// means the package will not perform any logging by default until the caller\r
-// requests it.\r
-var log btclog.Logger\r
-\r
-// The default amount of logging is none.\r
-func init() {\r
-       DisableLog()\r
-}\r
-\r
-// DisableLog disables all library log output.  Logging output is disabled\r
-// by default until UseLogger is called.\r
-func DisableLog() {\r
-       log = btclog.Disabled\r
-}\r
-\r
-// UseLogger uses a specified Logger to output package logging info.\r
-func UseLogger(logger btclog.Logger) {\r
-       log = logger\r
-}\r
diff --git a/mining/log.go b/mining/log.go
deleted file mode 100755 (executable)
index 4f33e83..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2016 The btcsuite developers\r
-// Use of this source code is governed by an ISC\r
-// license that can be found in the LICENSE file.\r
-\r
-package mining\r
-\r
-import (\r
-       "github.com/btcsuite/btclog"\r
-)\r
-\r
-// log is a logger that is initialized with no output filters.  This\r
-// means the package will not perform any logging by default until the caller\r
-// requests it.\r
-var log btclog.Logger\r
-\r
-// The default amount of logging is none.\r
-func init() {\r
-       DisableLog()\r
-}\r
-\r
-// DisableLog disables all library log output.  Logging output is disabled\r
-// by default until UseLogger is called.\r
-func DisableLog() {\r
-       log = btclog.Disabled\r
-}\r
-\r
-// UseLogger uses a specified Logger to output package logging info.\r
-func UseLogger(logger btclog.Logger) {\r
-       log = logger\r
-}\r
old mode 100755 (executable)
new mode 100644 (file)
index a68f417..6a568aa
-// Copyright (c) 2014-2016 The btcsuite developers\r
-// Use of this source code is governed by an ISC\r
-// license that can be found in the LICENSE file.\r
-\r
-package mining\r
-\r
-import (\r
-       "container/heap"\r
-       "fmt"\r
-       "time"\r
-\r
-       "github.com/btcsuite/btcd/blockchain"\r
-       "github.com/btcsuite/btcd/chaincfg"\r
-       "github.com/btcsuite/btcd/chaincfg/chainhash"\r
-       "github.com/btcsuite/btcd/txscript"\r
-       "github.com/btcsuite/btcd/wire"\r
-       "github.com/btcsuite/btcutil"\r
-)\r
-\r
-const (\r
-       // MinHighPriority is the minimum priority value that allows a\r
-       // transaction to be considered high priority.\r
-       MinHighPriority = btcutil.SatoshiPerBitcoin * 144.0 / 250\r
-\r
-       // blockHeaderOverhead is the max number of bytes it takes to serialize\r
-       // a block header and max possible transaction count.\r
-       blockHeaderOverhead = wire.MaxBlockHeaderPayload + wire.MaxVarIntPayload\r
-\r
-       // CoinbaseFlags is added to the coinbase script of a generated block\r
-       // and is used to monitor BIP16 support as well as blocks that are\r
-       // generated via btcd.\r
-       CoinbaseFlags = "/P2SH/btcd/"\r
-)\r
-\r
-// TxDesc is a descriptor about a transaction in a transaction source along with\r
-// additional metadata.\r
-type TxDesc struct {\r
-       // Tx is the transaction associated with the entry.\r
-       Tx *btcutil.Tx\r
-\r
-       // Added is the time when the entry was added to the source pool.\r
-       Added time.Time\r
-\r
-       // Height is the block height when the entry was added to the the source\r
-       // pool.\r
-       Height int32\r
-\r
-       // Fee is the total fee the transaction associated with the entry pays.\r
-       Fee int64\r
-\r
-       // FeePerKB is the fee the transaction pays in Satoshi per 1000 bytes.\r
-       FeePerKB int64\r
-}\r
-\r
-// TxSource represents a source of transactions to consider for inclusion in\r
-// new blocks.\r
-//\r
-// The interface contract requires that all of these methods are safe for\r
-// concurrent access with respect to the source.\r
-type TxSource interface {\r
-       // LastUpdated returns the last time a transaction was added to or\r
-       // removed from the source pool.\r
-       LastUpdated() time.Time\r
-\r
-       // MiningDescs returns a slice of mining descriptors for all the\r
-       // transactions in the source pool.\r
-       MiningDescs() []*TxDesc\r
-\r
-       // HaveTransaction returns whether or not the passed transaction hash\r
-       // exists in the source pool.\r
-       HaveTransaction(hash *chainhash.Hash) bool\r
-}\r
-\r
-// txPrioItem houses a transaction along with extra information that allows the\r
-// transaction to be prioritized and track dependencies on other transactions\r
-// which have not been mined into a block yet.\r
-type txPrioItem struct {\r
-       tx       *btcutil.Tx\r
-       fee      int64\r
-       priority float64\r
-       feePerKB int64\r
-\r
-       // dependsOn holds a map of transaction hashes which this one depends\r
-       // on.  It will only be set when the transaction references other\r
-       // transactions in the source pool and hence must come after them in\r
-       // a block.\r
-       dependsOn map[chainhash.Hash]struct{}\r
-}\r
-\r
-// txPriorityQueueLessFunc describes a function that can be used as a compare\r
-// function for a transaction priority queue (txPriorityQueue).\r
-type txPriorityQueueLessFunc func(*txPriorityQueue, int, int) bool\r
-\r
-// txPriorityQueue implements a priority queue of txPrioItem elements that\r
-// supports an arbitrary compare function as defined by txPriorityQueueLessFunc.\r
-type txPriorityQueue struct {\r
-       lessFunc txPriorityQueueLessFunc\r
-       items    []*txPrioItem\r
-}\r
-\r
-// Len returns the number of items in the priority queue.  It is part of the\r
-// heap.Interface implementation.\r
-func (pq *txPriorityQueue) Len() int {\r
-       return len(pq.items)\r
-}\r
-\r
-// Less returns whether the item in the priority queue with index i should sort\r
-// before the item with index j by deferring to the assigned less function.  It\r
-// is part of the heap.Interface implementation.\r
-func (pq *txPriorityQueue) Less(i, j int) bool {\r
-       return pq.lessFunc(pq, i, j)\r
-}\r
-\r
-// Swap swaps the items at the passed indices in the priority queue.  It is\r
-// part of the heap.Interface implementation.\r
-func (pq *txPriorityQueue) Swap(i, j int) {\r
-       pq.items[i], pq.items[j] = pq.items[j], pq.items[i]\r
-}\r
-\r
-// Push pushes the passed item onto the priority queue.  It is part of the\r
-// heap.Interface implementation.\r
-func (pq *txPriorityQueue) Push(x interface{}) {\r
-       pq.items = append(pq.items, x.(*txPrioItem))\r
-}\r
-\r
-// Pop removes the highest priority item (according to Less) from the priority\r
-// queue and returns it.  It is part of the heap.Interface implementation.\r
-func (pq *txPriorityQueue) Pop() interface{} {\r
-       n := len(pq.items)\r
-       item := pq.items[n-1]\r
-       pq.items[n-1] = nil\r
-       pq.items = pq.items[0 : n-1]\r
-       return item\r
-}\r
-\r
-// SetLessFunc sets the compare function for the priority queue to the provided\r
-// function.  It also invokes heap.Init on the priority queue using the new\r
-// function so it can immediately be used with heap.Push/Pop.\r
-func (pq *txPriorityQueue) SetLessFunc(lessFunc txPriorityQueueLessFunc) {\r
-       pq.lessFunc = lessFunc\r
-       heap.Init(pq)\r
-}\r
-\r
-// txPQByPriority sorts a txPriorityQueue by transaction priority and then fees\r
-// per kilobyte.\r
-func txPQByPriority(pq *txPriorityQueue, i, j int) bool {\r
-       // Using > here so that pop gives the highest priority item as opposed\r
-       // to the lowest.  Sort by priority first, then fee.\r
-       if pq.items[i].priority == pq.items[j].priority {\r
-               return pq.items[i].feePerKB > pq.items[j].feePerKB\r
-       }\r
-       return pq.items[i].priority > pq.items[j].priority\r
-\r
-}\r
-\r
-// txPQByFee sorts a txPriorityQueue by fees per kilobyte and then transaction\r
-// priority.\r
-func txPQByFee(pq *txPriorityQueue, i, j int) bool {\r
-       // Using > here so that pop gives the highest fee item as opposed\r
-       // to the lowest.  Sort by fee first, then priority.\r
-       if pq.items[i].feePerKB == pq.items[j].feePerKB {\r
-               return pq.items[i].priority > pq.items[j].priority\r
-       }\r
-       return pq.items[i].feePerKB > pq.items[j].feePerKB\r
-}\r
-\r
-// newTxPriorityQueue returns a new transaction priority queue that reserves the\r
-// passed amount of space for the elements.  The new priority queue uses either\r
-// the txPQByPriority or the txPQByFee compare function depending on the\r
-// sortByFee parameter and is already initialized for use with heap.Push/Pop.\r
-// The priority queue can grow larger than the reserved space, but extra copies\r
-// of the underlying array can be avoided by reserving a sane value.\r
-func newTxPriorityQueue(reserve int, sortByFee bool) *txPriorityQueue {\r
-       pq := &txPriorityQueue{\r
-               items: make([]*txPrioItem, 0, reserve),\r
-       }\r
-       if sortByFee {\r
-               pq.SetLessFunc(txPQByFee)\r
-       } else {\r
-               pq.SetLessFunc(txPQByPriority)\r
-       }\r
-       return pq\r
-}\r
-\r
-// BlockTemplate houses a block that has yet to be solved along with additional\r
-// details about the fees and the number of signature operations for each\r
-// transaction in the block.\r
-type BlockTemplate struct {\r
-       // Block is a block that is ready to be solved by miners.  Thus, it is\r
-       // completely valid with the exception of satisfying the proof-of-work\r
-       // requirement.\r
-       Block *wire.MsgBlock\r
-\r
-       // Fees contains the amount of fees each transaction in the generated\r
-       // template pays in base units.  Since the first transaction is the\r
-       // coinbase, the first entry (offset 0) will contain the negative of the\r
-       // sum of the fees of all other transactions.\r
-       Fees []int64\r
-\r
-       // SigOpCounts contains the number of signature operations each\r
-       // transaction in the generated template performs.\r
-       SigOpCounts []int64\r
-\r
-       // Height is the height at which the block template connects to the main\r
-       // chain.\r
-       Height int32\r
-\r
-       // ValidPayAddress indicates whether or not the template coinbase pays\r
-       // to an address or is redeemable by anyone.  See the documentation on\r
-       // NewBlockTemplate for details on which this can be useful to generate\r
-       // templates without a coinbase payment address.\r
-       ValidPayAddress bool\r
-}\r
-\r
-// mergeUtxoView adds all of the entries in view to viewA.  The result is that\r
-// viewA will contain all of its original entries plus all of the entries\r
-// in viewB.  It will replace any entries in viewB which also exist in viewA\r
-// if the entry in viewA is fully spent.\r
-func mergeUtxoView(viewA *blockchain.UtxoViewpoint, viewB *blockchain.UtxoViewpoint) {\r
-       viewAEntries := viewA.Entries()\r
-       for hash, entryB := range viewB.Entries() {\r
-               if entryA, exists := viewAEntries[hash]; !exists ||\r
-                       entryA == nil || entryA.IsFullySpent() {\r
-\r
-                       viewAEntries[hash] = entryB\r
-               }\r
-       }\r
-}\r
-\r
-// standardCoinbaseScript returns a standard script suitable for use as the\r
-// signature script of the coinbase transaction of a new block.  In particular,\r
-// it starts with the block height that is required by version 2 blocks and adds\r
-// the extra nonce as well as additional coinbase flags.\r
-func standardCoinbaseScript(nextBlockHeight int32, extraNonce uint64) ([]byte, error) {\r
-       return txscript.NewScriptBuilder().AddInt64(int64(nextBlockHeight)).\r
-               AddInt64(int64(extraNonce)).AddData([]byte(CoinbaseFlags)).\r
-               Script()\r
-}\r
-\r
-// createCoinbaseTx returns a coinbase transaction paying an appropriate subsidy\r
-// based on the passed block height to the provided address.  When the address\r
-// is nil, the coinbase transaction will instead be redeemable by anyone.\r
-//\r
-// See the comment for NewBlockTemplate for more information about why the nil\r
-// address handling is useful.\r
-func createCoinbaseTx(params *chaincfg.Params, coinbaseScript []byte, nextBlockHeight int32, addr btcutil.Address) (*btcutil.Tx, error) {\r
-       // Create the script to pay to the provided payment address if one was\r
-       // specified.  Otherwise create a script that allows the coinbase to be\r
-       // redeemable by anyone.\r
-       var pkScript []byte\r
-       if addr != nil {\r
-               var err error\r
-               pkScript, err = txscript.PayToAddrScript(addr)\r
-               if err != nil {\r
-                       return nil, err\r
-               }\r
-       } else {\r
-               var err error\r
-               scriptBuilder := txscript.NewScriptBuilder()\r
-               pkScript, err = scriptBuilder.AddOp(txscript.OP_TRUE).Script()\r
-               if err != nil {\r
-                       return nil, err\r
-               }\r
-       }\r
-\r
-       tx := wire.NewMsgTx(wire.TxVersion)\r
-       tx.AddTxIn(&wire.TxIn{\r
-               // Coinbase transactions have no inputs, so previous outpoint is\r
-               // zero hash and max index.\r
-               PreviousOutPoint: *wire.NewOutPoint(&chainhash.Hash{},\r
-                       wire.MaxPrevOutIndex),\r
-               SignatureScript: coinbaseScript,\r
-               Sequence:        wire.MaxTxInSequenceNum,\r
-       })\r
-       tx.AddTxOut(&wire.TxOut{\r
-               Value:    blockchain.CalcBlockSubsidy(nextBlockHeight, params),\r
-               PkScript: pkScript,\r
-       })\r
-       return btcutil.NewTx(tx), nil\r
-}\r
-\r
-// spendTransaction updates the passed view by marking the inputs to the passed\r
-// transaction as spent.  It also adds all outputs in the passed transaction\r
-// which are not provably unspendable as available unspent transaction outputs.\r
-func spendTransaction(utxoView *blockchain.UtxoViewpoint, tx *btcutil.Tx, height int32) error {\r
-       for _, txIn := range tx.MsgTx().TxIn {\r
-               originHash := &txIn.PreviousOutPoint.Hash\r
-               originIndex := txIn.PreviousOutPoint.Index\r
-               entry := utxoView.LookupEntry(originHash)\r
-               if entry != nil {\r
-                       entry.SpendOutput(originIndex)\r
-               }\r
-       }\r
-\r
-       utxoView.AddTxOuts(tx, height)\r
-       return nil\r
-}\r
-\r
-// logSkippedDeps logs any dependencies which are also skipped as a result of\r
-// skipping a transaction while generating a block template at the trace level.\r
-func logSkippedDeps(tx *btcutil.Tx, deps map[chainhash.Hash]*txPrioItem) {\r
-       if deps == nil {\r
-               return\r
-       }\r
-\r
-       for _, item := range deps {\r
-               log.Tracef("Skipping tx %s since it depends on %s\n",\r
-                       item.tx.Hash(), tx.Hash())\r
-       }\r
-}\r
-\r
-// MinimumMedianTime returns the minimum allowed timestamp for a block building\r
-// on the end of the provided best chain.  In particular, it is one second after\r
-// the median timestamp of the last several blocks per the chain consensus\r
-// rules.\r
-func MinimumMedianTime(chainState *blockchain.BestState) time.Time {\r
-       return chainState.MedianTime.Add(time.Second)\r
-}\r
-\r
-// medianAdjustedTime returns the current time adjusted to ensure it is at least\r
-// one second after the median timestamp of the last several blocks per the\r
-// chain consensus rules.\r
-func medianAdjustedTime(chainState *blockchain.BestState, timeSource blockchain.MedianTimeSource) time.Time {\r
-       // The timestamp for the block must not be before the median timestamp\r
-       // of the last several blocks.  Thus, choose the maximum between the\r
-       // current time and one second after the past median time.  The current\r
-       // timestamp is truncated to a second boundary before comparison since a\r
-       // block timestamp does not supported a precision greater than one\r
-       // second.\r
-       newTimestamp := timeSource.AdjustedTime()\r
-       minTimestamp := MinimumMedianTime(chainState)\r
-       if newTimestamp.Before(minTimestamp) {\r
-               newTimestamp = minTimestamp\r
-       }\r
-\r
-       return newTimestamp\r
-}\r
-\r
-// BlkTmplGenerator provides a type that can be used to generate block templates\r
-// based on a given mining policy and source of transactions to choose from.\r
-// It also houses additional state required in order to ensure the templates\r
-// are built on top of the current best chain and adhere to the consensus rules.\r
-type BlkTmplGenerator struct {\r
-       policy      *Policy\r
-       chainParams *chaincfg.Params\r
-       txSource    TxSource\r
-       chain       *blockchain.BlockChain\r
-       timeSource  blockchain.MedianTimeSource\r
-       sigCache    *txscript.SigCache\r
-}\r
-\r
-// NewBlkTmplGenerator returns a new block template generator for the given\r
-// policy using transactions from the provided transaction source.\r
-//\r
-// The additional state-related fields are required in order to ensure the\r
-// templates are built on top of the current best chain and adhere to the\r
-// consensus rules.\r
-func NewBlkTmplGenerator(policy *Policy, params *chaincfg.Params,\r
-       txSource TxSource, chain *blockchain.BlockChain,\r
-       timeSource blockchain.MedianTimeSource,\r
-       sigCache *txscript.SigCache) *BlkTmplGenerator {\r
-\r
-       return &BlkTmplGenerator{\r
-               policy:      policy,\r
-               chainParams: params,\r
-               txSource:    txSource,\r
-               chain:       chain,\r
-               timeSource:  timeSource,\r
-               sigCache:    sigCache,\r
-       }\r
-}\r
-\r
-// NewBlockTemplate returns a new block template that is ready to be solved\r
-// using the transactions from the passed transaction source pool and a coinbase\r
-// that either pays to the passed address if it is not nil, or a coinbase that\r
-// is redeemable by anyone if the passed address is nil.  The nil address\r
-// functionality is useful since there are cases such as the getblocktemplate\r
-// RPC where external mining software is responsible for creating their own\r
-// coinbase which will replace the one generated for the block template.  Thus\r
-// the need to have configured address can be avoided.\r
-//\r
-// The transactions selected and included are prioritized according to several\r
-// factors.  First, each transaction has a priority calculated based on its\r
-// value, age of inputs, and size.  Transactions which consist of larger\r
-// amounts, older inputs, and small sizes have the highest priority.  Second, a\r
-// fee per kilobyte is calculated for each transaction.  Transactions with a\r
-// higher fee per kilobyte are preferred.  Finally, the block generation related\r
-// policy settings are all taken into account.\r
-//\r
-// Transactions which only spend outputs from other transactions already in the\r
-// block chain are immediately added to a priority queue which either\r
-// prioritizes based on the priority (then fee per kilobyte) or the fee per\r
-// kilobyte (then priority) depending on whether or not the BlockPrioritySize\r
-// policy setting allots space for high-priority transactions.  Transactions\r
-// which spend outputs from other transactions in the source pool are added to a\r
-// dependency map so they can be added to the priority queue once the\r
-// transactions they depend on have been included.\r
-//\r
-// Once the high-priority area (if configured) has been filled with\r
-// transactions, or the priority falls below what is considered high-priority,\r
-// the priority queue is updated to prioritize by fees per kilobyte (then\r
-// priority).\r
-//\r
-// When the fees per kilobyte drop below the TxMinFreeFee policy setting, the\r
-// transaction will be skipped unless the BlockMinSize policy setting is\r
-// nonzero, in which case the block will be filled with the low-fee/free\r
-// transactions until the block size reaches that minimum size.\r
-//\r
-// Any transactions which would cause the block to exceed the BlockMaxSize\r
-// policy setting, exceed the maximum allowed signature operations per block, or\r
-// otherwise cause the block to be invalid are skipped.\r
-//\r
-// Given the above, a block generated by this function is of the following form:\r
-//\r
-//   -----------------------------------  --  --\r
-//  |      Coinbase Transaction         |   |   |\r
-//  |-----------------------------------|   |   |\r
-//  |                                   |   |   | ----- policy.BlockPrioritySize\r
-//  |   High-priority Transactions      |   |   |\r
-//  |                                   |   |   |\r
-//  |-----------------------------------|   | --\r
-//  |                                   |   |\r
-//  |                                   |   |\r
-//  |                                   |   |--- policy.BlockMaxSize\r
-//  |  Transactions prioritized by fee  |   |\r
-//  |  until <= policy.TxMinFreeFee     |   |\r
-//  |                                   |   |\r
-//  |                                   |   |\r
-//  |                                   |   |\r
-//  |-----------------------------------|   |\r
-//  |  Low-fee/Non high-priority (free) |   |\r
-//  |  transactions (while block size   |   |\r
-//  |  <= policy.BlockMinSize)          |   |\r
-//   -----------------------------------  --\r
-func (g *BlkTmplGenerator) NewBlockTemplate(payToAddress btcutil.Address) (*BlockTemplate, error) {\r
-       // Extend the most recently known best block.\r
-       best := g.chain.BestSnapshot()\r
-       prevHash := &best.Hash\r
-       nextBlockHeight := best.Height + 1\r
-\r
-       // Create a standard coinbase transaction paying to the provided\r
-       // address.  NOTE: The coinbase value will be updated to include the\r
-       // fees from the selected transactions later after they have actually\r
-       // been selected.  It is created here to detect any errors early\r
-       // before potentially doing a lot of work below.  The extra nonce helps\r
-       // ensure the transaction is not a duplicate transaction (paying the\r
-       // same value to the same public key address would otherwise be an\r
-       // identical transaction for block version 1).\r
-       extraNonce := uint64(0)\r
-       coinbaseScript, err := standardCoinbaseScript(nextBlockHeight, extraNonce)\r
-       if err != nil {\r
-               return nil, err\r
-       }\r
-       coinbaseTx, err := createCoinbaseTx(g.chainParams, coinbaseScript,\r
-               nextBlockHeight, payToAddress)\r
-       if err != nil {\r
-               return nil, err\r
-       }\r
-       numCoinbaseSigOps := int64(blockchain.CountSigOps(coinbaseTx))\r
-\r
-       // Get the current source transactions and create a priority queue to\r
-       // hold the transactions which are ready for inclusion into a block\r
-       // along with some priority related and fee metadata.  Reserve the same\r
-       // number of items that are available for the priority queue.  Also,\r
-       // choose the initial sort order for the priority queue based on whether\r
-       // or not there is an area allocated for high-priority transactions.\r
-       sourceTxns := g.txSource.MiningDescs()\r
-       sortedByFee := g.policy.BlockPrioritySize == 0\r
-       priorityQueue := newTxPriorityQueue(len(sourceTxns), sortedByFee)\r
-\r
-       // Create a slice to hold the transactions to be included in the\r
-       // generated block with reserved space.  Also create a utxo view to\r
-       // house all of the input transactions so multiple lookups can be\r
-       // avoided.\r
-       blockTxns := make([]*btcutil.Tx, 0, len(sourceTxns))\r
-       blockTxns = append(blockTxns, coinbaseTx)\r
-       blockUtxos := blockchain.NewUtxoViewpoint()\r
-\r
-       // dependers is used to track transactions which depend on another\r
-       // transaction in the source pool.  This, in conjunction with the\r
-       // dependsOn map kept with each dependent transaction helps quickly\r
-       // determine which dependent transactions are now eligible for inclusion\r
-       // in the block once each transaction has been included.\r
-       dependers := make(map[chainhash.Hash]map[chainhash.Hash]*txPrioItem)\r
-\r
-       // Create slices to hold the fees and number of signature operations\r
-       // for each of the selected transactions and add an entry for the\r
-       // coinbase.  This allows the code below to simply append details about\r
-       // a transaction as it is selected for inclusion in the final block.\r
-       // However, since the total fees aren't known yet, use a dummy value for\r
-       // the coinbase fee which will be updated later.\r
-       txFees := make([]int64, 0, len(sourceTxns))\r
-       txSigOpCounts := make([]int64, 0, len(sourceTxns))\r
-       txFees = append(txFees, -1) // Updated once known\r
-       txSigOpCounts = append(txSigOpCounts, numCoinbaseSigOps)\r
-\r
-       log.Debugf("Considering %d transactions for inclusion to new block",\r
-               len(sourceTxns))\r
-\r
-mempoolLoop:\r
-       for _, txDesc := range sourceTxns {\r
-               // A block can't have more than one coinbase or contain\r
-               // non-finalized transactions.\r
-               tx := txDesc.Tx\r
-               if blockchain.IsCoinBase(tx) {\r
-                       log.Tracef("Skipping coinbase tx %s", tx.Hash())\r
-                       continue\r
-               }\r
-               if !blockchain.IsFinalizedTransaction(tx, nextBlockHeight,\r
-                       g.timeSource.AdjustedTime()) {\r
-\r
-                       log.Tracef("Skipping non-finalized tx %s", tx.Hash())\r
-                       continue\r
-               }\r
-\r
-               // Fetch all of the utxos referenced by the this transaction.\r
-               // NOTE: This intentionally does not fetch inputs from the\r
-               // mempool since a transaction which depends on other\r
-               // transactions in the mempool must come after those\r
-               // dependencies in the final generated block.\r
-               utxos, err := g.chain.FetchUtxoView(tx)\r
-               if err != nil {\r
-                       log.Warnf("Unable to fetch utxo view for tx %s: %v",\r
-                               tx.Hash(), err)\r
-                       continue\r
-               }\r
-\r
-               // Setup dependencies for any transactions which reference\r
-               // other transactions in the mempool so they can be properly\r
-               // ordered below.\r
-               prioItem := &txPrioItem{tx: tx}\r
-               for _, txIn := range tx.MsgTx().TxIn {\r
-                       originHash := &txIn.PreviousOutPoint.Hash\r
-                       originIndex := txIn.PreviousOutPoint.Index\r
-                       utxoEntry := utxos.LookupEntry(originHash)\r
-                       if utxoEntry == nil || utxoEntry.IsOutputSpent(originIndex) {\r
-                               if !g.txSource.HaveTransaction(originHash) {\r
-                                       log.Tracef("Skipping tx %s because it "+\r
-                                               "references unspent output %s "+\r
-                                               "which is not available",\r
-                                               tx.Hash(), txIn.PreviousOutPoint)\r
-                                       continue mempoolLoop\r
-                               }\r
-\r
-                               // The transaction is referencing another\r
-                               // transaction in the source pool, so setup an\r
-                               // ordering dependency.\r
-                               deps, exists := dependers[*originHash]\r
-                               if !exists {\r
-                                       deps = make(map[chainhash.Hash]*txPrioItem)\r
-                                       dependers[*originHash] = deps\r
-                               }\r
-                               deps[*prioItem.tx.Hash()] = prioItem\r
-                               if prioItem.dependsOn == nil {\r
-                                       prioItem.dependsOn = make(\r
-                                               map[chainhash.Hash]struct{})\r
-                               }\r
-                               prioItem.dependsOn[*originHash] = struct{}{}\r
-\r
-                               // Skip the check below. We already know the\r
-                               // referenced transaction is available.\r
-                               continue\r
-                       }\r
-               }\r
-\r
-               // Calculate the final transaction priority using the input\r
-               // value age sum as well as the adjusted transaction size.  The\r
-               // formula is: sum(inputValue * inputAge) / adjustedTxSize\r
-               prioItem.priority = CalcPriority(tx.MsgTx(), utxos,\r
-                       nextBlockHeight)\r
-\r
-               // Calculate the fee in Satoshi/kB.\r
-               prioItem.feePerKB = txDesc.FeePerKB\r
-               prioItem.fee = txDesc.Fee\r
-\r
-               // Add the transaction to the priority queue to mark it ready\r
-               // for inclusion in the block unless it has dependencies.\r
-               if prioItem.dependsOn == nil {\r
-                       heap.Push(priorityQueue, prioItem)\r
-               }\r
-\r
-               // Merge the referenced outputs from the input transactions to\r
-               // this transaction into the block utxo view.  This allows the\r
-               // code below to avoid a second lookup.\r
-               mergeUtxoView(blockUtxos, utxos)\r
-       }\r
-\r
-       log.Tracef("Priority queue len %d, dependers len %d",\r
-               priorityQueue.Len(), len(dependers))\r
-\r
-       // The starting block size is the size of the block header plus the max\r
-       // possible transaction count size, plus the size of the coinbase\r
-       // transaction.\r
-       blockSize := blockHeaderOverhead + uint32(coinbaseTx.MsgTx().SerializeSize())\r
-       blockSigOps := numCoinbaseSigOps\r
-       totalFees := int64(0)\r
-\r
-       // Choose which transactions make it into the block.\r
-       for priorityQueue.Len() > 0 {\r
-               // Grab the highest priority (or highest fee per kilobyte\r
-               // depending on the sort order) transaction.\r
-               prioItem := heap.Pop(priorityQueue).(*txPrioItem)\r
-               tx := prioItem.tx\r
-\r
-               // Grab any transactions which depend on this one.\r
-               deps := dependers[*tx.Hash()]\r
-\r
-               // Enforce maximum block size.  Also check for overflow.\r
-               txSize := uint32(tx.MsgTx().SerializeSize())\r
-               blockPlusTxSize := blockSize + txSize\r
-               if blockPlusTxSize < blockSize ||\r
-                       blockPlusTxSize >= g.policy.BlockMaxSize {\r
-\r
-                       log.Tracef("Skipping tx %s because it would exceed "+\r
-                               "the max block size", tx.Hash())\r
-                       logSkippedDeps(tx, deps)\r
-                       continue\r
-               }\r
-\r
-               // Enforce maximum signature operations per block.  Also check\r
-               // for overflow.\r
-               numSigOps := int64(blockchain.CountSigOps(tx))\r
-               if blockSigOps+numSigOps < blockSigOps ||\r
-                       blockSigOps+numSigOps > blockchain.MaxSigOpsPerBlock {\r
-                       log.Tracef("Skipping tx %s because it would exceed "+\r
-                               "the maximum sigops per block", tx.Hash())\r
-                       logSkippedDeps(tx, deps)\r
-                       continue\r
-               }\r
-               numP2SHSigOps, err := blockchain.CountP2SHSigOps(tx, false,\r
-                       blockUtxos)\r
-               if err != nil {\r
-                       log.Tracef("Skipping tx %s due to error in "+\r
-                               "CountP2SHSigOps: %v", tx.Hash(), err)\r
-                       logSkippedDeps(tx, deps)\r
-                       continue\r
-               }\r
-               numSigOps += int64(numP2SHSigOps)\r
-               if blockSigOps+numSigOps < blockSigOps ||\r
-                       blockSigOps+numSigOps > blockchain.MaxSigOpsPerBlock {\r
-                       log.Tracef("Skipping tx %s because it would exceed "+\r
-                               "the maximum sigops per block (p2sh)",\r
-                               tx.Hash())\r
-                       logSkippedDeps(tx, deps)\r
-                       continue\r
-               }\r
-\r
-               // Skip free transactions once the block is larger than the\r
-               // minimum block size.\r
-               if sortedByFee &&\r
-                       prioItem.feePerKB < int64(g.policy.TxMinFreeFee) &&\r
-                       blockPlusTxSize >= g.policy.BlockMinSize {\r
-\r
-                       log.Tracef("Skipping tx %s with feePerKB %.2f "+\r
-                               "< TxMinFreeFee %d and block size %d >= "+\r
-                               "minBlockSize %d", tx.Hash(), prioItem.feePerKB,\r
-                               g.policy.TxMinFreeFee, blockPlusTxSize,\r
-                               g.policy.BlockMinSize)\r
-                       logSkippedDeps(tx, deps)\r
-                       continue\r
-               }\r
-\r
-               // Prioritize by fee per kilobyte once the block is larger than\r
-               // the priority size or there are no more high-priority\r
-               // transactions.\r
-               if !sortedByFee && (blockPlusTxSize >= g.policy.BlockPrioritySize ||\r
-                       prioItem.priority <= MinHighPriority) {\r
-\r
-                       log.Tracef("Switching to sort by fees per kilobyte "+\r
-                               "blockSize %d >= BlockPrioritySize %d || "+\r
-                               "priority %.2f <= minHighPriority %.2f",\r
-                               blockPlusTxSize, g.policy.BlockPrioritySize,\r
-                               prioItem.priority, MinHighPriority)\r
-\r
-                       sortedByFee = true\r
-                       priorityQueue.SetLessFunc(txPQByFee)\r
-\r
-                       // Put the transaction back into the priority queue and\r
-                       // skip it so it is re-priortized by fees if it won't\r
-                       // fit into the high-priority section or the priority is\r
-                       // too low.  Otherwise this transaction will be the\r
-                       // final one in the high-priority section, so just fall\r
-                       // though to the code below so it is added now.\r
-                       if blockPlusTxSize > g.policy.BlockPrioritySize ||\r
-                               prioItem.priority < MinHighPriority {\r
-\r
-                               heap.Push(priorityQueue, prioItem)\r
-                               continue\r
-                       }\r
-               }\r
-\r
-               // Ensure the transaction inputs pass all of the necessary\r
-               // preconditions before allowing it to be added to the block.\r
-               _, err = blockchain.CheckTransactionInputs(tx, nextBlockHeight,\r
-                       blockUtxos, g.chainParams)\r
-               if err != nil {\r
-                       log.Tracef("Skipping tx %s due to error in "+\r
-                               "CheckTransactionInputs: %v", tx.Hash(), err)\r
-                       logSkippedDeps(tx, deps)\r
-                       continue\r
-               }\r
-               err = blockchain.ValidateTransactionScripts(tx, blockUtxos,\r
-                       txscript.StandardVerifyFlags, g.sigCache)\r
-               if err != nil {\r
-                       log.Tracef("Skipping tx %s due to error in "+\r
-                               "ValidateTransactionScripts: %v", tx.Hash(),\r
-                               err)\r
-                       logSkippedDeps(tx, deps)\r
-                       continue\r
-               }\r
-\r
-               // Spend the transaction inputs in the block utxo view and add\r
-               // an entry for it to ensure any transactions which reference\r
-               // this one have it available as an input and can ensure they\r
-               // aren't double spending.\r
-               spendTransaction(blockUtxos, tx, nextBlockHeight)\r
-\r
-               // Add the transaction to the block, increment counters, and\r
-               // save the fees and signature operation counts to the block\r
-               // template.\r
-               blockTxns = append(blockTxns, tx)\r
-               blockSize += txSize\r
-               blockSigOps += numSigOps\r
-               totalFees += prioItem.fee\r
-               txFees = append(txFees, prioItem.fee)\r
-               txSigOpCounts = append(txSigOpCounts, numSigOps)\r
-\r
-               log.Tracef("Adding tx %s (priority %.2f, feePerKB %.2f)",\r
-                       prioItem.tx.Hash(), prioItem.priority, prioItem.feePerKB)\r
-\r
-               // Add transactions which depend on this one (and also do not\r
-               // have any other unsatisified dependencies) to the priority\r
-               // queue.\r
-               for _, item := range deps {\r
-                       // Add the transaction to the priority queue if there\r
-                       // are no more dependencies after this one.\r
-                       delete(item.dependsOn, *tx.Hash())\r
-                       if len(item.dependsOn) == 0 {\r
-                               heap.Push(priorityQueue, item)\r
-                       }\r
-               }\r
-       }\r
-\r
-       // Now that the actual transactions have been selected, update the\r
-       // block size for the real transaction count and coinbase value with\r
-       // the total fees accordingly.\r
-       blockSize -= wire.MaxVarIntPayload -\r
-               uint32(wire.VarIntSerializeSize(uint64(len(blockTxns))))\r
-       coinbaseTx.MsgTx().TxOut[0].Value += totalFees\r
-       txFees[0] = -totalFees\r
-\r
-       // Calculate the required difficulty for the block.  The timestamp\r
-       // is potentially adjusted to ensure it comes after the median time of\r
-       // the last several blocks per the chain consensus rules.\r
-       ts := medianAdjustedTime(best, g.timeSource)\r
-       reqDifficulty, err := g.chain.CalcNextRequiredDifficulty(ts)\r
-       if err != nil {\r
-               return nil, err\r
-       }\r
-\r
-       // Calculate the next expected block version based on the state of the\r
-       // rule change deployments.\r
-       nextBlockVersion, err := g.chain.CalcNextBlockVersion()\r
-       if err != nil {\r
-               return nil, err\r
-       }\r
-\r
-       // Create a new block ready to be solved.\r
-       merkles := blockchain.BuildMerkleTreeStore(blockTxns)\r
-       var msgBlock wire.MsgBlock\r
-       msgBlock.Header = wire.BlockHeader{\r
-               Version:    nextBlockVersion,\r
-               PrevBlock:  *prevHash,\r
-               MerkleRoot: *merkles[len(merkles)-1],\r
-               Timestamp:  ts,\r
-               Bits:       reqDifficulty,\r
-       }\r
-       for _, tx := range blockTxns {\r
-               if err := msgBlock.AddTransaction(tx.MsgTx()); err != nil {\r
-                       return nil, err\r
-               }\r
-       }\r
-\r
-       // Finally, perform a full check on the created block against the chain\r
-       // consensus rules to ensure it properly connects to the current best\r
-       // chain with no issues.\r
-       block := btcutil.NewBlock(&msgBlock)\r
-       block.SetHeight(nextBlockHeight)\r
-       if err := g.chain.CheckConnectBlock(block); err != nil {\r
-               return nil, err\r
-       }\r
-\r
-       log.Debugf("Created new block template (%d transactions, %d in fees, "+\r
-               "%d signature operations, %d bytes, target difficulty %064x)",\r
-               len(msgBlock.Transactions), totalFees, blockSigOps, blockSize,\r
-               blockchain.CompactToBig(msgBlock.Header.Bits))\r
-\r
-       return &BlockTemplate{\r
-               Block:           &msgBlock,\r
-               Fees:            txFees,\r
-               SigOpCounts:     txSigOpCounts,\r
-               Height:          nextBlockHeight,\r
-               ValidPayAddress: payToAddress != nil,\r
-       }, nil\r
-}\r
-\r
-// UpdateBlockTime updates the timestamp in the header of the passed block to\r
-// the current time while taking into account the median time of the last\r
-// several blocks to ensure the new time is after that time per the chain\r
-// consensus rules.  Finally, it will update the target difficulty if needed\r
-// based on the new time for the test networks since their target difficulty can\r
-// change based upon time.\r
-func (g *BlkTmplGenerator) UpdateBlockTime(msgBlock *wire.MsgBlock) error {\r
-       // The new timestamp is potentially adjusted to ensure it comes after\r
-       // the median time of the last several blocks per the chain consensus\r
-       // rules.\r
-       newTime := medianAdjustedTime(g.chain.BestSnapshot(), g.timeSource)\r
-       msgBlock.Header.Timestamp = newTime\r
-\r
-       // Recalculate the difficulty if running on a network that requires it.\r
-       if g.chainParams.ReduceMinDifficulty {\r
-               difficulty, err := g.chain.CalcNextRequiredDifficulty(newTime)\r
-               if err != nil {\r
-                       return err\r
-               }\r
-               msgBlock.Header.Bits = difficulty\r
-       }\r
-\r
-       return nil\r
-}\r
-\r
-// UpdateExtraNonce updates the extra nonce in the coinbase script of the passed\r
-// block by regenerating the coinbase script with the passed value and block\r
-// height.  It also recalculates and updates the new merkle root that results\r
-// from changing the coinbase script.\r
-func (g *BlkTmplGenerator) UpdateExtraNonce(msgBlock *wire.MsgBlock, blockHeight int32, extraNonce uint64) error {\r
-       coinbaseScript, err := standardCoinbaseScript(blockHeight, extraNonce)\r
-       if err != nil {\r
-               return err\r
-       }\r
-       if len(coinbaseScript) > blockchain.MaxCoinbaseScriptLen {\r
-               return fmt.Errorf("coinbase transaction script length "+\r
-                       "of %d is out of range (min: %d, max: %d)",\r
-                       len(coinbaseScript), blockchain.MinCoinbaseScriptLen,\r
-                       blockchain.MaxCoinbaseScriptLen)\r
-       }\r
-       msgBlock.Transactions[0].TxIn[0].SignatureScript = coinbaseScript\r
-\r
-       // TODO(davec): A btcutil.Block should use saved in the state to avoid\r
-       // recalculating all of the other transaction hashes.\r
-       // block.Transactions[0].InvalidateCache()\r
-\r
-       // Recalculate the merkle root with the updated extra nonce.\r
-       block := btcutil.NewBlock(msgBlock)\r
-       merkles := blockchain.BuildMerkleTreeStore(block.Transactions())\r
-       msgBlock.Header.MerkleRoot = *merkles[len(merkles)-1]\r
-       return nil\r
-}\r
-\r
-// BestSnapshot returns information about the current best chain block and\r
-// related state as of the current point in time using the chain instance\r
-// associated with the block template generator.  The returned state must be\r
-// treated as immutable since it is shared by all callers.\r
-//\r
-// This function is safe for concurrent access.\r
-func (g *BlkTmplGenerator) BestSnapshot() *blockchain.BestState {\r
-       return g.chain.BestSnapshot()\r
-}\r
-\r
-// TxSource returns the associated transaction source.\r
-//\r
-// This function is safe for concurrent access.\r
-func (g *BlkTmplGenerator) TxSource() TxSource {\r
-       return g.txSource\r
-}\r
+// Copyright (c) 2014-2016 The btcsuite developers
+// Use of this source code is governed by an ISC
+// license that can be found in the LICENSE file.
+
+package mining
+
+import (
+       "time"
+
+       "github.com/bytom/blockchain/txbuilder"
+       "github.com/bytom/consensus"
+       "github.com/bytom/errors"
+       "github.com/bytom/protocol"
+       "github.com/bytom/protocol/bc"
+       "github.com/bytom/protocol/bc/legacy"
+       "github.com/bytom/protocol/state"
+       "github.com/bytom/protocol/validation"
+       "github.com/bytom/protocol/vm"
+       "github.com/bytom/protocol/vm/vmutil"
+)
+
+// standardCoinbaseScript returns a standard script suitable for use as the
+// signature script of the coinbase transaction of a new block.
+func standardCoinbaseScript(blockHeight uint64) ([]byte, error) {
+       //TODO: add verify conditions, block heigh & sign
+       scriptBuild := vmutil.NewBuilder()
+       scriptBuild.AddOp(vm.OP_TRUE)
+       return scriptBuild.Build()
+}
+
+// createCoinbaseTx returns a coinbase transaction paying an appropriate subsidy
+// based on the passed block height to the provided address.  When the address
+// is nil, the coinbase transaction will instead be redeemable by anyone.
+func createCoinbaseTx(amount uint64, blockHeight uint64, addr []byte) (*legacy.Tx, error) {
+       //TODO: make sure things works
+       amount += consensus.BlockSubsidy(blockHeight)
+       cbScript, err := standardCoinbaseScript(blockHeight)
+       if err != nil {
+               return nil, err
+       }
+
+       builder := txbuilder.NewBuilder(time.Now())
+       builder.AddOutput(legacy.NewTxOutput(*validation.BTMAssetID, amount, cbScript, nil))
+       _, txData, err := builder.Build()
+       tx := &legacy.Tx{
+               TxData: *txData,
+               Tx:     legacy.MapTx(txData),
+       }
+       return tx, err
+}
+
+// NewBlockTemplate returns a new block template that is ready to be solved
+func NewBlockTemplate(c *protocol.Chain, txPool *protocol.TxPool, addr []byte) (*legacy.Block, error) {
+       // Extend the most recently known best block.
+       var err error
+       newSnap := state.Empty()
+       var blockData *bc.Block
+       nextBlockHeight := uint64(1)
+       preBlockHash := bc.Hash{}
+
+       block, snap := c.State()
+       if block != nil {
+               nextBlockHeight = block.BlockHeader.Height + 1
+               preBlockHash = block.Hash()
+               newSnap = state.Copy(snap)
+               blockData = legacy.MapBlock(block)
+       }
+
+       txDescs := txPool.GetTransactions()
+       blockTxns := make([]*legacy.Tx, 0, len(txDescs))
+       blockWeight := uint64(0)
+       txFee := uint64(0)
+
+       b := &legacy.Block{
+               BlockHeader: legacy.BlockHeader{
+                       Version:           1,
+                       Height:            nextBlockHeight,
+                       PreviousBlockHash: preBlockHash,
+                       TimestampMS:       bc.Millis(time.Now()),
+                       BlockCommitment:   legacy.BlockCommitment{},
+                       Bits:              consensus.CalcNextRequiredDifficulty(),
+               },
+       }
+       newSnap.PruneNonces(b.BlockHeader.TimestampMS)
+
+       var txEntries []*bc.Tx
+       for _, txDesc := range txDescs {
+               tx := txDesc.Tx.Tx
+               blockPlusTxWeight := blockWeight + txDesc.Weight
+               if blockPlusTxWeight > validation.MaxBlockSzie {
+                       break
+               }
+
+               if err := newSnap.ApplyTx(tx); err != nil {
+                       txPool.RemoveTransaction(&tx.ID)
+                       continue
+               }
+
+               if _, err := validation.ValidateTx(tx, blockData); err != nil {
+                       txPool.RemoveTransaction(&tx.ID)
+                       continue
+               }
+
+               blockTxns = append(blockTxns, txDesc.Tx)
+               txEntries = append(txEntries, tx)
+               blockWeight = blockPlusTxWeight
+               txFee += txDesc.Fee
+       }
+
+       cbTx, _ := createCoinbaseTx(txFee, nextBlockHeight, addr)
+       newSnap.ApplyTx(cbTx.Tx)
+       blockTxns = append([]*legacy.Tx{cbTx}, blockTxns...)
+
+       b.Transactions = blockTxns
+
+       b.BlockHeader.BlockCommitment.TransactionsMerkleRoot, err = bc.MerkleRoot(txEntries)
+       b.BlockHeader.BlockCommitment.AssetsMerkleRoot = newSnap.Tree.RootHash()
+       if err != nil {
+               return nil, errors.Wrap(err, "calculating tx merkle root")
+       }
+
+       return b, nil
+}
diff --git a/mining/policy.go b/mining/policy.go
deleted file mode 100755 (executable)
index fe85791..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright (c) 2014-2016 The btcsuite developers\r
-// Use of this source code is governed by an ISC\r
-// license that can be found in the LICENSE file.\r
-\r
-package mining\r
-\r
-import (\r
-       "github.com/btcsuite/btcd/blockchain"\r
-       "github.com/btcsuite/btcd/wire"\r
-       "github.com/btcsuite/btcutil"\r
-)\r
-\r
-const (\r
-       // UnminedHeight is the height used for the "block" height field of the\r
-       // contextual transaction information provided in a transaction store\r
-       // when it has not yet been mined into a block.\r
-       UnminedHeight = 0x7fffffff\r
-)\r
-\r
-// Policy houses the policy (configuration parameters) which is used to control\r
-// the generation of block templates.  See the documentation for\r
-// NewBlockTemplate for more details on each of these parameters are used.\r
-type Policy struct {\r
-       // BlockMinSize is the minimum block size in bytes to be used when\r
-       // generating a block template.\r
-       BlockMinSize uint32\r
-\r
-       // BlockMaxSize is the maximum block size in bytes to be used when\r
-       // generating a block template.\r
-       BlockMaxSize uint32\r
-\r
-       // BlockPrioritySize is the size in bytes for high-priority / low-fee\r
-       // transactions to be used when generating a block template.\r
-       BlockPrioritySize uint32\r
-\r
-       // TxMinFreeFee is the minimum fee in Satoshi/1000 bytes that is\r
-       // required for a transaction to be treated as free for mining purposes\r
-       // (block template generation).\r
-       TxMinFreeFee btcutil.Amount\r
-}\r
-\r
-// minInt is a helper function to return the minimum of two ints.  This avoids\r
-// a math import and the need to cast to floats.\r
-func minInt(a, b int) int {\r
-       if a < b {\r
-               return a\r
-       }\r
-       return b\r
-}\r
-\r
-// calcInputValueAge is a helper function used to calculate the input age of\r
-// a transaction.  The input age for a txin is the number of confirmations\r
-// since the referenced txout multiplied by its output value.  The total input\r
-// age is the sum of this value for each txin.  Any inputs to the transaction\r
-// which are currently in the mempool and hence not mined into a block yet,\r
-// contribute no additional input age to the transaction.\r
-func calcInputValueAge(tx *wire.MsgTx, utxoView *blockchain.UtxoViewpoint, nextBlockHeight int32) float64 {\r
-       var totalInputAge float64\r
-       for _, txIn := range tx.TxIn {\r
-               // Don't attempt to accumulate the total input age if the\r
-               // referenced transaction output doesn't exist.\r
-               originHash := &txIn.PreviousOutPoint.Hash\r
-               originIndex := txIn.PreviousOutPoint.Index\r
-               txEntry := utxoView.LookupEntry(originHash)\r
-               if txEntry != nil && !txEntry.IsOutputSpent(originIndex) {\r
-                       // Inputs with dependencies currently in the mempool\r
-                       // have their block height set to a special constant.\r
-                       // Their input age should computed as zero since their\r
-                       // parent hasn't made it into a block yet.\r
-                       var inputAge int32\r
-                       originHeight := txEntry.BlockHeight()\r
-                       if originHeight == UnminedHeight {\r
-                               inputAge = 0\r
-                       } else {\r
-                               inputAge = nextBlockHeight - originHeight\r
-                       }\r
-\r
-                       // Sum the input value times age.\r
-                       inputValue := txEntry.AmountByIndex(originIndex)\r
-                       totalInputAge += float64(inputValue * int64(inputAge))\r
-               }\r
-       }\r
-\r
-       return totalInputAge\r
-}\r
-\r
-// CalcPriority returns a transaction priority given a transaction and the sum\r
-// of each of its input values multiplied by their age (# of confirmations).\r
-// Thus, the final formula for the priority is:\r
-// sum(inputValue * inputAge) / adjustedTxSize\r
-func CalcPriority(tx *wire.MsgTx, utxoView *blockchain.UtxoViewpoint, nextBlockHeight int32) float64 {\r
-       // In order to encourage spending multiple old unspent transaction\r
-       // outputs thereby reducing the total set, don't count the constant\r
-       // overhead for each input as well as enough bytes of the signature\r
-       // script to cover a pay-to-script-hash redemption with a compressed\r
-       // pubkey.  This makes additional inputs free by boosting the priority\r
-       // of the transaction accordingly.  No more incentive is given to avoid\r
-       // encouraging gaming future transactions through the use of junk\r
-       // outputs.  This is the same logic used in the reference\r
-       // implementation.\r
-       //\r
-       // The constant overhead for a txin is 41 bytes since the previous\r
-       // outpoint is 36 bytes + 4 bytes for the sequence + 1 byte the\r
-       // signature script length.\r
-       //\r
-       // A compressed pubkey pay-to-script-hash redemption with a maximum len\r
-       // signature is of the form:\r
-       // [OP_DATA_73 <73-byte sig> + OP_DATA_35 + {OP_DATA_33\r
-       // <33 byte compresed pubkey> + OP_CHECKSIG}]\r
-       //\r
-       // Thus 1 + 73 + 1 + 1 + 33 + 1 = 110\r
-       overhead := 0\r
-       for _, txIn := range tx.TxIn {\r
-               // Max inputs + size can't possibly overflow here.\r
-               overhead += 41 + minInt(110, len(txIn.SignatureScript))\r
-       }\r
-\r
-       serializedTxSize := tx.SerializeSize()\r
-       if overhead >= serializedTxSize {\r
-               return 0.0\r
-       }\r
-\r
-       inputValueAge := calcInputValueAge(tx, utxoView, nextBlockHeight)\r
-       return inputValueAge / float64(serializedTxSize-overhead)\r
-}\r
index afd9e50..d36f8fb 100644 (file)
@@ -25,10 +25,10 @@ import (
        "github.com/tendermint/tmlibs/log"
        //rpc "github.com/blockchain/rpc/lib"
        "github.com/bytom/blockchain/account"
+       "github.com/bytom/blockchain/asset"
        "github.com/bytom/blockchain/txdb"
        "github.com/bytom/net/http/reqid"
        "github.com/bytom/protocol"
-       "github.com/bytom/blockchain/asset"
        rpcserver "github.com/bytom/rpc/lib/server"
        //      "github.com/bytom/net/http/static"
        //      "github.com/bytom/generated/dashboard"
@@ -199,6 +199,7 @@ func NewNode(config *cfg.Config, logger log.Logger) *Node {
        }
 
        chain, err := protocol.NewChain(context.Background(), genesisBlock.Hash(), store, nil)
+       txPool := protocol.NewTxPool()
        /* if err != nil {
             cmn.Exit(cmn.Fmt("protocol new chain failed: %v", err))
           }
@@ -213,7 +214,8 @@ func NewNode(config *cfg.Config, logger log.Logger) *Node {
        accounts := account.NewManager(accounts_db, chain)
        assets_db := dbm.NewDB("asset", config.DBBackend, config.DBDir())
        assets := asset.NewRegistry(assets_db, chain)
-       bcReactor := bc.NewBlockchainReactor(store, chain, accounts, assets, fastSync)
+       bcReactor := bc.NewBlockchainReactor(store, chain, txPool, accounts, assets, fastSync)
+
        bcReactor.SetLogger(logger.With("module", "blockchain"))
        sw.AddReactor("BLOCKCHAIN", bcReactor)
 
index 1e7cabe..1abda1c 100644 (file)
@@ -2,11 +2,6 @@ package bc
 
 import "io"
 
-const (
-       subsidyReductionInterval = uint64(560640)
-       baseSubsidy              = uint64(624000000000)
-)
-
 // BlockHeader contains the header information for a blockchain
 // block. It satisfies the Entry interface.
 
@@ -18,10 +13,8 @@ func (bh *BlockHeader) writeForHash(w io.Writer) {
        mustWriteForHash(w, bh.TimestampMs)
        mustWriteForHash(w, bh.TransactionsRoot)
        mustWriteForHash(w, bh.AssetsRoot)
-}
-
-func (bh *BlockHeader) BlockSubsidy() uint64 {
-       return baseSubsidy >> uint(bh.Height/subsidyReductionInterval)
+       mustWriteForHash(w, bh.Nonce)
+       mustWriteForHash(w, bh.Bits)
 }
 
 // NewBlockHeader creates a new BlockHeader and populates
index fcb011e..c0b4bae 100644 (file)
@@ -134,11 +134,19 @@ func (c *Chain) ValidateBlock(block, prev *legacy.Block) error {
 // ApplyValidBlock creates an updated snapshot without validating the
 // block.
 func (c *Chain) ApplyValidBlock(block *legacy.Block) (*state.Snapshot, error) {
-       newSnapshot := state.Copy(c.state.snapshot)
+       //TODO replace with a pre-defined init blo
+       var newSnapshot *state.Snapshot
+       if c.state.snapshot == nil {
+               newSnapshot = state.Empty()
+       } else {
+               newSnapshot = state.Copy(c.state.snapshot)
+       }
+
        err := newSnapshot.ApplyBlock(legacy.MapBlock(block))
        if err != nil {
                return nil, err
        }
+       //fmt.Printf("want %v, ger %v \n", block.BlockHeader.AssetsMerkleRoot, newSnapshot.Tree.RootHash())
        if block.AssetsMerkleRoot != newSnapshot.Tree.RootHash() {
                return nil, ErrBadStateRoot
        }
@@ -160,15 +168,15 @@ func (c *Chain) CommitAppliedBlock(ctx context.Context, block *legacy.Block, sna
        // SaveBlock is the linearization point. Once the block is committed
        // to persistent storage, the block has been applied and everything
        // else can be derived from that block.
-       /*err := c.store.SaveBlock(ctx, block)
+       err := c.store.SaveBlock(block)
        if err != nil {
                return errors.Wrap(err, "storing block")
-       }*/
+       }
        if block.Time().After(c.lastQueuedSnapshot.Add(saveSnapshotFrequency)) {
                c.queueSnapshot(ctx, block.Height, block.Time(), snapshot)
        }
 
-       err := c.store.FinalizeBlock(ctx, block.Height)
+       err = c.store.FinalizeBlock(ctx, block.Height)
        if err != nil {
                return errors.Wrap(err, "finalizing block")
        }
@@ -234,6 +242,7 @@ func NewInitialBlock(timestamp time.Time) (*legacy.Block, error) {
                                TransactionsMerkleRoot: root,
                        },
                },
+               Transactions: []*legacy.Tx{},
        }
        return b, nil
 }
similarity index 88%
rename from blockchain/mempool.go
rename to protocol/mempool.go
index 96355f1..4833e02 100644 (file)
@@ -1,4 +1,4 @@
-package blockchain
+package protocol
 
 import (
        "errors"
@@ -6,9 +6,9 @@ import (
        "sync/atomic"
        "time"
 
-       "github.com/golang/groupcache/lru"
-
        "github.com/bytom/protocol/bc"
+       "github.com/bytom/protocol/bc/legacy"
+       "github.com/golang/groupcache/lru"
 )
 
 var (
@@ -18,9 +18,10 @@ var (
 )
 
 type TxDesc struct {
-       Tx       *bc.Tx
+       Tx       *legacy.Tx
        Added    time.Time
        Height   uint64
+       Weight   uint64
        Fee      uint64
        FeePerKB uint64
 }
@@ -40,10 +41,11 @@ func NewTxPool() *TxPool {
        }
 }
 
-func (mp *TxPool) AddTransaction(tx *bc.Tx, height uint64, fee uint64) *TxDesc {
+func (mp *TxPool) AddTransaction(tx *legacy.Tx, weight, height, fee uint64) *TxDesc {
        txD := &TxDesc{
                Tx:       tx,
                Added:    time.Now(),
+               Weight:   weight,
                Height:   height,
                Fee:      fee,
                FeePerKB: fee * 1000 / tx.TxHeader.SerializedSize,
@@ -52,7 +54,7 @@ func (mp *TxPool) AddTransaction(tx *bc.Tx, height uint64, fee uint64) *TxDesc {
        mp.mtx.Lock()
        defer mp.mtx.Unlock()
 
-       mp.pool[tx.ID] = txD
+       mp.pool[tx.Tx.ID] = txD
        atomic.StoreInt64(&mp.lastUpdated, time.Now().Unix())
        return txD
 }
@@ -64,7 +66,7 @@ func (mp *TxPool) AddErrCache(txHash *bc.Hash) {
        mp.errCache.Add(txHash, nil)
 }
 
-func (mp *TxPool) removeTransaction(txHash *bc.Hash) {
+func (mp *TxPool) RemoveTransaction(txHash *bc.Hash) {
        mp.mtx.Lock()
        defer mp.mtx.Unlock()
 
similarity index 79%
rename from blockchain/mempool_test.go
rename to protocol/mempool_test.go
index 9fbe3b1..3ba81a2 100644 (file)
@@ -1,9 +1,8 @@
-package blockchain
+package protocol
 
 import (
        "testing"
 
-       "github.com/bytom/protocol/bc"
        "github.com/bytom/protocol/bc/legacy"
        "github.com/bytom/protocol/validation"
 )
@@ -15,7 +14,7 @@ func TestTxPool(t *testing.T) {
        txB := mockCoinbaseTx(2000, 2324)
        txC := mockCoinbaseTx(3000, 9322)
 
-       p.AddTransaction(txA, 1000, 5000000000)
+       p.AddTransaction(txA, 1, 1000, 5000000000)
        if !p.IsTransactionInPool(&txA.ID) {
                t.Errorf("fail to find added txA in tx pool")
        } else {
@@ -28,14 +27,15 @@ func TestTxPool(t *testing.T) {
        if p.IsTransactionInPool(&txB.ID) {
                t.Errorf("shouldn't find txB in tx pool")
        }
-       p.AddTransaction(txB, 1000, 5000000000)
+       p.AddTransaction(txB, 1000, 1, 5000000000)
        if !p.IsTransactionInPool(&txB.ID) {
                t.Errorf("shouldn find txB in tx pool")
        }
+
        if p.Count() != 2 {
                t.Errorf("get wrong number of tx in the pool")
        }
-       p.removeTransaction(&txB.ID)
+       p.RemoveTransaction(&txB.ID)
        if p.IsTransactionInPool(&txB.ID) {
                t.Errorf("shouldn't find txB in tx pool")
        }
@@ -49,11 +49,16 @@ func TestTxPool(t *testing.T) {
        }
 }
 
-func mockCoinbaseTx(serializedSize uint64, amount uint64) *bc.Tx {
-       return legacy.MapTx(&legacy.TxData{
+func mockCoinbaseTx(serializedSize uint64, amount uint64) *legacy.Tx {
+       oldTx := &legacy.TxData{
                SerializedSize: serializedSize,
                Outputs: []*legacy.TxOutput{
                        legacy.NewTxOutput(*validation.BTMAssetID, amount, []byte{1}, nil),
                },
-       })
+       }
+
+       return &legacy.Tx{
+               TxData: *oldTx,
+               Tx:     legacy.MapTx(oldTx),
+       }
 }
index 55b7740..2db6627 100644 (file)
@@ -3,6 +3,7 @@ package validation
 import (
        "fmt"
 
+       "github.com/bytom/consensus"
        "github.com/bytom/errors"
        "github.com/bytom/math/checked"
        "github.com/bytom/protocol/bc"
@@ -15,7 +16,7 @@ const (
        gasRate         = int64(1000)
 
        maxTxSize    = uint64(1024)
-       maxBlockSzie = uint64(16384)
+       MaxBlockSzie = uint64(16384)
 )
 
 var BTMAssetID = &bc.AssetID{
@@ -514,11 +515,11 @@ func ValidateBlock(b, prev *bc.Block) error {
                }
        }
 
-       if b.BlockHeader.SerializedSize > maxBlockSzie {
+       if b.BlockHeader.SerializedSize > MaxBlockSzie {
                return errWrongBlockSize
        }
 
-       coinbaseValue := b.BlockHeader.BlockSubsidy()
+       coinbaseValue := consensus.BlockSubsidy(b.BlockHeader.Height)
        for i, tx := range b.Transactions {
                if b.Version == 1 && tx.Version != 1 {
                        return errors.WithDetailf(errTxVersion, "block version %d, transaction version %d", b.Version, tx.Version)
diff --git a/rpc/chainhash/chainhash.go b/rpc/chainhash/chainhash.go
deleted file mode 100644 (file)
index 2b1cec0..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (c) 2013-2016 The btcsuite developers
-// Copyright (c) 2015 The Decred developers
-// Use of this source code is governed by an ISC
-// license that can be found in the LICENSE file.
-
-package chainhash
-
-import (
-       "encoding/hex"
-       "fmt"
-)
-
-// HashSize of array used to store hashes.  See Hash.
-const HashSize = 32
-
-// MaxHashStringSize is the maximum length of a Hash hash string.
-const MaxHashStringSize = HashSize * 2
-
-// ErrHashStrSize describes an error that indicates the caller specified a hash
-// string that has too many characters.
-var ErrHashStrSize = fmt.Errorf("max hash string length is %v bytes", MaxHashStringSize)
-
-// Hash is used in several of the bitcoin messages and common structures.  It
-// typically represents the double sha256 of data.
-type Hash [HashSize]byte
-
-// String returns the Hash as the hexadecimal string of the byte-reversed
-// hash.
-func (hash Hash) String() string {
-       for i := 0; i < HashSize/2; i++ {
-               hash[i], hash[HashSize-1-i] = hash[HashSize-1-i], hash[i]
-       }
-       return hex.EncodeToString(hash[:])
-}
-
-// CloneBytes returns a copy of the bytes which represent the hash as a byte
-// slice.
-//
-// NOTE: It is generally cheaper to just slice the hash directly thereby reusing
-// the same bytes rather than calling this method.
-func (hash *Hash) CloneBytes() []byte {
-       newHash := make([]byte, HashSize)
-       copy(newHash, hash[:])
-
-       return newHash
-}
-
-// SetBytes sets the bytes which represent the hash.  An error is returned if
-// the number of bytes passed in is not HashSize.
-func (hash *Hash) SetBytes(newHash []byte) error {
-       nhlen := len(newHash)
-       if nhlen != HashSize {
-               return fmt.Errorf("invalid hash length of %v, want %v", nhlen,
-                       HashSize)
-       }
-       copy(hash[:], newHash)
-
-       return nil
-}
-
-// IsEqual returns true if target is the same as hash.
-func (hash *Hash) IsEqual(target *Hash) bool {
-       if hash == nil && target == nil {
-               return true
-       }
-       if hash == nil || target == nil {
-               return false
-       }
-       return *hash == *target
-}
-
-// NewHash returns a new Hash from a byte slice.  An error is returned if
-// the number of bytes passed in is not HashSize.
-func NewHash(newHash []byte) (*Hash, error) {
-       var sh Hash
-       err := sh.SetBytes(newHash)
-       if err != nil {
-               return nil, err
-       }
-       return &sh, err
-}
-
-// NewHashFromStr creates a Hash from a hash string.  The string should be
-// the hexadecimal string of a byte-reversed hash, but any missing characters
-// result in zero padding at the end of the Hash.
-func NewHashFromStr(hash string) (*Hash, error) {
-       ret := new(Hash)
-       err := Decode(ret, hash)
-       if err != nil {
-               return nil, err
-       }
-       return ret, nil
-}
-
-// Decode decodes the byte-reversed hexadecimal string encoding of a Hash to a
-// destination.
-func Decode(dst *Hash, src string) error {
-       // Return error if hash string is too long.
-       if len(src) > MaxHashStringSize {
-               return ErrHashStrSize
-       }
-
-       // Hex decoder expects the hash to be a multiple of two.  When not, pad
-       // with a leading zero.
-       var srcBytes []byte
-       if len(src)%2 == 0 {
-               srcBytes = []byte(src)
-       } else {
-               srcBytes = make([]byte, 1+len(src))
-               srcBytes[0] = '0'
-               copy(srcBytes[1:], src)
-       }
-
-       // Hex decode the source bytes to a temporary destination.
-       var reversedHash Hash
-       _, err := hex.Decode(reversedHash[HashSize-hex.DecodedLen(len(srcBytes)):], srcBytes)
-       if err != nil {
-               return err
-       }
-
-       // Reverse copy from the temporary hash to destination.  Because the
-       // temporary was zeroed, the written result will be correctly padded.
-       for i, b := range reversedHash[:HashSize/2] {
-               dst[i], dst[HashSize-1-i] = reversedHash[HashSize-1-i], b
-       }
-
-       return nil
-}
diff --git a/rpc/chainhash/hashfunc.go b/rpc/chainhash/hashfunc.go
deleted file mode 100644 (file)
index bf74f73..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2015 The Decred developers
-// Copyright (c) 2016-2017 The btcsuite developers
-// Use of this source code is governed by an ISC
-// license that can be found in the LICENSE file.
-
-package chainhash
-
-import "crypto/sha256"
-
-// HashB calculates hash(b) and returns the resulting bytes.
-func HashB(b []byte) []byte {
-       hash := sha256.Sum256(b)
-       return hash[:]
-}
-
-// HashH calculates hash(b) and returns the resulting bytes as a Hash.
-func HashH(b []byte) Hash {
-       return Hash(sha256.Sum256(b))
-}
-
-// DoubleHashB calculates hash(hash(b)) and returns the resulting bytes.
-func DoubleHashB(b []byte) []byte {
-       first := sha256.Sum256(b)
-       second := sha256.Sum256(first[:])
-       return second[:]
-}
-
-// DoubleHashH calculates hash(hash(b)) and returns the resulting bytes as a
-// Hash.
-func DoubleHashH(b []byte) Hash {
-       first := sha256.Sum256(b)
-       return Hash(sha256.Sum256(first[:]))
-}
diff --git a/rpc/core/difficulty.go b/rpc/core/difficulty.go
deleted file mode 100644 (file)
index 9cf9dfc..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-package core
-
-import (
-       "math/big"
-       //"time"
-       //"github.com/blockchain/protocol/bc"
-)
-
-var (
-       // bigOne is 1 represented as a big.Int.  It is defined here to avoid
-       // the overhead of creating it multiple times.
-       bigOne = big.NewInt(1)
-
-       // oneLsh256 is 1 shifted left 256 bits.  It is defined here to avoid
-       // the overhead of creating it multiple times.
-       oneLsh256 = new(big.Int).Lsh(bigOne, 256)
-)
diff --git a/rpc/core/generate.go b/rpc/core/generate.go
deleted file mode 100644 (file)
index 62d7cad..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-package core
-
-import (
-       //"errors"
-       "math"
-       "math/big"
-       "runtime"
-       //"time"
-
-        //"github.com/blockchain/rpc/chainhash"
-         "github.com/bytom/rpc/wire"
-)
-
-func solveBlock(header *wire.BlockHeader, targetDifficulty *big.Int) bool {
-       // sbResult is used by the solver goroutines to send results.
-       type sbResult struct {
-               found bool
-               nonce uint32
-       }
-
-       // solver accepts a block header and a nonce range to test. It is
-       // intended to be run as a goroutine.
-       quit := make(chan bool)
-       results := make(chan sbResult)
-       solver := func(hdr wire.BlockHeader, startNonce, stopNonce uint32) {
-               // We need to modify the nonce field of the header, so make sure
-               // we work with a copy of the original header.
-               for i := startNonce; i >= startNonce && i <= stopNonce; i++ {
-                       select {
-                       case <-quit:
-                               return
-                       default:
-                               hdr.Nonce = i
-                               hash := hdr.BlockHash()
-                               if wire.HashToBig(&hash).Cmp(targetDifficulty) <= 0 {
-                                       results <- sbResult{true, i}
-                                       return
-                               }
-                       }
-               }
-               results <- sbResult{false, 0}
-       }
-
-       startNonce := uint32(1)
-       stopNonce := uint32(math.MaxUint32)
-       numCores := uint32(runtime.NumCPU())
-       noncesPerCore := (stopNonce - startNonce) / numCores
-       for i := uint32(0); i < numCores; i++ {
-               rangeStart := startNonce + (noncesPerCore * i)
-               rangeStop := startNonce + (noncesPerCore * (i + 1)) - 1
-               if i == numCores-1 {
-                       rangeStop = stopNonce
-               }
-               go solver(*header, rangeStart, rangeStop)
-       }
-       for i := uint32(0); i < numCores; i++ {
-               result := <-results
-               if result.found {
-                       close(quit)
-                       header.Nonce = result.nonce
-                       return true
-               }
-       }
-
-       return false
-}
-
-func checkProofOfWork(header *wire.BlockHeader, targetDifficulty *big.Int) bool {
-     hash := header.BlockHash()
-     if wire.HashToBig(&hash).Cmp(targetDifficulty) <= 0 {
-             return true
-     }
-     return false
-}
diff --git a/rpc/wire/blockheader.go b/rpc/wire/blockheader.go
deleted file mode 100755 (executable)
index 26393df..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-package wire
-
-import (
-        "bytes"
-        "io"
-        "time"
-
-        "github.com/bytom/rpc/chainhash"
-)
-
-// MaxBlockHeaderPayload is the maximum number of bytes a block header can be.
-// Version 4 bytes + Timestamp 4 bytes + Bits 4 bytes + Nonce 4 bytes +
-// PrevBlock and MerkleRoot hashes.
-const MaxBlockHeaderPayload = 16 + (chainhash.HashSize * 2)
-
-type uint32Time time.Time
-
-// BlockHeader defines information about a block and is used in the bitcoin
-// block (MsgBlock) and headers (MsgHeaders) messages.
-type BlockHeader struct {
-       // Version of the block.  This is not the same as the protocol version.
-       Version int32
-
-       // Hash of the previous block in the block chain.
-       PrevBlock chainhash.Hash
-
-       // Merkle tree reference to hash of all transactions for the block.
-       MerkleRoot chainhash.Hash
-
-       // Time the block was created.  This is, unfortunately, encoded as a
-       // uint32 on the wire and therefore is limited to 2106.
-       Timestamp time.Time
-
-       // Difficulty target for the block.
-       Bits uint32
-
-       // Nonce used to generate the block.
-       Nonce uint32
-}
-
-// blockHeaderLen is a constant that represents the number of bytes for a block
-// header.
-const blockHeaderLen = 80
-
-// BlockHash computes the block identifier hash for the given block header.
-func (h *BlockHeader) BlockHash() chainhash.Hash {
-       // Encode the header and double sha256 everything prior to the number of
-       // transactions.  Ignore the error returns since there is no way the
-       // encode could fail except being out of memory which would cause a
-       // run-time panic.
-       buf := bytes.NewBuffer(make([]byte, 0, MaxBlockHeaderPayload))
-       _ = writeBlockHeader(buf, 0, h)
-
-       return chainhash.DoubleHashH(buf.Bytes())
-}
-
-// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
-// This is part of the Message interface implementation.
-// See Deserialize for decoding block headers stored to disk, such as in a
-// database, as opposed to decoding block headers from the wire.
-func (h *BlockHeader) BtcDecode(r io.Reader, pver uint32) error {
-       return readBlockHeader(r, pver, h)
-}
-
-// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
-// This is part of the Message interface implementation.
-// See Serialize for encoding block headers to be stored to disk, such as in a
-// database, as opposed to encoding block headers for the wire.
-func (h *BlockHeader) BtcEncode(w io.Writer, pver uint32) error {
-       return writeBlockHeader(w, pver, h)
-}
-
-// Deserialize decodes a block header from r into the receiver using a format
-// that is suitable for long-term storage such as a database while respecting
-// the Version field.
-func (h *BlockHeader) Deserialize(r io.Reader) error {
-       // At the current time, there is no difference between the wire encoding
-       // at protocol version 0 and the stable long-term storage format.  As
-       // a result, make use of readBlockHeader.
-       return readBlockHeader(r, 0, h)
-}
-
-// Serialize encodes a block header from r into the receiver using a format
-// that is suitable for long-term storage such as a database while respecting
-// the Version field.
-func (h *BlockHeader) Serialize(w io.Writer) error {
-       // At the current time, there is no difference between the wire encoding
-       // at protocol version 0 and the stable long-term storage format.  As
-       // a result, make use of writeBlockHeader.
-       return writeBlockHeader(w, 0, h)
-}
-
-// NewBlockHeader returns a new BlockHeader using the provided version, previous
-// block hash, merkle root hash, difficulty bits, and nonce used to generate the
-// block with defaults for the remaining fields.
-func NewBlockHeader(version int32, prevHash, merkleRootHash *chainhash.Hash,
-       bits uint32, nonce uint32) *BlockHeader {
-
-       // Limit the timestamp to one second precision since the protocol
-       // doesn't support better.
-       return &BlockHeader{
-               Version:    version,
-               PrevBlock:  *prevHash,
-               MerkleRoot: *merkleRootHash,
-               Timestamp:  time.Unix(time.Now().Unix(), 0),
-               Bits:       bits,
-               Nonce:      nonce,
-       }
-}
-
-// readBlockHeader reads a bitcoin block header from r.  See Deserialize for
-// decoding block headers stored to disk, such as in a database, as opposed to
-// decoding from the wire.
-func readBlockHeader(r io.Reader, pver uint32, bh *BlockHeader) error {
-       return readElements(r, &bh.Version, &bh.PrevBlock, &bh.MerkleRoot,
-               (*uint32Time)(&bh.Timestamp), &bh.Bits, &bh.Nonce)
-}
-// writeBlockHeader writes a bitcoin block header to w.  See Serialize for
-// encoding block headers to be stored to disk, such as in a database, as
-// opposed to encoding for the wire.
-func writeBlockHeader(w io.Writer, pver uint32, bh *BlockHeader) error {
-       sec := uint32(bh.Timestamp.Unix())
-       return writeElements(w, bh.Version, &bh.PrevBlock, &bh.MerkleRoot,
-               sec, bh.Bits, bh.Nonce)
-}
-
-func writeElements(w io.Writer, elements ...interface{}) error {
- /*
-       for _, element := range elements {
-               err := writeElement(w, element)
-               if err != nil {
-                       return err
-               }
-       }
-*/
-       return nil
-}
-
-func readElements(r io.Reader, elements ...interface{}) error {
-/*
-       for _, element := range elements {
-               err := readElement(r, element)
-               if err != nil {
-                       return err
-               }
-       }
-*/
-       return nil
-}
diff --git a/rpc/wire/difficulty.go b/rpc/wire/difficulty.go
deleted file mode 100755 (executable)
index 40e8441..0000000
+++ /dev/null
@@ -1,343 +0,0 @@
-// Copyright (c) 2013-2017 The btcsuite developers\r
-// Use of this source code is governed by an ISC\r
-// license that can be found in the LICENSE file.\r
-\r
-package wire\r
-\r
-import (\r
-       "math/big"\r
-       //"time"\r
-\r
-       "github.com/bytom/rpc/chainhash"\r
-\r
-)\r
-\r
-var (\r
-       // bigOne is 1 represented as a big.Int.  It is defined here to avoid\r
-       // the overhead of creating it multiple times.\r
-       bigOne = big.NewInt(1)\r
-\r
-       // oneLsh256 is 1 shifted left 256 bits.  It is defined here to avoid\r
-       // the overhead of creating it multiple times.\r
-       oneLsh256 = new(big.Int).Lsh(bigOne, 256)\r
-)\r
-\r
-// HashToBig converts a chainhash.Hash into a big.Int that can be used to\r
-// perform math comparisons.\r
-func HashToBig(hash *chainhash.Hash) *big.Int {\r
-       // A Hash is in little-endian, but the big package wants the bytes in\r
-       // big-endian, so reverse them.\r
-       buf := *hash\r
-       blen := len(buf)\r
-       for i := 0; i < blen/2; i++ {\r
-               buf[i], buf[blen-1-i] = buf[blen-1-i], buf[i]\r
-       }\r
-\r
-       return new(big.Int).SetBytes(buf[:])\r
-}\r
-/*\r
-// CompactToBig converts a compact representation of a whole number N to an\r
-// unsigned 32-bit number.  The representation is similar to IEEE754 floating\r
-// point numbers.\r
-//\r
-// Like IEEE754 floating point, there are three basic components: the sign,\r
-// the exponent, and the mantissa.  They are broken out as follows:\r
-//\r
-//     * the most significant 8 bits represent the unsigned base 256 exponent\r
-//     * bit 23 (the 24th bit) represents the sign bit\r
-//     * the least significant 23 bits represent the mantissa\r
-//\r
-//     -------------------------------------------------\r
-//     |   Exponent     |    Sign    |    Mantissa     |\r
-//     -------------------------------------------------\r
-//     | 8 bits [31-24] | 1 bit [23] | 23 bits [22-00] |\r
-//     -------------------------------------------------\r
-//\r
-// The formula to calculate N is:\r
-//     N = (-1^sign) * mantissa * 256^(exponent-3)\r
-//\r
-// This compact form is only used in bitcoin to encode unsigned 256-bit numbers\r
-// which represent difficulty targets, thus there really is not a need for a\r
-// sign bit, but it is implemented here to stay consistent with bitcoind.\r
-func CompactToBig(compact uint32) *big.Int {\r
-       // Extract the mantissa, sign bit, and exponent.\r
-       mantissa := compact & 0x007fffff\r
-       isNegative := compact&0x00800000 != 0\r
-       exponent := uint(compact >> 24)\r
-\r
-       // Since the base for the exponent is 256, the exponent can be treated\r
-       // as the number of bytes to represent the full 256-bit number.  So,\r
-       // treat the exponent as the number of bytes and shift the mantissa\r
-       // right or left accordingly.  This is equivalent to:\r
-       // N = mantissa * 256^(exponent-3)\r
-       var bn *big.Int\r
-       if exponent <= 3 {\r
-               mantissa >>= 8 * (3 - exponent)\r
-               bn = big.NewInt(int64(mantissa))\r
-       } else {\r
-               bn = big.NewInt(int64(mantissa))\r
-               bn.Lsh(bn, 8*(exponent-3))\r
-       }\r
-\r
-       // Make it negative if the sign bit is set.\r
-       if isNegative {\r
-               bn = bn.Neg(bn)\r
-       }\r
-\r
-       return bn\r
-}\r
-\r
-// BigToCompact converts a whole number N to a compact representation using\r
-// an unsigned 32-bit number.  The compact representation only provides 23 bits\r
-// of precision, so values larger than (2^23 - 1) only encode the most\r
-// significant digits of the number.  See CompactToBig for details.\r
-func BigToCompact(n *big.Int) uint32 {\r
-       // No need to do any work if it's zero.\r
-       if n.Sign() == 0 {\r
-               return 0\r
-       }\r
-\r
-       // Since the base for the exponent is 256, the exponent can be treated\r
-       // as the number of bytes.  So, shift the number right or left\r
-       // accordingly.  This is equivalent to:\r
-       // mantissa = mantissa / 256^(exponent-3)\r
-       var mantissa uint32\r
-       exponent := uint(len(n.Bytes()))\r
-       if exponent <= 3 {\r
-               mantissa = uint32(n.Bits()[0])\r
-               mantissa <<= 8 * (3 - exponent)\r
-       } else {\r
-               // Use a copy to avoid modifying the caller's original number.\r
-               tn := new(big.Int).Set(n)\r
-               mantissa = uint32(tn.Rsh(tn, 8*(exponent-3)).Bits()[0])\r
-       }\r
-\r
-       // When the mantissa already has the sign bit set, the number is too\r
-       // large to fit into the available 23-bits, so divide the number by 256\r
-       // and increment the exponent accordingly.\r
-       if mantissa&0x00800000 != 0 {\r
-               mantissa >>= 8\r
-               exponent++\r
-       }\r
-\r
-       // Pack the exponent, sign bit, and mantissa into an unsigned 32-bit\r
-       // int and return it.\r
-       compact := uint32(exponent<<24) | mantissa\r
-       if n.Sign() < 0 {\r
-               compact |= 0x00800000\r
-       }\r
-       return compact\r
-}\r
-\r
-// CalcWork calculates a work value from difficulty bits.  Bitcoin increases\r
-// the difficulty for generating a block by decreasing the value which the\r
-// generated hash must be less than.  This difficulty target is stored in each\r
-// block header using a compact representation as described in the documentation\r
-// for CompactToBig.  The main chain is selected by choosing the chain that has\r
-// the most proof of work (highest difficulty).  Since a lower target difficulty\r
-// value equates to higher actual difficulty, the work value which will be\r
-// accumulated must be the inverse of the difficulty.  Also, in order to avoid\r
-// potential division by zero and really small floating point numbers, the\r
-// result adds 1 to the denominator and multiplies the numerator by 2^256.\r
-func CalcWork(bits uint32) *big.Int {\r
-       // Return a work value of zero if the passed difficulty bits represent\r
-       // a negative number. Note this should not happen in practice with valid\r
-       // blocks, but an invalid block could trigger it.\r
-       difficultyNum := CompactToBig(bits)\r
-       if difficultyNum.Sign() <= 0 {\r
-               return big.NewInt(0)\r
-       }\r
-\r
-       // (1 << 256) / (difficultyNum + 1)\r
-       denominator := new(big.Int).Add(difficultyNum, bigOne)\r
-       return new(big.Int).Div(oneLsh256, denominator)\r
-}\r
-\r
-// calcEasiestDifficulty calculates the easiest possible difficulty that a block\r
-// can have given starting difficulty bits and a duration.  It is mainly used to\r
-// verify that claimed proof of work by a block is sane as compared to a\r
-// known good checkpoint.\r
-func (b *BlockChain) calcEasiestDifficulty(bits uint32, duration time.Duration) uint32 {\r
-       // Convert types used in the calculations below.\r
-       durationVal := int64(duration / time.Second)\r
-       adjustmentFactor := big.NewInt(b.chainParams.RetargetAdjustmentFactor)\r
-\r
-       // The test network rules allow minimum difficulty blocks after more\r
-       // than twice the desired amount of time needed to generate a block has\r
-       // elapsed.\r
-       if b.chainParams.ReduceMinDifficulty {\r
-               reductionTime := int64(b.chainParams.MinDiffReductionTime /\r
-                       time.Second)\r
-               if durationVal > reductionTime {\r
-                       return b.chainParams.PowLimitBits\r
-               }\r
-       }\r
-\r
-       // Since easier difficulty equates to higher numbers, the easiest\r
-       // difficulty for a given duration is the largest value possible given\r
-       // the number of retargets for the duration and starting difficulty\r
-       // multiplied by the max adjustment factor.\r
-       newTarget := CompactToBig(bits)\r
-       for durationVal > 0 && newTarget.Cmp(b.chainParams.PowLimit) < 0 {\r
-               newTarget.Mul(newTarget, adjustmentFactor)\r
-               durationVal -= b.maxRetargetTimespan\r
-       }\r
-\r
-       // Limit new value to the proof of work limit.\r
-       if newTarget.Cmp(b.chainParams.PowLimit) > 0 {\r
-               newTarget.Set(b.chainParams.PowLimit)\r
-       }\r
-\r
-       return BigToCompact(newTarget)\r
-}\r
-\r
-// findPrevTestNetDifficulty returns the difficulty of the previous block which\r
-// did not have the special testnet minimum difficulty rule applied.\r
-//\r
-// This function MUST be called with the chain state lock held (for writes).\r
-func (b *BlockChain) findPrevTestNetDifficulty(startNode *blockNode) (uint32, error) {\r
-       // Search backwards through the chain for the last block without\r
-       // the special rule applied.\r
-       iterNode := startNode\r
-       for iterNode != nil && iterNode.height%b.blocksPerRetarget != 0 &&\r
-               iterNode.bits == b.chainParams.PowLimitBits {\r
-\r
-               // Get the previous block node.  This function is used over\r
-               // simply accessing iterNode.parent directly as it will\r
-               // dynamically create previous block nodes as needed.  This\r
-               // helps allow only the pieces of the chain that are needed\r
-               // to remain in memory.\r
-               var err error\r
-               iterNode, err = b.index.PrevNodeFromNode(iterNode)\r
-               if err != nil {\r
-                       log.Errorf("PrevNodeFromNode: %v", err)\r
-                       return 0, err\r
-               }\r
-       }\r
-\r
-       // Return the found difficulty or the minimum difficulty if no\r
-       // appropriate block was found.\r
-       lastBits := b.chainParams.PowLimitBits\r
-       if iterNode != nil {\r
-               lastBits = iterNode.bits\r
-       }\r
-       return lastBits, nil\r
-}\r
-\r
-// calcNextRequiredDifficulty calculates the required difficulty for the block\r
-// after the passed previous block node based on the difficulty retarget rules.\r
-// This function differs from the exported CalcNextRequiredDifficulty in that\r
-// the exported version uses the current best chain as the previous block node\r
-// while this function accepts any block node.\r
-//\r
-// This function MUST be called with the chain state lock held (for writes).\r
-func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, newBlockTime time.Time) (uint32, error) {\r
-       // Genesis block.\r
-       if lastNode == nil {\r
-               return b.chainParams.PowLimitBits, nil\r
-       }\r
-\r
-       // Return the previous block's difficulty requirements if this block\r
-       // is not at a difficulty retarget interval.\r
-       if (lastNode.height+1)%b.blocksPerRetarget != 0 {\r
-               // For networks that support it, allow special reduction of the\r
-               // required difficulty once too much time has elapsed without\r
-               // mining a block.\r
-               if b.chainParams.ReduceMinDifficulty {\r
-                       // Return minimum difficulty when more than the desired\r
-                       // amount of time has elapsed without mining a block.\r
-                       reductionTime := int64(b.chainParams.MinDiffReductionTime /\r
-                               time.Second)\r
-                       allowMinTime := lastNode.timestamp + reductionTime\r
-                       if newBlockTime.Unix() > allowMinTime {\r
-                               return b.chainParams.PowLimitBits, nil\r
-                       }\r
-\r
-                       // The block was mined within the desired timeframe, so\r
-                       // return the difficulty for the last block which did\r
-                       // not have the special minimum difficulty rule applied.\r
-                       prevBits, err := b.findPrevTestNetDifficulty(lastNode)\r
-                       if err != nil {\r
-                               return 0, err\r
-                       }\r
-                       return prevBits, nil\r
-               }\r
-\r
-               // For the main network (or any unrecognized networks), simply\r
-               // return the previous block's difficulty requirements.\r
-               return lastNode.bits, nil\r
-       }\r
-\r
-       // Get the block node at the previous retarget (targetTimespan days\r
-       // worth of blocks).\r
-       firstNode := lastNode\r
-       for i := int32(0); i < b.blocksPerRetarget-1 && firstNode != nil; i++ {\r
-               // Get the previous block node.  This function is used over\r
-               // simply accessing firstNode.parent directly as it will\r
-               // dynamically create previous block nodes as needed.  This\r
-               // helps allow only the pieces of the chain that are needed\r
-               // to remain in memory.\r
-               var err error\r
-               firstNode, err = b.index.PrevNodeFromNode(firstNode)\r
-               if err != nil {\r
-                       return 0, err\r
-               }\r
-       }\r
-\r
-       if firstNode == nil {\r
-               return 0, AssertError("unable to obtain previous retarget block")\r
-       }\r
-\r
-       // Limit the amount of adjustment that can occur to the previous\r
-       // difficulty.\r
-       actualTimespan := lastNode.timestamp - firstNode.timestamp\r
-       adjustedTimespan := actualTimespan\r
-       if actualTimespan < b.minRetargetTimespan {\r
-               adjustedTimespan = b.minRetargetTimespan\r
-       } else if actualTimespan > b.maxRetargetTimespan {\r
-               adjustedTimespan = b.maxRetargetTimespan\r
-       }\r
-\r
-       // Calculate new target difficulty as:\r
-       //  currentDifficulty * (adjustedTimespan / targetTimespan)\r
-       // The result uses integer division which means it will be slightly\r
-       // rounded down.  Bitcoind also uses integer division to calculate this\r
-       // result.\r
-       oldTarget := CompactToBig(lastNode.bits)\r
-       newTarget := new(big.Int).Mul(oldTarget, big.NewInt(adjustedTimespan))\r
-       targetTimeSpan := int64(b.chainParams.TargetTimespan / time.Second)\r
-       newTarget.Div(newTarget, big.NewInt(targetTimeSpan))\r
-\r
-       // Limit new value to the proof of work limit.\r
-       if newTarget.Cmp(b.chainParams.PowLimit) > 0 {\r
-               newTarget.Set(b.chainParams.PowLimit)\r
-       }\r
-\r
-       // Log new target difficulty and return it.  The new target logging is\r
-       // intentionally converting the bits back to a number instead of using\r
-       // newTarget since conversion to the compact representation loses\r
-       // precision.\r
-       newTargetBits := BigToCompact(newTarget)\r
-       log.Debugf("Difficulty retarget at block height %d", lastNode.height+1)\r
-       log.Debugf("Old target %08x (%064x)", lastNode.bits, oldTarget)\r
-       log.Debugf("New target %08x (%064x)", newTargetBits, CompactToBig(newTargetBits))\r
-       log.Debugf("Actual timespan %v, adjusted timespan %v, target timespan %v",\r
-               time.Duration(actualTimespan)*time.Second,\r
-               time.Duration(adjustedTimespan)*time.Second,\r
-               b.chainParams.TargetTimespan)\r
-\r
-       return newTargetBits, nil\r
-}\r
-\r
-// CalcNextRequiredDifficulty calculates the required difficulty for the block\r
-// after the end of the current best chain based on the difficulty retarget\r
-// rules.\r
-//\r
-// This function is safe for concurrent access.\r
-func (b *BlockChain) CalcNextRequiredDifficulty(timestamp time.Time) (uint32, error) {\r
-       b.chainLock.Lock()\r
-       difficulty, err := b.calcNextRequiredDifficulty(b.bestNode, timestamp)\r
-       b.chainLock.Unlock()\r
-       return difficulty, err\r
-}\r
-*/\r