From 63c56cca5c3fac51f0b46135d550c161ced9f331 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Tue, 14 Jan 2020 15:32:07 +0300 Subject: [PATCH 1/5] core: refactor out Block, BlockBase and Header structs See #597. --- cli/server/server.go | 3 +- pkg/consensus/block.go | 4 +-- pkg/consensus/consensus.go | 5 ++-- pkg/core/{ => block}/block.go | 6 ++-- pkg/core/{ => block}/block_base.go | 2 +- pkg/core/{ => block}/block_test.go | 8 +++--- pkg/core/{ => block}/header.go | 2 +- pkg/core/{ => block}/header_test.go | 2 +- pkg/core/block/helper_test.go | 44 +++++++++++++++++++++++++++++ pkg/core/blockchain.go | 29 ++++++++++--------- pkg/core/blockchain_test.go | 3 +- pkg/core/blockchainer.go | 11 ++++---- pkg/core/dao.go | 9 +++--- pkg/core/dao_test.go | 15 +++++----- pkg/core/helper_test.go | 41 +++++++++++++++++++++------ pkg/core/interop_neo_test.go | 3 +- pkg/core/interop_system.go | 15 +++++----- pkg/core/interops.go | 5 ++-- pkg/core/util.go | 13 +++++---- pkg/network/blockqueue.go | 5 ++-- pkg/network/blockqueue_test.go | 6 ++-- pkg/network/helper_test.go | 11 ++++---- pkg/network/message.go | 4 +-- pkg/network/payload/headers.go | 8 +++--- pkg/network/payload/headers_test.go | 8 +++--- pkg/network/payload/merkleblock.go | 8 +++--- pkg/network/server.go | 9 +++--- pkg/rpc/server_helper_test.go | 7 +++-- pkg/rpc/wrappers/block.go | 7 +++-- pkg/rpc/wrappers/tx_raw_output.go | 3 +- 30 files changed, 190 insertions(+), 106 deletions(-) rename pkg/core/{ => block}/block.go (96%) rename pkg/core/{ => block}/block_base.go (99%) rename pkg/core/{ => block}/block_test.go (99%) rename pkg/core/{ => block}/header.go (97%) rename pkg/core/{ => block}/header_test.go (99%) create mode 100644 pkg/core/block/helper_test.go diff --git a/cli/server/server.go b/cli/server/server.go index 42a5a7259..f560a245c 100644 --- a/cli/server/server.go +++ b/cli/server/server.go @@ -8,6 +8,7 @@ import ( "github.com/CityOfZion/neo-go/config" "github.com/CityOfZion/neo-go/pkg/core" + "github.com/CityOfZion/neo-go/pkg/core/block" "github.com/CityOfZion/neo-go/pkg/core/storage" "github.com/CityOfZion/neo-go/pkg/encoding/address" "github.com/CityOfZion/neo-go/pkg/io" @@ -268,7 +269,7 @@ func restoreDB(ctx *cli.Context) error { } for ; i < skip+count; i++ { bytes, err := readBlock(reader) - block := &core.Block{} + block := &block.Block{} newReader := io.NewBinReaderFromBuf(bytes) block.DecodeBinary(newReader) if err != nil { diff --git a/pkg/consensus/block.go b/pkg/consensus/block.go index 6d9c6dc27..f71f4bfb5 100644 --- a/pkg/consensus/block.go +++ b/pkg/consensus/block.go @@ -1,7 +1,7 @@ package consensus import ( - "github.com/CityOfZion/neo-go/pkg/core" + coreb "github.com/CityOfZion/neo-go/pkg/core/block" "github.com/CityOfZion/neo-go/pkg/core/transaction" "github.com/CityOfZion/neo-go/pkg/util" "github.com/nspcc-dev/dbft/block" @@ -11,7 +11,7 @@ import ( // neoBlock is a wrapper of core.Block which implements // methods necessary for dBFT library. type neoBlock struct { - core.Block + coreb.Block signature []byte } diff --git a/pkg/consensus/consensus.go b/pkg/consensus/consensus.go index 6aebda543..8f96d8d5b 100644 --- a/pkg/consensus/consensus.go +++ b/pkg/consensus/consensus.go @@ -8,6 +8,7 @@ import ( "github.com/CityOfZion/neo-go/config" "github.com/CityOfZion/neo-go/pkg/core" + coreb "github.com/CityOfZion/neo-go/pkg/core/block" "github.com/CityOfZion/neo-go/pkg/core/transaction" "github.com/CityOfZion/neo-go/pkg/crypto/hash" "github.com/CityOfZion/neo-go/pkg/crypto/keys" @@ -67,7 +68,7 @@ type Config struct { Broadcast func(p *Payload) // RelayBlock is a callback that is called to notify server // about the new block that needs to be broadcasted. - RelayBlock func(b *core.Block) + RelayBlock func(b *coreb.Block) // Chain is a core.Blockchainer instance. Chain core.Blockchainer // RequestTx is a callback to which will be called @@ -285,7 +286,7 @@ func (s *service) processBlock(b block.Block) { } } -func (s *service) getBlockWitness(b *core.Block) *transaction.Witness { +func (s *service) getBlockWitness(b *coreb.Block) *transaction.Witness { dctx := s.dbft.Context pubs := convertKeys(dctx.Validators) sigs := make(map[*keys.PublicKey][]byte) diff --git a/pkg/core/block.go b/pkg/core/block/block.go similarity index 96% rename from pkg/core/block.go rename to pkg/core/block/block.go index a7e2b4791..3077095c7 100644 --- a/pkg/core/block.go +++ b/pkg/core/block/block.go @@ -1,4 +1,4 @@ -package core +package block import ( "errors" @@ -39,8 +39,8 @@ func merkleTreeFromTransactions(txes []*transaction.Transaction) (*hash.MerkleTr return hash.NewMerkleTree(hashes) } -// rebuildMerkleRoot rebuilds the merkleroot of the block. -func (b *Block) rebuildMerkleRoot() error { +// RebuildMerkleRoot rebuilds the merkleroot of the block. +func (b *Block) RebuildMerkleRoot() error { merkle, err := merkleTreeFromTransactions(b.Transactions) if err != nil { return err diff --git a/pkg/core/block_base.go b/pkg/core/block/block_base.go similarity index 99% rename from pkg/core/block_base.go rename to pkg/core/block/block_base.go index 9e6c1d0b5..404701059 100644 --- a/pkg/core/block_base.go +++ b/pkg/core/block/block_base.go @@ -1,4 +1,4 @@ -package core +package block import ( "fmt" diff --git a/pkg/core/block_test.go b/pkg/core/block/block_test.go similarity index 99% rename from pkg/core/block_test.go rename to pkg/core/block/block_test.go index 82118b6ea..42355e9c0 100644 --- a/pkg/core/block_test.go +++ b/pkg/core/block/block_test.go @@ -1,4 +1,4 @@ -package core +package block import ( "encoding/hex" @@ -108,21 +108,21 @@ func TestHashBlockEqualsHashHeader(t *testing.T) { func TestBlockVerify(t *testing.T) { block := newDumbBlock() assert.NotNil(t, block.Verify()) - assert.Nil(t, block.rebuildMerkleRoot()) + assert.Nil(t, block.RebuildMerkleRoot()) assert.Nil(t, block.Verify()) block.Transactions = []*transaction.Transaction{ {Type: transaction.IssueType}, {Type: transaction.MinerType}, } - assert.NoError(t, block.rebuildMerkleRoot()) + assert.NoError(t, block.RebuildMerkleRoot()) assert.NotNil(t, block.Verify()) block.Transactions = []*transaction.Transaction{ {Type: transaction.MinerType}, {Type: transaction.MinerType}, } - assert.NoError(t, block.rebuildMerkleRoot()) + assert.NoError(t, block.RebuildMerkleRoot()) assert.NotNil(t, block.Verify()) block.Transactions = []*transaction.Transaction{ {Type: transaction.MinerType}, diff --git a/pkg/core/header.go b/pkg/core/block/header.go similarity index 97% rename from pkg/core/header.go rename to pkg/core/block/header.go index e3bf50824..5f9060f3d 100644 --- a/pkg/core/header.go +++ b/pkg/core/block/header.go @@ -1,4 +1,4 @@ -package core +package block import ( "fmt" diff --git a/pkg/core/header_test.go b/pkg/core/block/header_test.go similarity index 99% rename from pkg/core/header_test.go rename to pkg/core/block/header_test.go index ed35c6f73..020afcbda 100644 --- a/pkg/core/header_test.go +++ b/pkg/core/block/header_test.go @@ -1,4 +1,4 @@ -package core +package block import ( "testing" diff --git a/pkg/core/block/helper_test.go b/pkg/core/block/helper_test.go new file mode 100644 index 000000000..31a8f29d8 --- /dev/null +++ b/pkg/core/block/helper_test.go @@ -0,0 +1,44 @@ +package block + +import ( + "encoding/hex" + "encoding/json" + "fmt" + "io/ioutil" + "testing" + + "github.com/CityOfZion/neo-go/pkg/io" +) + +func getDecodedBlock(t *testing.T, i int) *Block { + data, err := getBlockData(i) + if err != nil { + t.Fatal(err) + } + + b, err := hex.DecodeString(data["raw"].(string)) + if err != nil { + t.Fatal(err) + } + + block := &Block{} + r := io.NewBinReaderFromBuf(b) + block.DecodeBinary(r) + if r.Err != nil { + t.Fatal(r.Err) + } + + return block +} + +func getBlockData(i int) (map[string]interface{}, error) { + b, err := ioutil.ReadFile(fmt.Sprintf("../test_data/block_%d.json", i)) + if err != nil { + return nil, err + } + var data map[string]interface{} + if err := json.Unmarshal(b, &data); err != nil { + return nil, err + } + return data, err +} diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index 69cb4f9b8..cd0da4930 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -11,6 +11,7 @@ import ( "time" "github.com/CityOfZion/neo-go/config" + "github.com/CityOfZion/neo-go/pkg/core/block" "github.com/CityOfZion/neo-go/pkg/core/state" "github.com/CityOfZion/neo-go/pkg/core/storage" "github.com/CityOfZion/neo-go/pkg/core/transaction" @@ -179,7 +180,7 @@ func (bc *Blockchain) init() error { targetHash = genesisBlock.Hash() bc.headerList.Add(targetHash) } - headers := make([]*Header, 0) + headers := make([]*block.Header, 0) for hash != targetHash { header, err := bc.GetHeader(hash) @@ -242,7 +243,7 @@ func (bc *Blockchain) Close() { // AddBlock accepts successive block for the Blockchain, verifies it and // stores internally. Eventually it will be persisted to the backing storage. -func (bc *Blockchain) AddBlock(block *Block) error { +func (bc *Blockchain) AddBlock(block *block.Block) error { expectedHeight := bc.BlockHeight() + 1 if expectedHeight != block.Index { return fmt.Errorf("expected block %d, but passed block %d", expectedHeight, block.Index) @@ -276,7 +277,7 @@ func (bc *Blockchain) AddBlock(block *Block) error { // AddHeaders processes the given headers and add them to the // HeaderHashList. -func (bc *Blockchain) AddHeaders(headers ...*Header) (err error) { +func (bc *Blockchain) AddHeaders(headers ...*block.Header) (err error) { var ( start = time.Now() batch = bc.dao.store.Batch() @@ -321,7 +322,7 @@ func (bc *Blockchain) AddHeaders(headers ...*Header) (err error) { // processHeader processes the given header. Note that this is only thread safe // if executed in headers operation. -func (bc *Blockchain) processHeader(h *Header, batch storage.Batch, headerList *HeaderHashList) error { +func (bc *Blockchain) processHeader(h *block.Header, batch storage.Batch, headerList *HeaderHashList) error { headerList.Add(h.Hash()) buf := io.NewBufBinWriter() @@ -352,7 +353,7 @@ func (bc *Blockchain) processHeader(h *Header, batch storage.Batch, headerList * // project. This for the sake of development speed and understanding of what // is happening here, quite allot as you can see :). If things are wired together // and all tests are in place, we can make a more optimized and cleaner implementation. -func (bc *Blockchain) storeBlock(block *Block) error { +func (bc *Blockchain) storeBlock(block *block.Block) error { cache := newCachedDao(bc.dao.store) if err := cache.StoreAsBlock(block, 0); err != nil { return err @@ -756,10 +757,10 @@ func (bc *Blockchain) GetStorageItems(hash util.Uint160) (map[string]*state.Stor } // GetBlock returns a Block by the given hash. -func (bc *Blockchain) GetBlock(hash util.Uint256) (*Block, error) { +func (bc *Blockchain) GetBlock(hash util.Uint256) (*block.Block, error) { topBlock := bc.topBlock.Load() if topBlock != nil { - if tb, ok := topBlock.(*Block); ok && tb.Hash().Equals(hash) { + if tb, ok := topBlock.(*block.Block); ok && tb.Hash().Equals(hash) { return tb, nil } } @@ -782,10 +783,10 @@ func (bc *Blockchain) GetBlock(hash util.Uint256) (*Block, error) { } // GetHeader returns data block header identified with the given hash value. -func (bc *Blockchain) GetHeader(hash util.Uint256) (*Header, error) { +func (bc *Blockchain) GetHeader(hash util.Uint256) (*block.Header, error) { topBlock := bc.topBlock.Load() if topBlock != nil { - if tb, ok := topBlock.(*Block); ok && tb.Hash().Equals(hash) { + if tb, ok := topBlock.(*block.Block); ok && tb.Hash().Equals(hash) { return tb.Header(), nil } } @@ -955,7 +956,7 @@ func (bc *Blockchain) GetMemPool() MemPool { } // VerifyBlock verifies block against its current state. -func (bc *Blockchain) VerifyBlock(block *Block) error { +func (bc *Blockchain) VerifyBlock(block *block.Block) error { prevHeader, err := bc.GetHeader(block.PrevHash) if err != nil { return errors.Wrap(err, "unable to get previous header") @@ -973,7 +974,7 @@ func (bc *Blockchain) VerifyBlock(block *Block) error { // is used for easy interop access and can be omitted for transactions that are // not yet added into any block. // Golang implementation of Verify method in C# (https://github.com/neo-project/neo/blob/master/neo/Network/P2P/Payloads/Transaction.cs#L270). -func (bc *Blockchain) VerifyTx(t *transaction.Transaction, block *Block) error { +func (bc *Blockchain) VerifyTx(t *transaction.Transaction, block *block.Block) error { if io.GetVarSize(t) > transaction.MaxTransactionSize { return errors.Errorf("invalid transaction size = %d. It shoud be less then MaxTransactionSize = %d", io.GetVarSize(t), transaction.MaxTransactionSize) } @@ -1440,7 +1441,7 @@ func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transa // not yet added into any block. // Golang implementation of VerifyWitnesses method in C# (https://github.com/neo-project/neo/blob/master/neo/SmartContract/Helper.cs#L87). // Unfortunately the IVerifiable interface could not be implemented because we can't move the References method in blockchain.go to the transaction.go file. -func (bc *Blockchain) verifyTxWitnesses(t *transaction.Transaction, block *Block) error { +func (bc *Blockchain) verifyTxWitnesses(t *transaction.Transaction, block *block.Block) error { hashes, err := bc.GetScriptHashesForVerifying(t) if err != nil { return err @@ -1465,7 +1466,7 @@ func (bc *Blockchain) verifyTxWitnesses(t *transaction.Transaction, block *Block } // verifyBlockWitnesses is a block-specific implementation of VerifyWitnesses logic. -func (bc *Blockchain) verifyBlockWitnesses(block *Block, prevHeader *Header) error { +func (bc *Blockchain) verifyBlockWitnesses(block *block.Block, prevHeader *block.Header) error { var hash util.Uint160 if prevHeader == nil && block.PrevHash.Equals(util.Uint256{}) { hash = block.Script.ScriptHash() @@ -1487,6 +1488,6 @@ func (bc *Blockchain) secondsPerBlock() int { return bc.config.SecondsPerBlock } -func (bc *Blockchain) newInteropContext(trigger byte, s storage.Store, block *Block, tx *transaction.Transaction) *interopContext { +func (bc *Blockchain) newInteropContext(trigger byte, s storage.Store, block *block.Block, tx *transaction.Transaction) *interopContext { return newInteropContext(trigger, bc, s, block, tx, bc.log) } diff --git a/pkg/core/blockchain_test.go b/pkg/core/blockchain_test.go index 0fa8b3aae..a35245776 100644 --- a/pkg/core/blockchain_test.go +++ b/pkg/core/blockchain_test.go @@ -3,6 +3,7 @@ package core import ( "testing" + "github.com/CityOfZion/neo-go/pkg/core/block" "github.com/CityOfZion/neo-go/pkg/core/storage" "github.com/CityOfZion/neo-go/pkg/core/transaction" "github.com/CityOfZion/neo-go/pkg/crypto/hash" @@ -38,7 +39,7 @@ func TestAddHeaders(t *testing.T) { func TestAddBlock(t *testing.T) { bc := newTestChain(t) - blocks := []*Block{ + blocks := []*block.Block{ newBlock(1, newMinerTX()), newBlock(2, newMinerTX()), newBlock(3, newMinerTX()), diff --git a/pkg/core/blockchainer.go b/pkg/core/blockchainer.go index 8493dec80..fdeaa6072 100644 --- a/pkg/core/blockchainer.go +++ b/pkg/core/blockchainer.go @@ -2,6 +2,7 @@ package core import ( "github.com/CityOfZion/neo-go/config" + "github.com/CityOfZion/neo-go/pkg/core/block" "github.com/CityOfZion/neo-go/pkg/core/state" "github.com/CityOfZion/neo-go/pkg/core/storage" "github.com/CityOfZion/neo-go/pkg/core/transaction" @@ -14,15 +15,15 @@ import ( // of the blockchain. type Blockchainer interface { GetConfig() config.ProtocolConfiguration - AddHeaders(...*Header) error - AddBlock(*Block) error + AddHeaders(...*block.Header) error + AddBlock(*block.Block) error BlockHeight() uint32 Close() HeaderHeight() uint32 - GetBlock(hash util.Uint256) (*Block, error) + GetBlock(hash util.Uint256) (*block.Block, error) GetContractState(hash util.Uint160) *state.Contract GetHeaderHash(int) util.Uint256 - GetHeader(hash util.Uint256) (*Header, error) + GetHeader(hash util.Uint256) (*block.Header, error) CurrentHeaderHash() util.Uint256 CurrentBlockHash() util.Uint256 HasBlock(util.Uint256) bool @@ -38,6 +39,6 @@ type Blockchainer interface { GetUnspentCoinState(util.Uint256) *UnspentCoinState References(t *transaction.Transaction) map[transaction.Input]*transaction.Output Feer // fee interface - VerifyTx(*transaction.Transaction, *Block) error + VerifyTx(*transaction.Transaction, *block.Block) error GetMemPool() MemPool } diff --git a/pkg/core/dao.go b/pkg/core/dao.go index d570d5e3e..4111fba66 100644 --- a/pkg/core/dao.go +++ b/pkg/core/dao.go @@ -6,6 +6,7 @@ import ( "fmt" "sort" + "github.com/CityOfZion/neo-go/pkg/core/block" "github.com/CityOfZion/neo-go/pkg/core/state" "github.com/CityOfZion/neo-go/pkg/core/storage" "github.com/CityOfZion/neo-go/pkg/core/transaction" @@ -358,13 +359,13 @@ func makeStorageItemKey(scripthash util.Uint160, key []byte) []byte { // -- other. // GetBlock returns Block by the given hash if it exists in the store. -func (dao *dao) GetBlock(hash util.Uint256) (*Block, error) { +func (dao *dao) GetBlock(hash util.Uint256) (*block.Block, error) { key := storage.AppendPrefix(storage.DataBlock, hash.BytesLE()) b, err := dao.store.Get(key) if err != nil { return nil, err } - block, err := NewBlockFromTrimmedBytes(b) + block, err := block.NewBlockFromTrimmedBytes(b) if err != nil { return nil, err } @@ -486,7 +487,7 @@ func (dao *dao) HasTransaction(hash util.Uint256) bool { } // StoreAsBlock stores the given block as DataBlock. -func (dao *dao) StoreAsBlock(block *Block, sysFee uint32) error { +func (dao *dao) StoreAsBlock(block *block.Block, sysFee uint32) error { var ( key = storage.AppendPrefix(storage.DataBlock, block.Hash().BytesLE()) buf = io.NewBufBinWriter() @@ -505,7 +506,7 @@ func (dao *dao) StoreAsBlock(block *Block, sysFee uint32) error { } // StoreAsCurrentBlock stores the given block witch prefix SYSCurrentBlock. -func (dao *dao) StoreAsCurrentBlock(block *Block) error { +func (dao *dao) StoreAsCurrentBlock(block *block.Block) error { buf := io.NewBufBinWriter() h := block.Hash() h.EncodeBinary(buf.BinWriter) diff --git a/pkg/core/dao_test.go b/pkg/core/dao_test.go index d747ddf19..cf06aa757 100644 --- a/pkg/core/dao_test.go +++ b/pkg/core/dao_test.go @@ -3,6 +3,7 @@ package core import ( "testing" + "github.com/CityOfZion/neo-go/pkg/core/block" "github.com/CityOfZion/neo-go/pkg/core/state" "github.com/CityOfZion/neo-go/pkg/core/storage" "github.com/CityOfZion/neo-go/pkg/core/transaction" @@ -260,16 +261,16 @@ func TestGetBlock_NotExists(t *testing.T) { func TestPutGetBlock(t *testing.T) { dao := newDao(storage.NewMemoryStore()) - block := &Block{ - BlockBase: BlockBase{ + b := &block.Block{ + BlockBase: block.BlockBase{ Script: transaction.Witness{ VerificationScript: []byte{byte(opcode.PUSH1)}, InvocationScript: []byte{byte(opcode.NOP)}, }, }, } - hash := block.Hash() - err := dao.StoreAsBlock(block, 0) + hash := b.Hash() + err := dao.StoreAsBlock(b, 0) require.NoError(t, err) gotBlock, err := dao.GetBlock(hash) require.NoError(t, err) @@ -301,15 +302,15 @@ func TestGetCurrentHeaderHeight_NoHeader(t *testing.T) { func TestGetCurrentHeaderHeight_Store(t *testing.T) { dao := newDao(storage.NewMemoryStore()) - block := &Block{ - BlockBase: BlockBase{ + b := &block.Block{ + BlockBase: block.BlockBase{ Script: transaction.Witness{ VerificationScript: []byte{byte(opcode.PUSH1)}, InvocationScript: []byte{byte(opcode.NOP)}, }, }, } - err := dao.StoreAsCurrentBlock(block) + err := dao.StoreAsCurrentBlock(b) require.NoError(t, err) height, err := dao.GetCurrentBlockHeight() require.NoError(t, err) diff --git a/pkg/core/helper_test.go b/pkg/core/helper_test.go index f750af78f..9a452ffc9 100644 --- a/pkg/core/helper_test.go +++ b/pkg/core/helper_test.go @@ -9,8 +9,10 @@ import ( "time" "github.com/CityOfZion/neo-go/config" + "github.com/CityOfZion/neo-go/pkg/core/block" "github.com/CityOfZion/neo-go/pkg/core/storage" "github.com/CityOfZion/neo-go/pkg/core/transaction" + "github.com/CityOfZion/neo-go/pkg/crypto/hash" "github.com/CityOfZion/neo-go/pkg/crypto/keys" "github.com/CityOfZion/neo-go/pkg/io" "github.com/CityOfZion/neo-go/pkg/smartcontract" @@ -49,7 +51,7 @@ func newTestChain(t *testing.T) *Blockchain { return chain } -func newBlock(index uint32, txs ...*transaction.Transaction) *Block { +func newBlock(index uint32, txs ...*transaction.Transaction) *block.Block { validators, _ := getValidators(unitTestNetCfg.ProtocolConfiguration) vlen := len(validators) valScript, _ := smartcontract.CreateMultiSigRedeemScript( @@ -59,8 +61,8 @@ func newBlock(index uint32, txs ...*transaction.Transaction) *Block { witness := transaction.Witness{ VerificationScript: valScript, } - b := &Block{ - BlockBase: BlockBase{ + b := &block.Block{ + BlockBase: block.BlockBase{ Version: 0, PrevHash: newBlockPrevHash, Timestamp: uint32(time.Now().UTC().Unix()) + index, @@ -71,8 +73,7 @@ func newBlock(index uint32, txs ...*transaction.Transaction) *Block { }, Transactions: txs, } - _ = b.rebuildMerkleRoot() - b.createHash() + _ = b.RebuildMerkleRoot() newBlockPrevHash = b.Hash() invScript := make([]byte, 0) @@ -93,8 +94,8 @@ func newBlock(index uint32, txs ...*transaction.Transaction) *Block { return b } -func makeBlocks(n int) []*Block { - blocks := make([]*Block, n) +func makeBlocks(n int) []*block.Block { + blocks := make([]*block.Block, n) for i := 0; i < n; i++ { blocks[i] = newBlock(uint32(i+1), newMinerTX()) } @@ -108,7 +109,7 @@ func newMinerTX() *transaction.Transaction { } } -func getDecodedBlock(t *testing.T, i int) *Block { +func getDecodedBlock(t *testing.T, i int) *block.Block { data, err := getBlockData(i) if err != nil { t.Fatal(err) @@ -119,7 +120,7 @@ func getDecodedBlock(t *testing.T, i int) *Block { t.Fatal(err) } - block := &Block{} + block := &block.Block{} r := io.NewBinReaderFromBuf(b) block.DecodeBinary(r) if r.Err != nil { @@ -140,3 +141,25 @@ func getBlockData(i int) (map[string]interface{}, error) { } return data, err } + +func newDumbBlock() *block.Block { + return &block.Block{ + BlockBase: block.BlockBase{ + Version: 0, + PrevHash: hash.Sha256([]byte("a")), + MerkleRoot: hash.Sha256([]byte("b")), + Timestamp: uint32(100500), + Index: 1, + ConsensusData: 1111, + NextConsensus: hash.Hash160([]byte("a")), + Script: transaction.Witness{ + VerificationScript: []byte{0x51}, // PUSH1 + InvocationScript: []byte{0x61}, // NOP + }, + }, + Transactions: []*transaction.Transaction{ + {Type: transaction.MinerType}, + {Type: transaction.IssueType}, + }, + } +} diff --git a/pkg/core/interop_neo_test.go b/pkg/core/interop_neo_test.go index 39c43a714..f55a95cf9 100644 --- a/pkg/core/interop_neo_test.go +++ b/pkg/core/interop_neo_test.go @@ -4,6 +4,7 @@ import ( "math/big" "testing" + "github.com/CityOfZion/neo-go/pkg/core/block" "github.com/CityOfZion/neo-go/pkg/core/state" "github.com/CityOfZion/neo-go/pkg/core/storage" "github.com/CityOfZion/neo-go/pkg/core/transaction" @@ -451,7 +452,7 @@ func TestAssetGetPrecision(t *testing.T) { // Helper functions to create VM, InteropContext, TX, Account, Contract, Asset. -func createVMAndPushBlock(t *testing.T) (*vm.VM, *Block, *interopContext, *Blockchain) { +func createVMAndPushBlock(t *testing.T) (*vm.VM, *block.Block, *interopContext, *Blockchain) { v := vm.New() block := newDumbBlock() chain := newTestChain(t) diff --git a/pkg/core/interop_system.go b/pkg/core/interop_system.go index b96b5a0ec..9d8c930a8 100644 --- a/pkg/core/interop_system.go +++ b/pkg/core/interop_system.go @@ -5,6 +5,7 @@ import ( "fmt" "math" + "github.com/CityOfZion/neo-go/pkg/core/block" "github.com/CityOfZion/neo-go/pkg/core/state" "github.com/CityOfZion/neo-go/pkg/core/transaction" "github.com/CityOfZion/neo-go/pkg/crypto/hash" @@ -132,11 +133,11 @@ func (ic *interopContext) bcGetTransactionHeight(v *vm.VM) error { // popHeaderFromVM returns pointer to Header or error. It's main feature is // proper treatment of Block structure, because C# code implicitly assumes // that header APIs can also operate on blocks. -func popHeaderFromVM(v *vm.VM) (*Header, error) { +func popHeaderFromVM(v *vm.VM) (*block.Header, error) { iface := v.Estack().Pop().Value() - header, ok := iface.(*Header) + header, ok := iface.(*block.Header) if !ok { - block, ok := iface.(*Block) + block, ok := iface.(*block.Block) if !ok { return nil, errors.New("value is not a header or block") } @@ -188,7 +189,7 @@ func (ic *interopContext) headerGetTimestamp(v *vm.VM) error { // blockGetTransactionCount returns transactions count in the given block. func (ic *interopContext) blockGetTransactionCount(v *vm.VM) error { blockInterface := v.Estack().Pop().Value() - block, ok := blockInterface.(*Block) + block, ok := blockInterface.(*block.Block) if !ok { return errors.New("value is not a block") } @@ -199,7 +200,7 @@ func (ic *interopContext) blockGetTransactionCount(v *vm.VM) error { // blockGetTransactions returns transactions from the given block. func (ic *interopContext) blockGetTransactions(v *vm.VM) error { blockInterface := v.Estack().Pop().Value() - block, ok := blockInterface.(*Block) + block, ok := blockInterface.(*block.Block) if !ok { return errors.New("value is not a block") } @@ -218,7 +219,7 @@ func (ic *interopContext) blockGetTransactions(v *vm.VM) error { // block. func (ic *interopContext) blockGetTransaction(v *vm.VM) error { blockInterface := v.Estack().Pop().Value() - block, ok := blockInterface.(*Block) + block, ok := blockInterface.(*block.Block) if !ok { return errors.New("value is not a block") } @@ -359,7 +360,7 @@ func (ic *interopContext) runtimeLog(v *vm.VM) error { // runtimeGetTime returns timestamp of the block being verified, or the latest // one in the blockchain if no block is given to interopContext. func (ic *interopContext) runtimeGetTime(v *vm.VM) error { - var header *Header + var header *block.Header if ic.block == nil { var err error header, err = ic.bc.GetHeader(ic.bc.CurrentBlockHash()) diff --git a/pkg/core/interops.go b/pkg/core/interops.go index bf33b347d..15ee9b994 100644 --- a/pkg/core/interops.go +++ b/pkg/core/interops.go @@ -10,6 +10,7 @@ package core import ( "sort" + "github.com/CityOfZion/neo-go/pkg/core/block" "github.com/CityOfZion/neo-go/pkg/core/state" "github.com/CityOfZion/neo-go/pkg/core/storage" "github.com/CityOfZion/neo-go/pkg/core/transaction" @@ -20,14 +21,14 @@ import ( type interopContext struct { bc Blockchainer trigger byte - block *Block + block *block.Block tx *transaction.Transaction dao *cachedDao notifications []state.NotificationEvent log *zap.Logger } -func newInteropContext(trigger byte, bc Blockchainer, s storage.Store, block *Block, tx *transaction.Transaction, log *zap.Logger) *interopContext { +func newInteropContext(trigger byte, bc Blockchainer, s storage.Store, block *block.Block, tx *transaction.Transaction, log *zap.Logger) *interopContext { dao := newCachedDao(s) nes := make([]state.NotificationEvent, 0) return &interopContext{bc, trigger, block, tx, dao, nes, log} diff --git a/pkg/core/util.go b/pkg/core/util.go index c553f5ef0..3269035de 100644 --- a/pkg/core/util.go +++ b/pkg/core/util.go @@ -4,6 +4,7 @@ import ( "time" "github.com/CityOfZion/neo-go/config" + "github.com/CityOfZion/neo-go/pkg/core/block" "github.com/CityOfZion/neo-go/pkg/core/transaction" "github.com/CityOfZion/neo-go/pkg/crypto/hash" "github.com/CityOfZion/neo-go/pkg/crypto/keys" @@ -13,7 +14,7 @@ import ( ) // createGenesisBlock creates a genesis block based on the given configuration. -func createGenesisBlock(cfg config.ProtocolConfiguration) (*Block, error) { +func createGenesisBlock(cfg config.ProtocolConfiguration) (*block.Block, error) { validators, err := getValidators(cfg) if err != nil { return nil, err @@ -24,7 +25,7 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*Block, error) { return nil, err } - base := BlockBase{ + base := block.BlockBase{ Version: 0, PrevHash: util.Uint256{}, Timestamp: uint32(time.Date(2016, 7, 15, 15, 8, 21, 0, time.UTC).Unix()), @@ -48,7 +49,7 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*Block, error) { } scriptOut := hash.Hash160(rawScript) - block := &Block{ + b := &block.Block{ BlockBase: base, Transactions: []*transaction.Transaction{ { @@ -84,11 +85,11 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*Block, error) { }, } - if err = block.rebuildMerkleRoot(); err != nil { + if err = b.RebuildMerkleRoot(); err != nil { return nil, err } - return block, nil + return b, nil } func governingTokenTX() *transaction.Transaction { @@ -167,7 +168,7 @@ func calculateUtilityAmount() util.Fixed8 { } // headerSliceReverse reverses the given slice of *Header. -func headerSliceReverse(dest []*Header) { +func headerSliceReverse(dest []*block.Header) { for i, j := 0, len(dest)-1; i < j; i, j = i+1, j-1 { dest[i], dest[j] = dest[j], dest[i] } diff --git a/pkg/network/blockqueue.go b/pkg/network/blockqueue.go index bbd9f176a..e26d96629 100644 --- a/pkg/network/blockqueue.go +++ b/pkg/network/blockqueue.go @@ -2,6 +2,7 @@ package network import ( "github.com/CityOfZion/neo-go/pkg/core" + "github.com/CityOfZion/neo-go/pkg/core/block" "github.com/Workiva/go-datastructures/queue" "go.uber.org/zap" ) @@ -37,7 +38,7 @@ func (bq *blockQueue) run() { if item == nil { break } - minblock := item.(*core.Block) + minblock := item.(*block.Block) if minblock.Index <= bq.chain.BlockHeight()+1 { _, _ = bq.queue.Get(1) updateBlockQueueLenMetric(bq.length()) @@ -57,7 +58,7 @@ func (bq *blockQueue) run() { } } -func (bq *blockQueue) putBlock(block *core.Block) error { +func (bq *blockQueue) putBlock(block *block.Block) error { if bq.chain.BlockHeight() >= block.Index { // can easily happen when fetching the same blocks from // different peers, thus not considered as error diff --git a/pkg/network/blockqueue_test.go b/pkg/network/blockqueue_test.go index f30b47a0a..881759d33 100644 --- a/pkg/network/blockqueue_test.go +++ b/pkg/network/blockqueue_test.go @@ -4,7 +4,7 @@ import ( "testing" "time" - "github.com/CityOfZion/neo-go/pkg/core" + "github.com/CityOfZion/neo-go/pkg/core/block" "github.com/stretchr/testify/assert" "go.uber.org/zap/zaptest" ) @@ -13,9 +13,9 @@ func TestBlockQueue(t *testing.T) { chain := &testChain{} // notice, it's not yet running bq := newBlockQueue(0, chain, zaptest.NewLogger(t)) - blocks := make([]*core.Block, 11) + blocks := make([]*block.Block, 11) for i := 1; i < 11; i++ { - blocks[i] = &core.Block{BlockBase: core.BlockBase{Index: uint32(i)}} + blocks[i] = &block.Block{BlockBase: block.BlockBase{Index: uint32(i)}} } // not the ones expected currently for i := 3; i < 5; i++ { diff --git a/pkg/network/helper_test.go b/pkg/network/helper_test.go index 5fdc86e5f..e71fde016 100644 --- a/pkg/network/helper_test.go +++ b/pkg/network/helper_test.go @@ -9,6 +9,7 @@ import ( "github.com/CityOfZion/neo-go/config" "github.com/CityOfZion/neo-go/pkg/core" + "github.com/CityOfZion/neo-go/pkg/core/block" "github.com/CityOfZion/neo-go/pkg/core/state" "github.com/CityOfZion/neo-go/pkg/core/storage" "github.com/CityOfZion/neo-go/pkg/core/transaction" @@ -43,10 +44,10 @@ func (chain testChain) NetworkFee(t *transaction.Transaction) util.Fixed8 { panic("TODO") } -func (chain testChain) AddHeaders(...*core.Header) error { +func (chain testChain) AddHeaders(...*block.Header) error { panic("TODO") } -func (chain *testChain) AddBlock(block *core.Block) error { +func (chain *testChain) AddBlock(block *block.Block) error { if block.Index == chain.blockheight+1 { atomic.StoreUint32(&chain.blockheight, block.Index) } @@ -61,7 +62,7 @@ func (chain *testChain) Close() { func (chain testChain) HeaderHeight() uint32 { return 0 } -func (chain testChain) GetBlock(hash util.Uint256) (*core.Block, error) { +func (chain testChain) GetBlock(hash util.Uint256) (*block.Block, error) { panic("TODO") } func (chain testChain) GetContractState(hash util.Uint160) *state.Contract { @@ -70,7 +71,7 @@ func (chain testChain) GetContractState(hash util.Uint160) *state.Contract { func (chain testChain) GetHeaderHash(int) util.Uint256 { return util.Uint256{} } -func (chain testChain) GetHeader(hash util.Uint256) (*core.Header, error) { +func (chain testChain) GetHeader(hash util.Uint256) (*block.Header, error) { panic("TODO") } @@ -123,7 +124,7 @@ func (chain testChain) IsLowPriority(*transaction.Transaction) bool { panic("TODO") } -func (chain testChain) VerifyTx(*transaction.Transaction, *core.Block) error { +func (chain testChain) VerifyTx(*transaction.Transaction, *block.Block) error { panic("TODO") } diff --git a/pkg/network/message.go b/pkg/network/message.go index 087724967..973dee330 100644 --- a/pkg/network/message.go +++ b/pkg/network/message.go @@ -7,7 +7,7 @@ import ( "github.com/CityOfZion/neo-go/config" "github.com/CityOfZion/neo-go/pkg/consensus" - "github.com/CityOfZion/neo-go/pkg/core" + "github.com/CityOfZion/neo-go/pkg/core/block" "github.com/CityOfZion/neo-go/pkg/core/transaction" "github.com/CityOfZion/neo-go/pkg/crypto/hash" "github.com/CityOfZion/neo-go/pkg/io" @@ -184,7 +184,7 @@ func (m *Message) decodePayload(br *io.BinReader) error { case CMDAddr: p = &payload.AddressList{} case CMDBlock: - p = &core.Block{} + p = &block.Block{} case CMDConsensus: p = &consensus.Payload{} case CMDGetBlocks: diff --git a/pkg/network/payload/headers.go b/pkg/network/payload/headers.go index 57160c190..1b0ed7fd4 100644 --- a/pkg/network/payload/headers.go +++ b/pkg/network/payload/headers.go @@ -1,14 +1,14 @@ package payload import ( - "github.com/CityOfZion/neo-go/pkg/core" + "github.com/CityOfZion/neo-go/pkg/core/block" "github.com/CityOfZion/neo-go/pkg/io" "github.com/pkg/errors" ) // Headers payload. type Headers struct { - Hdrs []*core.Header + Hdrs []*block.Header } // Users can at most request 2k header. @@ -30,10 +30,10 @@ func (p *Headers) DecodeBinary(br *io.BinReader) { lenHeaders = MaxHeadersAllowed } - p.Hdrs = make([]*core.Header, lenHeaders) + p.Hdrs = make([]*block.Header, lenHeaders) for i := 0; i < int(lenHeaders); i++ { - header := &core.Header{} + header := &block.Header{} header.DecodeBinary(br) p.Hdrs[i] = header } diff --git a/pkg/network/payload/headers_test.go b/pkg/network/payload/headers_test.go index 22762cc0e..f9fa957d0 100644 --- a/pkg/network/payload/headers_test.go +++ b/pkg/network/payload/headers_test.go @@ -4,7 +4,7 @@ import ( "encoding/hex" "testing" - "github.com/CityOfZion/neo-go/pkg/core" + "github.com/CityOfZion/neo-go/pkg/core/block" "github.com/CityOfZion/neo-go/pkg/core/transaction" "github.com/CityOfZion/neo-go/pkg/io" "github.com/stretchr/testify/assert" @@ -26,11 +26,11 @@ func TestHeadersEncodeDecode(t *testing.T) { } func newTestHeaders(n int) *Headers { - headers := &Headers{Hdrs: make([]*core.Header, n)} + headers := &Headers{Hdrs: make([]*block.Header, n)} for i := range headers.Hdrs { - headers.Hdrs[i] = &core.Header{ - BlockBase: core.BlockBase{ + headers.Hdrs[i] = &block.Header{ + BlockBase: block.BlockBase{ Index: uint32(i + 1), Script: transaction.Witness{ InvocationScript: []byte{0x0}, diff --git a/pkg/network/payload/merkleblock.go b/pkg/network/payload/merkleblock.go index 410e2b749..9759a853c 100644 --- a/pkg/network/payload/merkleblock.go +++ b/pkg/network/payload/merkleblock.go @@ -1,14 +1,14 @@ package payload import ( - "github.com/CityOfZion/neo-go/pkg/core" + "github.com/CityOfZion/neo-go/pkg/core/block" "github.com/CityOfZion/neo-go/pkg/io" "github.com/CityOfZion/neo-go/pkg/util" ) // MerkleBlock represents a merkle block packet payload. type MerkleBlock struct { - *core.BlockBase + *block.BlockBase TxCount int Hashes []util.Uint256 Flags []byte @@ -16,7 +16,7 @@ type MerkleBlock struct { // DecodeBinary implements Serializable interface. func (m *MerkleBlock) DecodeBinary(br *io.BinReader) { - m.BlockBase = &core.BlockBase{} + m.BlockBase = &block.BlockBase{} m.BlockBase.DecodeBinary(br) m.TxCount = int(br.ReadVarUint()) @@ -26,7 +26,7 @@ func (m *MerkleBlock) DecodeBinary(br *io.BinReader) { // EncodeBinary implements Serializable interface. func (m *MerkleBlock) EncodeBinary(bw *io.BinWriter) { - m.BlockBase = &core.BlockBase{} + m.BlockBase = &block.BlockBase{} m.BlockBase.EncodeBinary(bw) bw.WriteVarUint(uint64(m.TxCount)) diff --git a/pkg/network/server.go b/pkg/network/server.go index 9eabb5e7e..dbda99c9f 100644 --- a/pkg/network/server.go +++ b/pkg/network/server.go @@ -12,6 +12,7 @@ import ( "github.com/CityOfZion/neo-go/pkg/consensus" "github.com/CityOfZion/neo-go/pkg/core" + "github.com/CityOfZion/neo-go/pkg/core/block" "github.com/CityOfZion/neo-go/pkg/core/transaction" "github.com/CityOfZion/neo-go/pkg/network/payload" "github.com/CityOfZion/neo-go/pkg/util" @@ -400,7 +401,7 @@ func (s *Server) handleHeadersCmd(p Peer, headers *payload.Headers) { } // handleBlockCmd processes the received block received from its peer. -func (s *Server) handleBlockCmd(p Peer, block *core.Block) error { +func (s *Server) handleBlockCmd(p Peer, block *block.Block) error { return s.bQueue.putBlock(block) } @@ -505,7 +506,7 @@ func (s *Server) handleGetHeadersCmd(p Peer, gh *payload.GetBlocks) error { return err } resp := payload.Headers{} - resp.Hdrs = make([]*core.Header, 0, payload.MaxHeadersAllowed) + resp.Hdrs = make([]*block.Header, 0, payload.MaxHeadersAllowed) for i := start.Index + 1; i < start.Index+1+payload.MaxHeadersAllowed; i++ { hash := s.chain.GetHeaderHash(int(i)) if hash.Equals(util.Uint256{}) || hash.Equals(gh.HashStop) { @@ -632,7 +633,7 @@ func (s *Server) handleMessage(peer Peer, msg *Message) error { inventory := msg.Payload.(*payload.Inventory) return s.handleInvCmd(peer, inventory) case CMDBlock: - block := msg.Payload.(*core.Block) + block := msg.Payload.(*block.Block) return s.handleBlockCmd(peer, block) case CMDConsensus: cp := msg.Payload.(*consensus.Payload) @@ -689,7 +690,7 @@ func (s *Server) relayInventoryCmd(cmd CommandType, t payload.InventoryType, has } // relayBlock tells all the other connected nodes about the given block. -func (s *Server) relayBlock(b *core.Block) { +func (s *Server) relayBlock(b *block.Block) { s.relayInventoryCmd(CMDInv, payload.BlockType, b.Hash()) } diff --git a/pkg/rpc/server_helper_test.go b/pkg/rpc/server_helper_test.go index 5b0590f69..135e96f8a 100644 --- a/pkg/rpc/server_helper_test.go +++ b/pkg/rpc/server_helper_test.go @@ -7,6 +7,7 @@ import ( "github.com/CityOfZion/neo-go/config" "github.com/CityOfZion/neo-go/pkg/core" + "github.com/CityOfZion/neo-go/pkg/core/block" "github.com/CityOfZion/neo-go/pkg/core/storage" "github.com/CityOfZion/neo-go/pkg/io" "github.com/CityOfZion/neo-go/pkg/network" @@ -193,10 +194,10 @@ func initServerWithInMemoryChain(t *testing.T) (*core.Blockchain, http.HandlerFu nBlocks = br.ReadU32LE() require.Nil(t, br.Err) for i := 0; i < int(nBlocks); i++ { - block := &core.Block{} - block.DecodeBinary(br) + b := &block.Block{} + b.DecodeBinary(br) require.Nil(t, br.Err) - require.NoError(t, chain.AddBlock(block)) + require.NoError(t, chain.AddBlock(b)) } serverConfig := network.NewServerConfig(cfg) diff --git a/pkg/rpc/wrappers/block.go b/pkg/rpc/wrappers/block.go index 6c6a6ef56..77cf71bb0 100644 --- a/pkg/rpc/wrappers/block.go +++ b/pkg/rpc/wrappers/block.go @@ -2,14 +2,15 @@ package wrappers import ( "github.com/CityOfZion/neo-go/pkg/core" + "github.com/CityOfZion/neo-go/pkg/core/block" "github.com/CityOfZion/neo-go/pkg/util" ) type ( // Block wrapper used for the representation of - // core.Block / core.BlockBase on the RPC Server. + // block.Block / block.BlockBase on the RPC Server. Block struct { - *core.Block + *block.Block Confirmations uint32 `json:"confirmations"` NextBlockHash util.Uint256 `json:"nextblockhash,omitempty"` Hash util.Uint256 `json:"hash"` @@ -17,7 +18,7 @@ type ( ) // NewBlock creates a new Block wrapper. -func NewBlock(block *core.Block, chain core.Blockchainer) Block { +func NewBlock(block *block.Block, chain core.Blockchainer) Block { blockWrapper := Block{ Block: block, Hash: block.Hash(), diff --git a/pkg/rpc/wrappers/tx_raw_output.go b/pkg/rpc/wrappers/tx_raw_output.go index 7a8a6fcf7..53f3025c9 100644 --- a/pkg/rpc/wrappers/tx_raw_output.go +++ b/pkg/rpc/wrappers/tx_raw_output.go @@ -2,6 +2,7 @@ package wrappers import ( "github.com/CityOfZion/neo-go/pkg/core" + "github.com/CityOfZion/neo-go/pkg/core/block" "github.com/CityOfZion/neo-go/pkg/core/transaction" "github.com/CityOfZion/neo-go/pkg/io" "github.com/CityOfZion/neo-go/pkg/util" @@ -21,7 +22,7 @@ type TransactionOutputRaw struct { } // NewTransactionOutputRaw returns a new ransactionOutputRaw object. -func NewTransactionOutputRaw(tx *transaction.Transaction, header *core.Header, chain core.Blockchainer) TransactionOutputRaw { +func NewTransactionOutputRaw(tx *transaction.Transaction, header *block.Header, chain core.Blockchainer) TransactionOutputRaw { // confirmations formula confirmations := int(chain.BlockHeight() - header.BlockBase.Index + 1) // set index position From 489b88afbba54bcd9d4cd5ca13d5b8e2cfaaee1d Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Wed, 15 Jan 2020 11:29:50 +0300 Subject: [PATCH 2/5] block: rename BlockBase to Base --- pkg/consensus/block.go | 4 ++-- pkg/core/block/block.go | 8 ++++---- pkg/core/block/block_base.go | 24 ++++++++++++------------ pkg/core/block/block_test.go | 8 ++++---- pkg/core/block/header.go | 6 +++--- pkg/core/block/header_test.go | 2 +- pkg/core/dao_test.go | 4 ++-- pkg/core/helper_test.go | 4 ++-- pkg/core/util.go | 4 ++-- pkg/network/blockqueue_test.go | 2 +- pkg/network/payload/headers_test.go | 2 +- pkg/network/payload/merkleblock.go | 10 +++++----- pkg/rpc/wrappers/block.go | 2 +- pkg/rpc/wrappers/tx_raw_output.go | 2 +- 14 files changed, 41 insertions(+), 41 deletions(-) diff --git a/pkg/consensus/block.go b/pkg/consensus/block.go index f71f4bfb5..90824fe9e 100644 --- a/pkg/consensus/block.go +++ b/pkg/consensus/block.go @@ -20,7 +20,7 @@ var _ block.Block = (*neoBlock)(nil) // Sign implements block.Block interface. func (n *neoBlock) Sign(key crypto.PrivateKey) error { - data := n.BlockBase.GetHashableData() + data := n.Base.GetHashableData() sig, err := key.Sign(data[:]) if err != nil { return err @@ -33,7 +33,7 @@ func (n *neoBlock) Sign(key crypto.PrivateKey) error { // Verify implements block.Block interface. func (n *neoBlock) Verify(key crypto.PublicKey, sign []byte) error { - data := n.BlockBase.GetHashableData() + data := n.Base.GetHashableData() return key.Verify(data, sign) } diff --git a/pkg/core/block/block.go b/pkg/core/block/block.go index 3077095c7..4eb533a8d 100644 --- a/pkg/core/block/block.go +++ b/pkg/core/block/block.go @@ -14,7 +14,7 @@ import ( // Block represents one block in the chain. type Block struct { // The base of the block. - BlockBase + Base // Transaction list. Transactions []*transaction.Transaction `json:"tx"` @@ -26,7 +26,7 @@ type Block struct { // Header returns the Header of the Block. func (b *Block) Header() *Header { return &Header{ - BlockBase: b.BlockBase, + Base: b.Base, } } @@ -126,14 +126,14 @@ func (b *Block) Trim() ([]byte, error) { // DecodeBinary decodes the block from the given BinReader, implementing // Serializable interface. func (b *Block) DecodeBinary(br *io.BinReader) { - b.BlockBase.DecodeBinary(br) + b.Base.DecodeBinary(br) br.ReadArray(&b.Transactions) } // EncodeBinary encodes the block to the given BinWriter, implementing // Serializable interface. func (b *Block) EncodeBinary(bw *io.BinWriter) { - b.BlockBase.EncodeBinary(bw) + b.Base.EncodeBinary(bw) bw.WriteArray(b.Transactions) } diff --git a/pkg/core/block/block_base.go b/pkg/core/block/block_base.go index 404701059..8655ea9ac 100644 --- a/pkg/core/block/block_base.go +++ b/pkg/core/block/block_base.go @@ -9,8 +9,8 @@ import ( "github.com/CityOfZion/neo-go/pkg/util" ) -// BlockBase holds the base info of a block -type BlockBase struct { +// Base holds the base info of a block +type Base struct { // Version of the block. Version uint32 `json:"version"` @@ -47,14 +47,14 @@ type BlockBase struct { verificationHash util.Uint256 } -// Verify verifies the integrity of the BlockBase. -func (b *BlockBase) Verify() bool { +// Verify verifies the integrity of the Base. +func (b *Base) Verify() bool { // TODO: Need a persisted blockchain for this. return true } // Hash returns the hash of the block. -func (b *BlockBase) Hash() util.Uint256 { +func (b *Base) Hash() util.Uint256 { if b.hash.Equals(util.Uint256{}) { b.createHash() } @@ -62,7 +62,7 @@ func (b *BlockBase) Hash() util.Uint256 { } // VerificationHash returns the hash of the block used to verify it. -func (b *BlockBase) VerificationHash() util.Uint256 { +func (b *Base) VerificationHash() util.Uint256 { if b.verificationHash.Equals(util.Uint256{}) { b.createHash() } @@ -70,7 +70,7 @@ func (b *BlockBase) VerificationHash() util.Uint256 { } // DecodeBinary implements Serializable interface. -func (b *BlockBase) DecodeBinary(br *io.BinReader) { +func (b *Base) DecodeBinary(br *io.BinReader) { b.decodeHashableFields(br) padding := []byte{0} @@ -84,14 +84,14 @@ func (b *BlockBase) DecodeBinary(br *io.BinReader) { } // EncodeBinary implements Serializable interface -func (b *BlockBase) EncodeBinary(bw *io.BinWriter) { +func (b *Base) EncodeBinary(bw *io.BinWriter) { b.encodeHashableFields(bw) bw.WriteBytes([]byte{1}) b.Script.EncodeBinary(bw) } // GetHashableData returns serialized hashable data of the block. -func (b *BlockBase) GetHashableData() []byte { +func (b *Base) GetHashableData() []byte { buf := io.NewBufBinWriter() // No error can occure while encoding hashable fields. b.encodeHashableFields(buf.BinWriter) @@ -105,7 +105,7 @@ func (b *BlockBase) GetHashableData() []byte { // version, PrevBlock, MerkleRoot, timestamp, and height, the nonce, NextMiner. // Since MerkleRoot already contains the hash value of all transactions, // the modification of transaction will influence the hash value of the block. -func (b *BlockBase) createHash() { +func (b *Base) createHash() { bb := b.GetHashableData() b.verificationHash = hash.Sha256(bb) b.hash = hash.Sha256(b.verificationHash.BytesBE()) @@ -113,7 +113,7 @@ func (b *BlockBase) createHash() { // encodeHashableFields will only encode the fields used for hashing. // see Hash() for more information about the fields. -func (b *BlockBase) encodeHashableFields(bw *io.BinWriter) { +func (b *Base) encodeHashableFields(bw *io.BinWriter) { bw.WriteU32LE(b.Version) bw.WriteBytes(b.PrevHash[:]) bw.WriteBytes(b.MerkleRoot[:]) @@ -125,7 +125,7 @@ func (b *BlockBase) encodeHashableFields(bw *io.BinWriter) { // decodeHashableFields decodes the fields used for hashing. // see Hash() for more information about the fields. -func (b *BlockBase) decodeHashableFields(br *io.BinReader) { +func (b *Base) decodeHashableFields(br *io.BinReader) { b.Version = br.ReadU32LE() br.ReadBytes(b.PrevHash[:]) br.ReadBytes(b.MerkleRoot[:]) diff --git a/pkg/core/block/block_test.go b/pkg/core/block/block_test.go index 42355e9c0..571e404d3 100644 --- a/pkg/core/block/block_test.go +++ b/pkg/core/block/block_test.go @@ -79,7 +79,7 @@ func TestTrimmedBlock(t *testing.T) { func newDumbBlock() *Block { return &Block{ - BlockBase: BlockBase{ + Base: Base{ Version: 0, PrevHash: hash.Sha256([]byte("a")), MerkleRoot: hash.Sha256([]byte("b")), @@ -291,9 +291,9 @@ func TestBlockSizeCalculation(t *testing.T) { } func TestBlockCompare(t *testing.T) { - b1 := Block{BlockBase: BlockBase{Index: 1}} - b2 := Block{BlockBase: BlockBase{Index: 2}} - b3 := Block{BlockBase: BlockBase{Index: 3}} + b1 := Block{Base: Base{Index: 1}} + b2 := Block{Base: Base{Index: 2}} + b3 := Block{Base: Base{Index: 3}} assert.Equal(t, 1, b2.Compare(&b1)) assert.Equal(t, 0, b2.Compare(&b2)) assert.Equal(t, -1, b2.Compare(&b3)) diff --git a/pkg/core/block/header.go b/pkg/core/block/header.go index 5f9060f3d..98804870c 100644 --- a/pkg/core/block/header.go +++ b/pkg/core/block/header.go @@ -9,14 +9,14 @@ import ( // Header holds the head info of a block. type Header struct { // Base of the block. - BlockBase + Base // Padding that is fixed to 0. _ uint8 } // DecodeBinary implements Serializable interface. func (h *Header) DecodeBinary(r *io.BinReader) { - h.BlockBase.DecodeBinary(r) + h.Base.DecodeBinary(r) padding := []byte{0} r.ReadBytes(padding) @@ -28,6 +28,6 @@ func (h *Header) DecodeBinary(r *io.BinReader) { // EncodeBinary implements Serializable interface. func (h *Header) EncodeBinary(w *io.BinWriter) { - h.BlockBase.EncodeBinary(w) + h.Base.EncodeBinary(w) w.WriteBytes([]byte{0}) } diff --git a/pkg/core/block/header_test.go b/pkg/core/block/header_test.go index 020afcbda..d7ea801f5 100644 --- a/pkg/core/block/header_test.go +++ b/pkg/core/block/header_test.go @@ -12,7 +12,7 @@ import ( ) func TestHeaderEncodeDecode(t *testing.T) { - header := Header{BlockBase: BlockBase{ + header := Header{Base: Base{ Version: 0, PrevHash: hash.Sha256([]byte("prevhash")), MerkleRoot: hash.Sha256([]byte("merkleroot")), diff --git a/pkg/core/dao_test.go b/pkg/core/dao_test.go index cf06aa757..0bee6800f 100644 --- a/pkg/core/dao_test.go +++ b/pkg/core/dao_test.go @@ -262,7 +262,7 @@ func TestGetBlock_NotExists(t *testing.T) { func TestPutGetBlock(t *testing.T) { dao := newDao(storage.NewMemoryStore()) b := &block.Block{ - BlockBase: block.BlockBase{ + Base: block.Base{ Script: transaction.Witness{ VerificationScript: []byte{byte(opcode.PUSH1)}, InvocationScript: []byte{byte(opcode.NOP)}, @@ -303,7 +303,7 @@ func TestGetCurrentHeaderHeight_NoHeader(t *testing.T) { func TestGetCurrentHeaderHeight_Store(t *testing.T) { dao := newDao(storage.NewMemoryStore()) b := &block.Block{ - BlockBase: block.BlockBase{ + Base: block.Base{ Script: transaction.Witness{ VerificationScript: []byte{byte(opcode.PUSH1)}, InvocationScript: []byte{byte(opcode.NOP)}, diff --git a/pkg/core/helper_test.go b/pkg/core/helper_test.go index 9a452ffc9..915d33ea6 100644 --- a/pkg/core/helper_test.go +++ b/pkg/core/helper_test.go @@ -62,7 +62,7 @@ func newBlock(index uint32, txs ...*transaction.Transaction) *block.Block { VerificationScript: valScript, } b := &block.Block{ - BlockBase: block.BlockBase{ + Base: block.Base{ Version: 0, PrevHash: newBlockPrevHash, Timestamp: uint32(time.Now().UTC().Unix()) + index, @@ -144,7 +144,7 @@ func getBlockData(i int) (map[string]interface{}, error) { func newDumbBlock() *block.Block { return &block.Block{ - BlockBase: block.BlockBase{ + Base: block.Base{ Version: 0, PrevHash: hash.Sha256([]byte("a")), MerkleRoot: hash.Sha256([]byte("b")), diff --git a/pkg/core/util.go b/pkg/core/util.go index 3269035de..4465a0621 100644 --- a/pkg/core/util.go +++ b/pkg/core/util.go @@ -25,7 +25,7 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*block.Block, error) return nil, err } - base := block.BlockBase{ + base := block.Base{ Version: 0, PrevHash: util.Uint256{}, Timestamp: uint32(time.Date(2016, 7, 15, 15, 8, 21, 0, time.UTC).Unix()), @@ -50,7 +50,7 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*block.Block, error) scriptOut := hash.Hash160(rawScript) b := &block.Block{ - BlockBase: base, + Base: base, Transactions: []*transaction.Transaction{ { Type: transaction.MinerType, diff --git a/pkg/network/blockqueue_test.go b/pkg/network/blockqueue_test.go index 881759d33..62a43595f 100644 --- a/pkg/network/blockqueue_test.go +++ b/pkg/network/blockqueue_test.go @@ -15,7 +15,7 @@ func TestBlockQueue(t *testing.T) { bq := newBlockQueue(0, chain, zaptest.NewLogger(t)) blocks := make([]*block.Block, 11) for i := 1; i < 11; i++ { - blocks[i] = &block.Block{BlockBase: block.BlockBase{Index: uint32(i)}} + blocks[i] = &block.Block{Base: block.Base{Index: uint32(i)}} } // not the ones expected currently for i := 3; i < 5; i++ { diff --git a/pkg/network/payload/headers_test.go b/pkg/network/payload/headers_test.go index f9fa957d0..008804eb0 100644 --- a/pkg/network/payload/headers_test.go +++ b/pkg/network/payload/headers_test.go @@ -30,7 +30,7 @@ func newTestHeaders(n int) *Headers { for i := range headers.Hdrs { headers.Hdrs[i] = &block.Header{ - BlockBase: block.BlockBase{ + Base: block.Base{ Index: uint32(i + 1), Script: transaction.Witness{ InvocationScript: []byte{0x0}, diff --git a/pkg/network/payload/merkleblock.go b/pkg/network/payload/merkleblock.go index 9759a853c..2aa31033e 100644 --- a/pkg/network/payload/merkleblock.go +++ b/pkg/network/payload/merkleblock.go @@ -8,7 +8,7 @@ import ( // MerkleBlock represents a merkle block packet payload. type MerkleBlock struct { - *block.BlockBase + *block.Base TxCount int Hashes []util.Uint256 Flags []byte @@ -16,8 +16,8 @@ type MerkleBlock struct { // DecodeBinary implements Serializable interface. func (m *MerkleBlock) DecodeBinary(br *io.BinReader) { - m.BlockBase = &block.BlockBase{} - m.BlockBase.DecodeBinary(br) + m.Base = &block.Base{} + m.Base.DecodeBinary(br) m.TxCount = int(br.ReadVarUint()) br.ReadArray(&m.Hashes) @@ -26,8 +26,8 @@ func (m *MerkleBlock) DecodeBinary(br *io.BinReader) { // EncodeBinary implements Serializable interface. func (m *MerkleBlock) EncodeBinary(bw *io.BinWriter) { - m.BlockBase = &block.BlockBase{} - m.BlockBase.EncodeBinary(bw) + m.Base = &block.Base{} + m.Base.EncodeBinary(bw) bw.WriteVarUint(uint64(m.TxCount)) bw.WriteArray(m.Hashes) diff --git a/pkg/rpc/wrappers/block.go b/pkg/rpc/wrappers/block.go index 77cf71bb0..2380f2f27 100644 --- a/pkg/rpc/wrappers/block.go +++ b/pkg/rpc/wrappers/block.go @@ -8,7 +8,7 @@ import ( type ( // Block wrapper used for the representation of - // block.Block / block.BlockBase on the RPC Server. + // block.Block / block.Base on the RPC Server. Block struct { *block.Block Confirmations uint32 `json:"confirmations"` diff --git a/pkg/rpc/wrappers/tx_raw_output.go b/pkg/rpc/wrappers/tx_raw_output.go index 53f3025c9..cdc2723cb 100644 --- a/pkg/rpc/wrappers/tx_raw_output.go +++ b/pkg/rpc/wrappers/tx_raw_output.go @@ -24,7 +24,7 @@ type TransactionOutputRaw struct { // NewTransactionOutputRaw returns a new ransactionOutputRaw object. func NewTransactionOutputRaw(tx *transaction.Transaction, header *block.Header, chain core.Blockchainer) TransactionOutputRaw { // confirmations formula - confirmations := int(chain.BlockHeight() - header.BlockBase.Index + 1) + confirmations := int(chain.BlockHeight() - header.Base.Index + 1) // set index position for i, o := range tx.Outputs { o.Position = i From 79bceb3e40c65f49b23ee9412d5f33335ff6db61 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Wed, 15 Jan 2020 11:35:02 +0300 Subject: [PATCH 3/5] block: use require in tests --- pkg/core/block/block_test.go | 17 +++++------------ pkg/core/block/helper_test.go | 13 ++++--------- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/pkg/core/block/block_test.go b/pkg/core/block/block_test.go index 571e404d3..236ccebd8 100644 --- a/pkg/core/block/block_test.go +++ b/pkg/core/block/block_test.go @@ -9,20 +9,17 @@ import ( "github.com/CityOfZion/neo-go/pkg/encoding/address" "github.com/CityOfZion/neo-go/pkg/io" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) // Test blocks are blocks from mainnet with their corresponding index. func TestDecodeBlock1(t *testing.T) { data, err := getBlockData(1) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) b, err := hex.DecodeString(data["raw"].(string)) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) block := &Block{} r := io.NewBinReaderFromBuf(b) @@ -51,14 +48,10 @@ func TestTrimmedBlock(t *testing.T) { block := getDecodedBlock(t, 1) b, err := block.Trim() - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) trimmedBlock, err := NewBlockFromTrimmedBytes(b) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) assert.True(t, trimmedBlock.Trimmed) assert.Equal(t, block.Version, trimmedBlock.Version) diff --git a/pkg/core/block/helper_test.go b/pkg/core/block/helper_test.go index 31a8f29d8..8f3821cc6 100644 --- a/pkg/core/block/helper_test.go +++ b/pkg/core/block/helper_test.go @@ -8,25 +8,20 @@ import ( "testing" "github.com/CityOfZion/neo-go/pkg/io" + "github.com/stretchr/testify/require" ) func getDecodedBlock(t *testing.T, i int) *Block { data, err := getBlockData(i) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) b, err := hex.DecodeString(data["raw"].(string)) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) block := &Block{} r := io.NewBinReaderFromBuf(b) block.DecodeBinary(r) - if r.Err != nil { - t.Fatal(r.Err) - } + require.NoError(t, r.Err) return block } From fed6fba9b6249d7813b5a79d0801de74625cc336 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Wed, 15 Jan 2020 10:52:59 +0300 Subject: [PATCH 4/5] core: refactor out MemPool --- pkg/consensus/consensus_test.go | 9 ++++--- pkg/core/blockchain.go | 7 ++--- pkg/core/blockchainer.go | 5 ++-- pkg/core/{ => mempool}/feer.go | 2 +- pkg/core/{ => mempool}/mem_pool.go | 2 +- pkg/core/{ => mempool}/mem_pool_test.go | 9 ++++++- pkg/core/mempool/prometheus.go | 34 +++++++++++++++++++++++++ pkg/core/prometheus.go | 23 ----------------- pkg/network/helper_test.go | 3 ++- pkg/network/server.go | 3 ++- 10 files changed, 60 insertions(+), 37 deletions(-) rename pkg/core/{ => mempool}/feer.go (96%) rename pkg/core/{ => mempool}/mem_pool.go (99%) rename pkg/core/{ => mempool}/mem_pool_test.go (94%) create mode 100644 pkg/core/mempool/prometheus.go diff --git a/pkg/consensus/consensus_test.go b/pkg/consensus/consensus_test.go index 1cd450f77..08de02dd9 100644 --- a/pkg/consensus/consensus_test.go +++ b/pkg/consensus/consensus_test.go @@ -5,6 +5,7 @@ import ( "github.com/CityOfZion/neo-go/config" "github.com/CityOfZion/neo-go/pkg/core" + "github.com/CityOfZion/neo-go/pkg/core/mempool" "github.com/CityOfZion/neo-go/pkg/core/storage" "github.com/CityOfZion/neo-go/pkg/core/transaction" "github.com/CityOfZion/neo-go/pkg/util" @@ -20,7 +21,7 @@ func TestNewService(t *testing.T) { Type: transaction.MinerType, Data: &transaction.MinerTX{Nonce: 12345}, } - item := core.NewPoolItem(tx, new(feer)) + item := mempool.NewPoolItem(tx, new(feer)) srv.Chain.GetMemPool().TryAdd(tx.Hash(), item) var txx []block.Transaction @@ -38,7 +39,7 @@ func TestService_GetVerified(t *testing.T) { newMinerTx(4), } pool := srv.Chain.GetMemPool() - item := core.NewPoolItem(txs[3], new(feer)) + item := mempool.NewPoolItem(txs[3], new(feer)) require.True(t, pool.TryAdd(txs[3].Hash(), item)) @@ -65,7 +66,7 @@ func TestService_GetVerified(t *testing.T) { t.Run("more than half of the last proposal will be reused", func(t *testing.T) { for _, tx := range txs[:2] { - item := core.NewPoolItem(tx, new(feer)) + item := mempool.NewPoolItem(tx, new(feer)) require.True(t, pool.TryAdd(tx.Hash(), item)) } @@ -114,7 +115,7 @@ func TestService_getTx(t *testing.T) { require.Equal(t, nil, srv.getTx(h)) - item := core.NewPoolItem(tx, new(feer)) + item := mempool.NewPoolItem(tx, new(feer)) srv.Chain.GetMemPool().TryAdd(h, item) got := srv.getTx(h) diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index cd0da4930..0bf36e1dc 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -12,6 +12,7 @@ import ( "github.com/CityOfZion/neo-go/config" "github.com/CityOfZion/neo-go/pkg/core/block" + "github.com/CityOfZion/neo-go/pkg/core/mempool" "github.com/CityOfZion/neo-go/pkg/core/state" "github.com/CityOfZion/neo-go/pkg/core/storage" "github.com/CityOfZion/neo-go/pkg/core/transaction" @@ -77,7 +78,7 @@ type Blockchain struct { stopCh chan struct{} runToExitCh chan struct{} - memPool MemPool + memPool mempool.MemPool // cache for block verification keys. keyCache map[util.Uint160]map[string]*keys.PublicKey @@ -101,7 +102,7 @@ func NewBlockchain(s storage.Store, cfg config.ProtocolConfiguration, log *zap.L headersOpDone: make(chan struct{}), stopCh: make(chan struct{}), runToExitCh: make(chan struct{}), - memPool: NewMemPool(50000), + memPool: mempool.NewMemPool(50000), keyCache: make(map[util.Uint160]map[string]*keys.PublicKey), log: log, } @@ -951,7 +952,7 @@ func (bc *Blockchain) IsLowPriority(t *transaction.Transaction) bool { } // GetMemPool returns the memory pool of the blockchain. -func (bc *Blockchain) GetMemPool() MemPool { +func (bc *Blockchain) GetMemPool() mempool.MemPool { return bc.memPool } diff --git a/pkg/core/blockchainer.go b/pkg/core/blockchainer.go index fdeaa6072..15ade1c18 100644 --- a/pkg/core/blockchainer.go +++ b/pkg/core/blockchainer.go @@ -3,6 +3,7 @@ package core import ( "github.com/CityOfZion/neo-go/config" "github.com/CityOfZion/neo-go/pkg/core/block" + "github.com/CityOfZion/neo-go/pkg/core/mempool" "github.com/CityOfZion/neo-go/pkg/core/state" "github.com/CityOfZion/neo-go/pkg/core/storage" "github.com/CityOfZion/neo-go/pkg/core/transaction" @@ -38,7 +39,7 @@ type Blockchainer interface { GetTransaction(util.Uint256) (*transaction.Transaction, uint32, error) GetUnspentCoinState(util.Uint256) *UnspentCoinState References(t *transaction.Transaction) map[transaction.Input]*transaction.Output - Feer // fee interface + mempool.Feer // fee interface VerifyTx(*transaction.Transaction, *block.Block) error - GetMemPool() MemPool + GetMemPool() mempool.MemPool } diff --git a/pkg/core/feer.go b/pkg/core/mempool/feer.go similarity index 96% rename from pkg/core/feer.go rename to pkg/core/mempool/feer.go index 61adbe3ca..f92c0e1d1 100644 --- a/pkg/core/feer.go +++ b/pkg/core/mempool/feer.go @@ -1,4 +1,4 @@ -package core +package mempool import ( "github.com/CityOfZion/neo-go/pkg/core/transaction" diff --git a/pkg/core/mem_pool.go b/pkg/core/mempool/mem_pool.go similarity index 99% rename from pkg/core/mem_pool.go rename to pkg/core/mempool/mem_pool.go index 2a629d403..404149a2a 100644 --- a/pkg/core/mem_pool.go +++ b/pkg/core/mempool/mem_pool.go @@ -1,4 +1,4 @@ -package core +package mempool import ( "sort" diff --git a/pkg/core/mem_pool_test.go b/pkg/core/mempool/mem_pool_test.go similarity index 94% rename from pkg/core/mem_pool_test.go rename to pkg/core/mempool/mem_pool_test.go index b75419d17..6da40043b 100644 --- a/pkg/core/mem_pool_test.go +++ b/pkg/core/mempool/mem_pool_test.go @@ -1,4 +1,4 @@ -package core +package mempool import ( "testing" @@ -88,3 +88,10 @@ func TestMemPoolVerify(t *testing.T) { tx3.Inputs = append(tx3.Inputs, transaction.Input{PrevHash: inhash2, PrevIndex: 0}) require.Equal(t, false, mp.Verify(tx3)) } + +func newMinerTX() *transaction.Transaction { + return &transaction.Transaction{ + Type: transaction.MinerType, + Data: &transaction.MinerTX{}, + } +} diff --git a/pkg/core/mempool/prometheus.go b/pkg/core/mempool/prometheus.go new file mode 100644 index 000000000..3d8a6a585 --- /dev/null +++ b/pkg/core/mempool/prometheus.go @@ -0,0 +1,34 @@ +package mempool + +import "github.com/prometheus/client_golang/prometheus" + +var ( + //mempoolUnsortedTx prometheus metric. + mempoolUnsortedTx = prometheus.NewGauge( + prometheus.GaugeOpts{ + Help: "Mempool Unsorted TXs", + Name: "mempool_unsorted_tx", + Namespace: "neogo", + }, + ) + //mempoolUnverifiedTx prometheus metric. + mempoolUnverifiedTx = prometheus.NewGauge( + prometheus.GaugeOpts{ + Help: "Mempool Unverified TXs", + Name: "mempool_unverified_tx", + Namespace: "neogo", + }, + ) +) + +func init() { + prometheus.MustRegister( + mempoolUnsortedTx, + mempoolUnverifiedTx, + ) +} + +func updateMempoolMetrics(unsortedTxnLen int, unverifiedTxnLen int) { + mempoolUnsortedTx.Set(float64(unsortedTxnLen)) + mempoolUnverifiedTx.Set(float64(unverifiedTxnLen)) +} diff --git a/pkg/core/prometheus.go b/pkg/core/prometheus.go index b4bec8ca9..b81fb847d 100644 --- a/pkg/core/prometheus.go +++ b/pkg/core/prometheus.go @@ -30,22 +30,6 @@ var ( Namespace: "neogo", }, ) - //mempoolUnsortedTx prometheus metric. - mempoolUnsortedTx = prometheus.NewGauge( - prometheus.GaugeOpts{ - Help: "Mempool Unsorted TXs", - Name: "mempool_unsorted_tx", - Namespace: "neogo", - }, - ) - //mempoolUnverifiedTx prometheus metric. - mempoolUnverifiedTx = prometheus.NewGauge( - prometheus.GaugeOpts{ - Help: "Mempool Unverified TXs", - Name: "mempool_unverified_tx", - Namespace: "neogo", - }, - ) ) func init() { @@ -53,8 +37,6 @@ func init() { blockHeight, persistedHeight, headerHeight, - mempoolUnsortedTx, - mempoolUnverifiedTx, ) } @@ -69,8 +51,3 @@ func updateHeaderHeightMetric(hHeight int) { func updateBlockHeightMetric(bHeight uint32) { blockHeight.Set(float64(bHeight)) } - -func updateMempoolMetrics(unsortedTxnLen int, unverifiedTxnLen int) { - mempoolUnsortedTx.Set(float64(unsortedTxnLen)) - mempoolUnverifiedTx.Set(float64(unverifiedTxnLen)) -} diff --git a/pkg/network/helper_test.go b/pkg/network/helper_test.go index e71fde016..e78b8c20f 100644 --- a/pkg/network/helper_test.go +++ b/pkg/network/helper_test.go @@ -10,6 +10,7 @@ import ( "github.com/CityOfZion/neo-go/config" "github.com/CityOfZion/neo-go/pkg/core" "github.com/CityOfZion/neo-go/pkg/core/block" + "github.com/CityOfZion/neo-go/pkg/core/mempool" "github.com/CityOfZion/neo-go/pkg/core/state" "github.com/CityOfZion/neo-go/pkg/core/storage" "github.com/CityOfZion/neo-go/pkg/core/transaction" @@ -116,7 +117,7 @@ func (chain testChain) GetUnspentCoinState(util.Uint256) *core.UnspentCoinState panic("TODO") } -func (chain testChain) GetMemPool() core.MemPool { +func (chain testChain) GetMemPool() mempool.MemPool { panic("TODO") } diff --git a/pkg/network/server.go b/pkg/network/server.go index dbda99c9f..82eed386b 100644 --- a/pkg/network/server.go +++ b/pkg/network/server.go @@ -13,6 +13,7 @@ import ( "github.com/CityOfZion/neo-go/pkg/consensus" "github.com/CityOfZion/neo-go/pkg/core" "github.com/CityOfZion/neo-go/pkg/core/block" + "github.com/CityOfZion/neo-go/pkg/core/mempool" "github.com/CityOfZion/neo-go/pkg/core/transaction" "github.com/CityOfZion/neo-go/pkg/network/payload" "github.com/CityOfZion/neo-go/pkg/util" @@ -709,7 +710,7 @@ func (s *Server) RelayTxn(t *transaction.Transaction) RelayReason { // TODO: Implement Plugin.CheckPolicy? //if (!Plugin.CheckPolicy(transaction)) // return RelayResultReason.PolicyFail; - if ok := s.chain.GetMemPool().TryAdd(t.Hash(), core.NewPoolItem(t, s.chain)); !ok { + if ok := s.chain.GetMemPool().TryAdd(t.Hash(), mempool.NewPoolItem(t, s.chain)); !ok { return RelayOutOfMemory } From 28183b81d6c034e6c7bf9a57cc4eecebe9b4130a Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Wed, 15 Jan 2020 15:10:05 +0300 Subject: [PATCH 5/5] mempool: simplify names of exported types With the move to a separate package, naming can be simplified: MemPool -> Pool, PoolItem -> Item, PoolItems -> Items. --- pkg/core/blockchain.go | 4 +- pkg/core/blockchainer.go | 2 +- pkg/core/mempool/mem_pool.go | 94 ++++++++++++++++++------------------ pkg/network/helper_test.go | 2 +- 4 files changed, 51 insertions(+), 51 deletions(-) diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index 0bf36e1dc..c24de0535 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -78,7 +78,7 @@ type Blockchain struct { stopCh chan struct{} runToExitCh chan struct{} - memPool mempool.MemPool + memPool mempool.Pool // cache for block verification keys. keyCache map[util.Uint160]map[string]*keys.PublicKey @@ -952,7 +952,7 @@ func (bc *Blockchain) IsLowPriority(t *transaction.Transaction) bool { } // GetMemPool returns the memory pool of the blockchain. -func (bc *Blockchain) GetMemPool() mempool.MemPool { +func (bc *Blockchain) GetMemPool() mempool.Pool { return bc.memPool } diff --git a/pkg/core/blockchainer.go b/pkg/core/blockchainer.go index 15ade1c18..34b6d70cf 100644 --- a/pkg/core/blockchainer.go +++ b/pkg/core/blockchainer.go @@ -41,5 +41,5 @@ type Blockchainer interface { References(t *transaction.Transaction) map[transaction.Input]*transaction.Output mempool.Feer // fee interface VerifyTx(*transaction.Transaction, *block.Block) error - GetMemPool() mempool.MemPool + GetMemPool() mempool.Pool } diff --git a/pkg/core/mempool/mem_pool.go b/pkg/core/mempool/mem_pool.go index 404149a2a..444f2e36e 100644 --- a/pkg/core/mempool/mem_pool.go +++ b/pkg/core/mempool/mem_pool.go @@ -9,38 +9,38 @@ import ( "github.com/CityOfZion/neo-go/pkg/util" ) -// PoolItem represents a transaction in the the Memory pool. -type PoolItem struct { +// Item represents a transaction in the the Memory pool. +type Item struct { txn *transaction.Transaction timeStamp time.Time fee Feer } -// PoolItems slice of PoolItem. -type PoolItems []*PoolItem +// Items is a slice of Item. +type Items []*Item -// MemPool stores the unconfirms transactions. -type MemPool struct { +// Pool stores the unconfirms transactions. +type Pool struct { lock *sync.RWMutex - unsortedTxn map[util.Uint256]*PoolItem - unverifiedTxn map[util.Uint256]*PoolItem - sortedHighPrioTxn PoolItems - sortedLowPrioTxn PoolItems - unverifiedSortedHighPrioTxn PoolItems - unverifiedSortedLowPrioTxn PoolItems + unsortedTxn map[util.Uint256]*Item + unverifiedTxn map[util.Uint256]*Item + sortedHighPrioTxn Items + sortedLowPrioTxn Items + unverifiedSortedHighPrioTxn Items + unverifiedSortedLowPrioTxn Items capacity int } -func (p PoolItems) Len() int { return len(p) } -func (p PoolItems) Swap(i, j int) { p[i], p[j] = p[j], p[i] } -func (p PoolItems) Less(i, j int) bool { return p[i].CompareTo(p[j]) < 0 } +func (p Items) Len() int { return len(p) } +func (p Items) Swap(i, j int) { p[i], p[j] = p[j], p[i] } +func (p Items) Less(i, j int) bool { return p[i].CompareTo(p[j]) < 0 } -// CompareTo returns the difference between two PoolItems. +// CompareTo returns the difference between two Items. // difference < 0 implies p < otherP. // difference = 0 implies p = otherP. // difference > 0 implies p > otherP. -func (p PoolItem) CompareTo(otherP *PoolItem) int { +func (p Item) CompareTo(otherP *Item) int { if otherP == nil { return 1 } @@ -77,15 +77,15 @@ func (p PoolItem) CompareTo(otherP *PoolItem) int { } // Count returns the total number of uncofirm transactions. -func (mp MemPool) Count() int { +func (mp Pool) Count() int { mp.lock.RLock() defer mp.lock.RUnlock() return len(mp.unsortedTxn) + len(mp.unverifiedTxn) } -// ContainsKey checks if a transactions hash is in the MemPool. -func (mp MemPool) ContainsKey(hash util.Uint256) bool { +// ContainsKey checks if a transactions hash is in the Pool. +func (mp Pool) ContainsKey(hash util.Uint256) bool { mp.lock.RLock() defer mp.lock.RUnlock() @@ -100,9 +100,9 @@ func (mp MemPool) ContainsKey(hash util.Uint256) bool { return false } -// TryAdd try to add the PoolItem to the MemPool. -func (mp MemPool) TryAdd(hash util.Uint256, pItem *PoolItem) bool { - var pool PoolItems +// TryAdd try to add the Item to the Pool. +func (mp Pool) TryAdd(hash util.Uint256, pItem *Item) bool { + var pool Items mp.lock.Lock() if _, ok := mp.unsortedTxn[hash]; ok { @@ -135,13 +135,13 @@ func (mp MemPool) TryAdd(hash util.Uint256, pItem *PoolItem) bool { // Remove removes an item from the mempool, if it exists there (and does // nothing if it doesn't). -func (mp *MemPool) Remove(hash util.Uint256) { +func (mp *Pool) Remove(hash util.Uint256) { var mapAndPools = []struct { - unsortedMap map[util.Uint256]*PoolItem - sortedPools []*PoolItems + unsortedMap map[util.Uint256]*Item + sortedPools []*Items }{ - {unsortedMap: mp.unsortedTxn, sortedPools: []*PoolItems{&mp.sortedHighPrioTxn, &mp.sortedLowPrioTxn}}, - {unsortedMap: mp.unverifiedTxn, sortedPools: []*PoolItems{&mp.unverifiedSortedHighPrioTxn, &mp.unverifiedSortedLowPrioTxn}}, + {unsortedMap: mp.unsortedTxn, sortedPools: []*Items{&mp.sortedHighPrioTxn, &mp.sortedLowPrioTxn}}, + {unsortedMap: mp.unverifiedTxn, sortedPools: []*Items{&mp.unverifiedSortedHighPrioTxn, &mp.unverifiedSortedLowPrioTxn}}, } mp.lock.Lock() for _, mapAndPool := range mapAndPools { @@ -149,7 +149,7 @@ func (mp *MemPool) Remove(hash util.Uint256) { delete(mapAndPool.unsortedMap, hash) for _, pool := range mapAndPool.sortedPools { var num int - var item *PoolItem + var item *Item for num, item = range *pool { if hash.Equals(item.txn.Hash()) { break @@ -168,8 +168,8 @@ func (mp *MemPool) Remove(hash util.Uint256) { } // RemoveOverCapacity removes transactions with lowest fees until the total number of transactions -// in the MemPool is within the capacity of the MemPool. -func (mp *MemPool) RemoveOverCapacity() { +// in the Pool is within the capacity of the Pool. +func (mp *Pool) RemoveOverCapacity() { for mp.Count()-mp.capacity > 0 { mp.lock.Lock() if minItem, argPosition := getLowestFeeTransaction(mp.sortedLowPrioTxn, mp.unverifiedSortedLowPrioTxn); minItem != nil { @@ -205,27 +205,27 @@ func (mp *MemPool) RemoveOverCapacity() { } -// NewPoolItem returns a new PoolItem. -func NewPoolItem(t *transaction.Transaction, fee Feer) *PoolItem { - return &PoolItem{ +// NewPoolItem returns a new Item. +func NewPoolItem(t *transaction.Transaction, fee Feer) *Item { + return &Item{ txn: t, timeStamp: time.Now().UTC(), fee: fee, } } -// NewMemPool returns a new MemPool struct. -func NewMemPool(capacity int) MemPool { - return MemPool{ +// NewMemPool returns a new Pool struct. +func NewMemPool(capacity int) Pool { + return Pool{ lock: new(sync.RWMutex), - unsortedTxn: make(map[util.Uint256]*PoolItem), - unverifiedTxn: make(map[util.Uint256]*PoolItem), + unsortedTxn: make(map[util.Uint256]*Item), + unverifiedTxn: make(map[util.Uint256]*Item), capacity: capacity, } } // TryGetValue returns a transaction if it exists in the memory pool. -func (mp MemPool) TryGetValue(hash util.Uint256) (*transaction.Transaction, bool) { +func (mp Pool) TryGetValue(hash util.Uint256) (*transaction.Transaction, bool) { mp.lock.RLock() defer mp.lock.RUnlock() if pItem, ok := mp.unsortedTxn[hash]; ok { @@ -239,13 +239,13 @@ func (mp MemPool) TryGetValue(hash util.Uint256) (*transaction.Transaction, bool return nil, false } -// getLowestFeeTransaction returns the PoolItem with the lowest fee amongst the "verifiedTxnSorted" -// and "unverifiedTxnSorted" PoolItems along with a integer. The integer can assume two values, 1 and 2 which indicate -// that the PoolItem with the lowest fee was found in "verifiedTxnSorted" respectively in "unverifiedTxnSorted". +// getLowestFeeTransaction returns the Item with the lowest fee amongst the "verifiedTxnSorted" +// and "unverifiedTxnSorted" Items along with a integer. The integer can assume two values, 1 and 2 which indicate +// that the Item with the lowest fee was found in "verifiedTxnSorted" respectively in "unverifiedTxnSorted". // "verifiedTxnSorted" and "unverifiedTxnSorted" are sorted slice order by transaction fee ascending. This means that // the transaction with lowest fee start at index 0. // Reference: GetLowestFeeTransaction method in C# (https://github.com/neo-project/neo/blob/master/neo/Ledger/MemoryPool.cs) -func getLowestFeeTransaction(verifiedTxnSorted PoolItems, unverifiedTxnSorted PoolItems) (*PoolItem, int) { +func getLowestFeeTransaction(verifiedTxnSorted Items, unverifiedTxnSorted Items) (*Item, int) { minItem := min(unverifiedTxnSorted) verifiedMin := min(verifiedTxnSorted) if verifiedMin == nil || (minItem != nil && verifiedMin.CompareTo(minItem) >= 0) { @@ -259,7 +259,7 @@ func getLowestFeeTransaction(verifiedTxnSorted PoolItems, unverifiedTxnSorted Po // min returns the minimum item in a ascending sorted slice of pool items. // The function can't be applied to unsorted slice! -func min(sortedPool PoolItems) *PoolItem { +func min(sortedPool Items) *Item { if len(sortedPool) == 0 { return nil } @@ -268,7 +268,7 @@ func min(sortedPool PoolItems) *PoolItem { // GetVerifiedTransactions returns a slice of Input from all the transactions in the memory pool // whose hash is not included in excludedHashes. -func (mp *MemPool) GetVerifiedTransactions() []*transaction.Transaction { +func (mp *Pool) GetVerifiedTransactions() []*transaction.Transaction { mp.lock.RLock() defer mp.lock.RUnlock() @@ -286,7 +286,7 @@ func (mp *MemPool) GetVerifiedTransactions() []*transaction.Transaction { // Verify verifies if the inputs of a transaction tx are already used in any other transaction in the memory pool. // If yes, the transaction tx is not a valid transaction and the function return false. // If no, the transaction tx is a valid transaction and the function return true. -func (mp MemPool) Verify(tx *transaction.Transaction) bool { +func (mp Pool) Verify(tx *transaction.Transaction) bool { mp.lock.RLock() defer mp.lock.RUnlock() for _, item := range mp.unsortedTxn { diff --git a/pkg/network/helper_test.go b/pkg/network/helper_test.go index e78b8c20f..ddfec8e67 100644 --- a/pkg/network/helper_test.go +++ b/pkg/network/helper_test.go @@ -117,7 +117,7 @@ func (chain testChain) GetUnspentCoinState(util.Uint256) *core.UnspentCoinState panic("TODO") } -func (chain testChain) GetMemPool() mempool.MemPool { +func (chain testChain) GetMemPool() mempool.Pool { panic("TODO") }