{1000, bc.NewHash([32]byte{0x28, 0x29, 0xc9, 0xe2, 0x19, 0x0f, 0xfe, 0xb6, 0xf2, 0x73, 0xde, 0x1a, 0xe8, 0x1f, 0xa6, 0xbc, 0x15, 0xaa, 0x08, 0xa9, 0xb8, 0x4c, 0x43, 0x25, 0x9a, 0xa0, 0x24, 0x8a, 0xd8, 0x55, 0x73, 0xca})},
{1500, bc.NewHash([32]byte{0xc2, 0x94, 0x02, 0xd1, 0x6c, 0xa8, 0x18, 0xc4, 0x95, 0x67, 0x48, 0xb8, 0xa8, 0x42, 0xa2, 0x69, 0x8e, 0xdd, 0xb2, 0xa9, 0xb6, 0xd9, 0x30, 0xf4, 0x12, 0xdb, 0x0f, 0x1e, 0x58, 0xc9, 0x69, 0x3b})},
{10303, bc.NewHash([32]byte{0x3e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c})},
+ {21920, bc.NewHash([32]byte{0x3c, 0x5f, 0xb2, 0x7d, 0xb9, 0x97, 0xfe, 0x6f, 0xfa, 0x85, 0x4a, 0xfc, 0x2f, 0x01, 0x63, 0x8b, 0x5e, 0xbb, 0xcf, 0x2e, 0x41, 0x89, 0x88, 0xf7, 0x0d, 0xf0, 0xfe, 0xdd, 0x4d, 0x68, 0x4e, 0x13})},
},
}
)
const (
- syncCycle = 5 * time.Second
- blockProcessChSize = 1024
- blocksProcessChSize = 128
- headersProcessChSize = 1024
+ syncCycle = 5 * time.Second
+ blockProcessChSize = 1024
+ blocksProcessChSize = 128
+ headersProcessChSize = 1024
+ merkleBlocksProcessChSize = 128
)
var (
func newBlockKeeper(chain Chain, peers *peerSet) *blockKeeper {
bk := &blockKeeper{
- chain: chain,
- peers: peers,
- blockProcessCh: make(chan *blockMsg, blockProcessChSize),
- blocksProcessCh: make(chan *blocksMsg, blocksProcessChSize),
- headersProcessCh: make(chan *headersMsg, headersProcessChSize),
- headerList: list.New(),
+ chain: chain,
+ peers: peers,
+ blockProcessCh: make(chan *blockMsg, blockProcessChSize),
+ blocksProcessCh: make(chan *blocksMsg, blocksProcessChSize),
+ headersProcessCh: make(chan *headersMsg, headersProcessChSize),
+ merkleBlockProcessCh: make(chan *merkleBlockMsg, merkleBlocksProcessChSize),
+
+ headerList: list.New(),
}
bk.resetHeaderState()
go bk.syncWorker()
}
fastHeader := bk.headerList.Front()
- for bk.chain.BestBlockHeight() < checkPoint.Height {
+ for bk.chain.BestBlockHeight() <= checkPoint.Height {
hash := fastHeader.Value.(*types.BlockHeader).Hash()
merkleBlock, err := bk.requireMerkleBlock(fastHeader.Value.(*types.BlockHeader).Height, &hash)
if err != nil {
}
bk.VerifyMerkleBlock(fastHeader.Value.(*types.BlockHeader), merkleBlock)
blockHash := merkleBlock.Hash()
- //if blockHash != fastHeader.Value.(*types.BlockHeader).Hash() {
- // return errPeerMisbehave
- //}
+ if blockHash != fastHeader.Value.(*types.BlockHeader).Hash() {
+ return errPeerMisbehave
+ }
seed, err := bk.chain.CalcNextSeed(&merkleBlock.PreviousBlockHash)
if err != nil {
return errors.Wrap(err, "fail on fastBlockSync calculate seed")
if err != nil {
return errors.Wrap(err, "fail on fastBlockSync process block")
}
+ if fastHeader = fastHeader.Next(); fastHeader == nil {
+ return nil
+ }
}
- //locator := bk.blockLocator()
- //blocks, err := bk.requireBlocks(locator, &checkPoint.Hash)
- //if err != nil {
- // return err
- //}
- //
- //if len(blocks) == 0 {
- // return errors.Wrap(errPeerMisbehave, "requireBlocks return empty list")
- //}
- // for ;fastHeader = fastHeader.Next(); fastHeader == nil {
- // blocks, err := bk.requireMerkleBlock(fastHeader.Value.(*types.BlockHeader).Height, fastHeader.Value.(*types.BlockHeader).Hash())
- // if err != nil {
- // return err
- //}
-
- //}
- //for _, block := range blocks {
- // if fastHeader = fastHeader.Next(); fastHeader == nil {
- // return errors.New("get block than is higher than checkpoint")
- // }
- //
- // blockHash := block.Hash()
- // if blockHash != fastHeader.Value.(*types.BlockHeader).Hash() {
- // return errPeerMisbehave
- // }
- //
- // seed, err := bk.chain.CalcNextSeed(&block.PreviousBlockHash)
- // if err != nil {
- // return errors.Wrap(err, "fail on fastBlockSync calculate seed")
- // }
- //
- // tensority.AIHash.AddCache(&blockHash, seed, &bc.Hash{})
- // _, err = bk.chain.ProcessBlock(block)
- // tensority.AIHash.RemoveCache(&blockHash, seed)
- // if err != nil {
- // return errors.Wrap(err, "fail on fastBlockSync process block")
- // }
- //}
- //}
return nil
}
NewTransactionByte = byte(0x30)
NewMineBlockByte = byte(0x40)
FilterLoadByte = byte(0x50)
- FilterClearByte = byte(0x51)
- FilterAddByte = byte(0x52)
+ FilterAddByte = byte(0x51)
+ FilterClearByte = byte(0x52)
MerkleRequestByte = byte(0x60)
MerkleResponseByte = byte(0x61)
wire.ConcreteType{&TransactionMessage{}, NewTransactionByte},
wire.ConcreteType{&MineBlockMessage{}, NewMineBlockByte},
wire.ConcreteType{&FilterLoadMessage{}, FilterLoadByte},
- wire.ConcreteType{&FilterClearMessage{}, FilterClearByte},
wire.ConcreteType{&FilterAddMessage{}, FilterAddByte},
+ wire.ConcreteType{&FilterClearMessage{}, FilterClearByte},
wire.ConcreteType{&GetMerkleBlockMessage{}, MerkleRequestByte},
wire.ConcreteType{&MerkleBlockMessage{}, MerkleResponseByte},
)
//FilterLoadMessage new load addresses msg
type FilterAddMessage struct {
- Addresse []byte
+ Address []byte
}
//NewMinedBlockMessage construct new mined block msg
func NewFilterAddMessage(addresse []byte) (*FilterAddMessage, error) {
- return &FilterAddMessage{Addresse: addresse}, nil
+ return &FilterAddMessage{Address: addresse}, nil
}
//FilterClearMessage tells the receiving peer to remove a previously-set filter.
"github.com/bytom/protocol/bc"
"github.com/bytom/protocol/bc/types"
"github.com/bytom/protocol/vm"
+ "github.com/bytom/protocol"
+ "github.com/bytom/protocol/validation"
+ "fmt"
)
func TestBlockHeader(t *testing.T) {
t.Fatalf("test max block gas failed")
}
}
+
+// NewBlock create block according to the current status of chain
+func NewMerkleBlock(chain *protocol.Chain, txs []*types.Tx, controlProgram []byte) (*types.Block, error) {
+ gasUsed := uint64(0)
+ txsFee := uint64(0)
+ txEntries := []*bc.Tx{nil}
+ txStatus := bc.NewTransactionStatus()
+ txStatus.SetStatus(0, false)
+
+ preBlockHeader := chain.BestBlockHeader()
+ preBlockHash := preBlockHeader.Hash()
+ nextBits, err := chain.CalcNextBits(&preBlockHash)
+ if err != nil {
+ return nil, err
+ }
+
+ b := &types.Block{
+ BlockHeader: types.BlockHeader{
+ Version: 1,
+ Height: preBlockHeader.Height + 1,
+ PreviousBlockHash: preBlockHeader.Hash(),
+ Timestamp: preBlockHeader.Timestamp + 1,
+ BlockCommitment: types.BlockCommitment{},
+ Bits: nextBits,
+ },
+ Transactions: []*types.Tx{nil},
+ }
+
+ bcBlock := &bc.Block{BlockHeader: &bc.BlockHeader{Height: preBlockHeader.Height + 1}}
+ for _, tx := range txs {
+ gasOnlyTx := false
+ gasStatus, err := validation.ValidateTx(tx.Tx, bcBlock)
+ if err != nil {
+ if !gasStatus.GasValid {
+ continue
+ }
+ gasOnlyTx = true
+ }
+
+ txStatus.SetStatus(len(b.Transactions), gasOnlyTx)
+ b.Transactions = append(b.Transactions, tx)
+ txEntries = append(txEntries, tx.Tx)
+ gasUsed += uint64(gasStatus.GasUsed)
+ txsFee += txFee(tx)
+ }
+
+ coinbaseTx, err := CreateCoinbaseTx(controlProgram, preBlockHeader.Height+1, txsFee)
+ if err != nil {
+ return nil, err
+ }
+
+ b.Transactions[0] = coinbaseTx
+ txEntries[0] = coinbaseTx.Tx
+ b.TransactionsMerkleRoot, err = bc.TxMerkleRoot(txEntries)
+ if err != nil {
+ return nil, err
+ }
+
+ b.TransactionStatusHash, err = bc.TxStatusMerkleRoot(txStatus.VerifyStatus)
+ b.Transactions = b.Transactions[1:len(b.Transactions)/2]
+ return b, err
+}
+
+func TestMerkleBlock(t *testing.T) {
+ chainDB := dbm.NewDB("test_block_db", "leveldb", "test_block_db")
+ defer os.RemoveAll("test_block_db")
+ chain, _, _, err := MockChain(chainDB)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if err := AppendBlocks(chain, 7); err != nil {
+ t.Fatal(err)
+ }
+
+ block, err := chain.GetBlockByHeight(1)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ tx, err := CreateTxFromTx(block.Transactions[0], 0, 600000000000, []byte{byte(vm.OP_TRUE)})
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ outputAmount := uint64(600000000000)
+ txs := []*types.Tx{tx}
+ for i := 1; i < 50000; i++ {
+ outputAmount -= 10000000
+ tx, err := CreateTxFromTx(txs[i-1], 0, outputAmount, []byte{byte(vm.OP_TRUE)})
+ if err != nil {
+ t.Fatal(err)
+ }
+ txs = append(txs, tx)
+ }
+
+ block, err = NewMerkleBlock(chain, txs, []byte{byte(vm.OP_TRUE)})
+ if err != nil {
+ t.Fatal(err)
+ }
+ fmt.Println(len(block.Transactions))
+ if err := SolveAndUpdate(chain, block); err == nil {
+ t.Fatalf("test max block gas failed")
+ }
+}
\ No newline at end of file