X-Git-Url: http://git.osdn.net/view?p=bytom%2Fvapor.git;a=blobdiff_plain;f=mining%2Fmining.go;h=ead4501619e5c83a403e5cea385ea30350e17f9c;hp=e2a6e6711aca99b6e9e3441f1deac27b2f8cd2e7;hb=ee01d543fdfe1fd0a4d548965c66f7923ea7b062;hpb=b3065dfd76cff7942569ae0d4f3507b5437dfa70 diff --git a/mining/mining.go b/mining/mining.go index e2a6e671..ead45016 100644 --- a/mining/mining.go +++ b/mining/mining.go @@ -1,10 +1,14 @@ package mining import ( + "encoding/binary" + "encoding/json" "sort" "strconv" "time" + "github.com/vapor/protocol/vm" + "github.com/vapor/common" log "github.com/sirupsen/logrus" @@ -14,6 +18,7 @@ import ( "github.com/vapor/config" "github.com/vapor/consensus" engine "github.com/vapor/consensus/consensus" + dpos "github.com/vapor/consensus/consensus/dpos" "github.com/vapor/crypto/ed25519/chainkd" "github.com/vapor/errors" "github.com/vapor/protocol" @@ -27,12 +32,12 @@ import ( // 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(accountManager *account.Manager, amount uint64, blockHeight uint64) (tx *types.Tx, err error) { +func createCoinbaseTx(accountManager *account.Manager, amount uint64, blockHeight uint64, delegateInfo interface{}, timestamp uint64) (tx *types.Tx, err error) { //amount += consensus.BlockSubsidy(blockHeight) arbitrary := append([]byte{0x00}, []byte(strconv.FormatUint(blockHeight, 10))...) var script []byte - address, _ := common.DecodeAddress(config.CommonConfig.Consensus.Dpos.Coinbase, &consensus.ActiveNetParams) + address, _ := common.DecodeAddress(config.CommonConfig.Consensus.Coinbase, &consensus.ActiveNetParams) redeemContract := address.ScriptAddress() script, _ = vmutil.P2WPKHProgram(redeemContract) @@ -48,6 +53,7 @@ func createCoinbaseTx(accountManager *account.Manager, amount uint64, blockHeigh if err = builder.AddInput(types.NewCoinbaseInput(arbitrary), &txbuilder.SigningInstruction{}); err != nil { return nil, err } + if err = builder.AddOutput(types.NewTxOutput(*consensus.BTMAssetID, amount, script)); err != nil { return nil, err } @@ -56,6 +62,39 @@ func createCoinbaseTx(accountManager *account.Manager, amount uint64, blockHeigh return nil, err } + delegates := dpos.DelegateInfoList{} + if delegateInfo != nil { + tmp := delegateInfo.(*dpos.DelegateInfo) + delegates.Delegate = *tmp + } + + var xPrv chainkd.XPrv + if config.CommonConfig.Consensus.XPrv == "" { + return nil, errors.New("Signer is empty") + } + xPrv.UnmarshalText([]byte(config.CommonConfig.Consensus.XPrv)) + + buf := [8]byte{} + binary.LittleEndian.PutUint64(buf[:], timestamp) + delegates.SigTime = xPrv.Sign(buf[:]) + delegates.Xpub = xPrv.XPub() + + data, err := json.Marshal(&delegates) + if err != nil { + return nil, err + } + + msg := dpos.DposMsg{ + Type: vm.OP_DELEGATE, + Data: data, + } + + data, err = json.Marshal(&msg) + if err != nil { + return nil, err + } + txData.ReferenceData = data + byteData, err := txData.MarshalText() if err != nil { return nil, err @@ -70,7 +109,7 @@ func createCoinbaseTx(accountManager *account.Manager, amount uint64, blockHeigh } // NewBlockTemplate returns a new block template that is ready to be solved -func NewBlockTemplate(c *protocol.Chain, txPool *protocol.TxPool, accountManager *account.Manager, engine engine.Engine) (b *types.Block, err error) { +func NewBlockTemplate(c *protocol.Chain, txPool *protocol.TxPool, accountManager *account.Manager, engine engine.Engine, delegateInfo interface{}, blockTime uint64) (b *types.Block, err error) { view := state.NewUtxoViewpoint() txStatus := bc.NewTransactionStatus() if err := txStatus.SetStatus(0, false); err != nil { @@ -85,25 +124,12 @@ func NewBlockTemplate(c *protocol.Chain, txPool *protocol.TxPool, accountManager preBlockHash := preBlockHeader.Hash() nextBlockHeight := preBlockHeader.Height + 1 - var xPrv chainkd.XPrv - if config.CommonConfig.Consensus.Dpos.XPrv == "" { - return nil, errors.New("Signer is empty") - } - xPrv.UnmarshalText([]byte(config.CommonConfig.Consensus.Dpos.XPrv)) - xpub, _ := xPrv.XPub().MarshalText() - header := types.BlockHeader{ Version: 1, Height: nextBlockHeight, PreviousBlockHash: preBlockHash, - Timestamp: uint64(time.Now().Unix()), + Timestamp: blockTime, BlockCommitment: types.BlockCommitment{}, - Coinbase: xpub, - } - - if err := engine.Prepare(c, &header); err != nil { - log.Error("Failed to prepare header for mining", "err", err) - return nil, err } b = &types.Block{} @@ -151,13 +177,9 @@ func NewBlockTemplate(c *protocol.Chain, txPool *protocol.TxPool, accountManager } } - if err := engine.Finalize(c, &header, txEntries[1:]); err != nil { - return nil, err - } - b.BlockHeader = header // creater coinbase transaction - b.Transactions[0], err = createCoinbaseTx(accountManager, txFee, nextBlockHeight) + b.Transactions[0], err = createCoinbaseTx(accountManager, txFee, nextBlockHeight, delegateInfo, b.Timestamp) if err != nil { return nil, errors.Wrap(err, "fail on createCoinbaseTx") }