@go test -bench $(PACKAGES)
functional-tests:
- @go test -v -timeout=5m -tags="functional" ./test
+ @go test -timeout=5m -tags="functional" ./test
ci: test functional-tests
contractIndexPrefix = []byte("ContractIndex")
contractPrefix = []byte("Contract:")
miningAddressKey = []byte("MiningAddress")
+ CoinbaseAbKey = []byte("CoinbaseArbitrary")
)
// pre-define errors for supporting bytom errorFormatter
return account.Alias
}
+func (m *Manager) GetCoinbaseArbitrary() []byte {
+ if arbitrary := m.db.Get(CoinbaseAbKey); arbitrary != nil {
+ return arbitrary
+ }
+ return []byte{}
+}
+
// GetCoinbaseControlProgram will return a coinbase script
func (m *Manager) GetCoinbaseControlProgram() ([]byte, error) {
cp, err := m.GetCoinbaseCtrlProgram()
return m.GetMiningAddress()
}
+func (m *Manager) SetCoinbaseArbitrary(arbitrary []byte) {
+ m.db.Set(CoinbaseAbKey, arbitrary)
+}
+
// CreateAddress generate an address for the select account
func (m *Manager) createAddress(account *Account, change bool) (cp *CtrlProgram, err error) {
if len(account.XPubs) == 1 {
m.Handle("/submit-work", jsonHandler(a.submitWork))
m.Handle("/submit-work-json", jsonHandler(a.submitWorkJSON))
+ m.Handle("/get-coinbase-arbitrary", jsonHandler(a.getCoinbaseArbitrary))
+ m.Handle("/set-coinbase-arbitrary", jsonHandler(a.setCoinbaseArbitrary))
+
m.Handle("/verify-message", jsonHandler(a.verifyMessage))
m.Handle("/decode-program", jsonHandler(a.decodeProgram))
m.Handle("/compile", jsonHandler(a.compileEquity))
"github.com/bytom/blockchain/query"
"github.com/bytom/consensus/difficulty"
chainjson "github.com/bytom/encoding/json"
+ "github.com/bytom/errors"
"github.com/bytom/protocol/bc"
"github.com/bytom/protocol/bc/types"
)
Transactions []*BlockTx `json:"transactions"`
}
-// return block by hash
+// return block by hash/height
func (a *API) getBlock(ins BlockReq) Response {
- var err error
- block := &types.Block{}
- if len(ins.BlockHash) == 32 {
- b32 := [32]byte{}
- copy(b32[:], ins.BlockHash)
- hash := bc.NewHash(b32)
- block, err = a.chain.GetBlockByHash(&hash)
- } else {
- block, err = a.chain.GetBlockByHeight(ins.BlockHeight)
- }
+ block, err := a.getBlockHelper(ins)
if err != nil {
return NewErrorResponse(err)
}
}
func (a *API) getBlockHeader(ins BlockReq) Response {
- var err error
- block := &types.Block{}
- if len(ins.BlockHash) == 32 {
- b32 := [32]byte{}
- copy(b32[:], ins.BlockHash)
- hash := bc.NewHash(b32)
- block, err = a.chain.GetBlockByHash(&hash)
- } else {
- block, err = a.chain.GetBlockByHeight(ins.BlockHeight)
- }
+ block, err := a.getBlockHelper(ins)
if err != nil {
return NewErrorResponse(err)
}
return NewSuccessResponse(resp)
}
+func (a *API) getBlockHelper(ins BlockReq) (*types.Block, error) {
+ if len(ins.BlockHash) == 32 {
+ b32 := [32]byte{}
+ copy(b32[:], ins.BlockHash)
+ hash := bc.NewHash(b32)
+ return a.chain.GetBlockByHash(&hash)
+ } else {
+ return a.chain.GetBlockByHeight(ins.BlockHeight)
+ }
+}
+
// GetDifficultyResp is resp struct for getDifficulty API
type GetDifficultyResp struct {
BlockHash *bc.Hash `json:"hash"`
Difficulty string `json:"difficulty"`
}
-func (a *API) getDifficulty(ins *BlockReq) Response {
- var err error
- block := &types.Block{}
-
- if len(ins.BlockHash) == 32 && ins.BlockHash != nil {
- b32 := [32]byte{}
- copy(b32[:], ins.BlockHash)
- hash := bc.NewHash(b32)
- block, err = a.chain.GetBlockByHash(&hash)
- } else if ins.BlockHeight > 0 {
- block, err = a.chain.GetBlockByHeight(ins.BlockHeight)
- } else {
- hash := a.chain.BestBlockHash()
- block, err = a.chain.GetBlockByHash(hash)
- }
-
+func (a *API) getDifficulty(ins BlockReq) Response {
+ block, err := a.getBlockHelper(ins)
if err != nil {
return NewErrorResponse(err)
}
}
func (a *API) getHashRate(ins BlockReq) Response {
- var err error
- block := &types.Block{}
-
- if len(ins.BlockHash) == 32 && ins.BlockHash != nil {
- b32 := [32]byte{}
- copy(b32[:], ins.BlockHash)
- hash := bc.NewHash(b32)
- block, err = a.chain.GetBlockByHash(&hash)
- } else if ins.BlockHeight > 0 {
- block, err = a.chain.GetBlockByHeight(ins.BlockHeight)
- } else {
- hash := a.chain.BestBlockHash()
- block, err = a.chain.GetBlockByHash(hash)
+ if len(ins.BlockHash) != 32 && ins.BlockHeight == 0 {
+ err := errors.New("Request format error.")
+ return NewErrorResponse(err)
}
+ block, err := a.getBlockHelper(ins)
if err != nil {
return NewErrorResponse(err)
}
import (
"context"
+ chainjson "github.com/bytom/encoding/json"
"github.com/bytom/errors"
"github.com/bytom/protocol/bc"
"github.com/bytom/protocol/bc/types"
BlockCommitment *types.BlockCommitment `json:"block_commitment"` //Block commitment
}
+type CoinbaseArbitrary struct {
+ Arbitrary chainjson.HexBytes `json:"arbitrary"`
+}
+
+func (a *API) getCoinbaseArbitrary() Response {
+ arbitrary := a.wallet.AccountMgr.GetCoinbaseArbitrary()
+ resp := &CoinbaseArbitrary{
+ Arbitrary: arbitrary,
+ }
+ return NewSuccessResponse(resp)
+}
+
+func (a *API) setCoinbaseArbitrary(ctx context.Context, req CoinbaseArbitrary) Response {
+ a.wallet.AccountMgr.SetCoinbaseArbitrary(req.Arbitrary)
+ return a.getCoinbaseArbitrary()
+}
+
// getWork gets work in compressed protobuf format
func (a *API) getWork() Response {
work, err := a.GetWork()
// Get the start and end of the page.
func getPageRange(size int, from uint, count uint) (uint, uint) {
- total := uint(size)
+ total := uint(size)
if from == 0 && count == 0 {
return 0, total
}
start := from
end := from + count
- if start > total {start = total}
- if end > total {end = total}
+ if start > total {
+ start = total
+ }
+ if end > total {
+ end = total
+ }
return start, end
-}
\ No newline at end of file
+}
// a concurrency-safe manner.
type CPUMiner struct {
sync.Mutex
- chain *protocol.Chain
- accountManager *account.Manager
- txPool *protocol.TxPool
- numWorkers uint64
- started bool
- discreteMining bool
- workerWg sync.WaitGroup
- updateNumWorkers chan struct{}
- quit chan struct{}
- newBlockCh chan *bc.Hash
+ chain *protocol.Chain
+ accountManager *account.Manager
+ txPool *protocol.TxPool
+ numWorkers uint64
+ started bool
+ discreteMining bool
+ workerWg sync.WaitGroup
+ updateNumWorkers chan struct{}
+ quit chan struct{}
+ newBlockCh chan *bc.Hash
}
// solveBlock attempts to find some combination of a nonce, extra nonce, and
// type for more details.
func NewCPUMiner(c *protocol.Chain, accountManager *account.Manager, txPool *protocol.TxPool, newBlockCh chan *bc.Hash) *CPUMiner {
return &CPUMiner{
- chain: c,
- accountManager: accountManager,
- txPool: txPool,
- numWorkers: defaultNumWorkers,
- updateNumWorkers: make(chan struct{}),
- newBlockCh: newBlockCh,
+ chain: c,
+ accountManager: accountManager,
+ txPool: txPool,
+ numWorkers: defaultNumWorkers,
+ updateNumWorkers: make(chan struct{}),
+ newBlockCh: newBlockCh,
}
}
-// 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 (
// 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) {
amount += consensus.BlockSubsidy(blockHeight)
+ arbitrary := append([]byte{0x00}, []byte(strconv.FormatUint(blockHeight, 10))...)
var script []byte
if accountManager == nil {
script, err = vmutil.DefaultCoinbaseProgram()
} else {
script, err = accountManager.GetCoinbaseControlProgram()
+ arbitrary = append(arbitrary, accountManager.GetCoinbaseArbitrary()...)
}
if err != nil {
- return
+ return nil, err
+ }
+
+ if len(arbitrary) > consensus.CoinbaseArbitrarySizeLimit {
+ return nil, validation.ErrCoinbaseArbitraryOversize
}
builder := txbuilder.NewBuilder(time.Now())
- if err = builder.AddInput(types.NewCoinbaseInput(
- append([]byte{0x00}, []byte(strconv.FormatUint(blockHeight, 10))...),
- ), &txbuilder.SigningInstruction{}); err != nil {
- return
+ 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
+ return nil, err
}
_, txData, err := builder.Build()
if err != nil {
- return
+ return nil, err
}
byteData, err := txData.MarshalText()
if err != nil {
- return
+ return nil, err
}
txData.SerializedSize = uint64(len(byteData))
TxData: *txData,
Tx: types.MapTx(txData),
}
- return
+ return tx, nil
}
// NewBlockTemplate returns a new block template that is ready to be solved
package types
-// CoinbaseInput is record the coinbase message
+// CoinbaseInput records the coinbase message
type CoinbaseInput struct {
Arbitrary []byte
}
-// NewCoinbaseInput create a new coinbase input struct
+// NewCoinbaseInput creates a new coinbase input struct
func NewCoinbaseInput(arbitrary []byte) *TxInput {
return &TxInput{
AssetVersion: 1,