From d3b0e469da7208d8cbfefcf022021d81345b29a0 Mon Sep 17 00:00:00 2001 From: steven Date: Thu, 20 Jun 2019 18:39:34 +0800 Subject: [PATCH 01/17] add block height check when run transaction (#916) * add block height check when run transaction * finetune the config height * update blockheight, estimate by ((two weeks block) * 2 + current blockheight) * make pickitem support both big.int and bytearray. ensure big.int do not expose to user * update opcode hight constant to future block --- common/config/config.go | 10 ++++ common/constants/constants.go | 4 ++ smartcontract/service/neovm/runtime_test.go | 4 +- smartcontract/smart_contract.go | 3 +- smartcontract/test/height_test.go | 65 +++++++++++++++++++++ vm/neovm/common_test.go | 2 +- vm/neovm/execution_engine.go | 4 +- vm/neovm/func_array.go | 2 +- vm/neovm/func_validate.go | 25 +++++++- 9 files changed, 110 insertions(+), 9 deletions(-) create mode 100644 smartcontract/test/height_test.go diff --git a/common/config/config.go b/common/config/config.go index d52a6e4bd8..971558e217 100644 --- a/common/config/config.go +++ b/common/config/config.go @@ -114,6 +114,16 @@ func GetStateHashCheckHeight(id uint32) uint32 { return STATE_HASH_CHECK_HEIGHT[id] } +var OPCODE_UPDATE_CHECK_HEIGHT = map[uint32]uint32{ + NETWORK_ID_MAIN_NET: constants.OPCODE_HEIGHT_UPDATE_FIRST_MAINNET, //Network main + NETWORK_ID_POLARIS_NET: constants.OPCODE_HEIGHT_UPDATE_FIRST_POLARIS, //Network polaris + NETWORK_ID_SOLO_NET: 0, //Network solo +} + +func GetOpcodeUpdateCheckHeight(id uint32) uint32 { + return OPCODE_UPDATE_CHECK_HEIGHT[id] +} + func GetNetworkName(id uint32) string { name, ok := NETWORK_NAME[id] if ok { diff --git a/common/constants/constants.go b/common/constants/constants.go index c863bc956a..e0d9bb5508 100644 --- a/common/constants/constants.go +++ b/common/constants/constants.go @@ -82,3 +82,7 @@ const ( // ledger state hash check height const STATE_HASH_HEIGHT_MAINNET = 3000000 const STATE_HASH_HEIGHT_POLARIS = 850000 + +// neovm opcode update check height +const OPCODE_HEIGHT_UPDATE_FIRST_MAINNET = 6000000 +const OPCODE_HEIGHT_UPDATE_FIRST_POLARIS = 2100000 diff --git a/smartcontract/service/neovm/runtime_test.go b/smartcontract/service/neovm/runtime_test.go index 3880d488ad..4e4e31e332 100644 --- a/smartcontract/service/neovm/runtime_test.go +++ b/smartcontract/service/neovm/runtime_test.go @@ -128,7 +128,7 @@ func TestStructRef(t *testing.T) { } func TestRuntimeBase58ToAddress(t *testing.T) { - vm := neovm.NewExecutionEngine() + vm := neovm.NewExecutionEngine(0) acc := account.NewAccount("") addr := acc.Address @@ -152,7 +152,7 @@ func TestRuntimeBase58ToAddress(t *testing.T) { } func TestRuntimeAddressToBase58(t *testing.T) { - vm := neovm.NewExecutionEngine() + vm := neovm.NewExecutionEngine(0) acc := account.NewAccount("") addr := acc.Address diff --git a/smartcontract/smart_contract.go b/smartcontract/smart_contract.go index 95f04b2773..581e852af9 100644 --- a/smartcontract/smart_contract.go +++ b/smartcontract/smart_contract.go @@ -126,6 +126,7 @@ func (this *SmartContract) NewExecuteEngine(code []byte) (context.Engine, error) if !this.checkContexts() { return nil, fmt.Errorf("%s", "engine over max limit!") } + service := &neovm.NeoVmService{ Store: this.Store, CacheDB: this.CacheDB, @@ -135,7 +136,7 @@ func (this *SmartContract) NewExecuteEngine(code []byte) (context.Engine, error) Time: this.Config.Time, Height: this.Config.Height, BlockHash: this.Config.BlockHash, - Engine: vm.NewExecutionEngine(), + Engine: vm.NewExecutionEngine(this.Config.Height), PreExec: this.PreExec, } return service, nil diff --git a/smartcontract/test/height_test.go b/smartcontract/test/height_test.go new file mode 100644 index 0000000000..5a21bca5ab --- /dev/null +++ b/smartcontract/test/height_test.go @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2018 The ontology Authors + * This file is part of The ontology library. + * + * The ontology is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ontology is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The ontology. If not, see . + */ + +package test + +import ( + "github.com/ontio/ontology/smartcontract" + "github.com/ontio/ontology/vm/neovm" + "github.com/ontio/ontology/vm/neovm/errors" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestHeight(t *testing.T) { + byteCode0 := []byte{ + byte(neovm.NEWMAP), + byte(neovm.PUSH0), + byte(neovm.HASKEY), + } + + byteCode1 := []byte{ + byte(neovm.NEWMAP), + byte(neovm.KEYS), + } + + byteCode2 := []byte{ + byte(neovm.NEWMAP), + byte(neovm.VALUES), + } + + bytecode := [...][]byte{byteCode0, byteCode1, byteCode2} + + for i := 0; i < 3; i++ { + config := &smartcontract.Config{ + Time: 10, + Height: 10, + //Tx: &types.Transaction{}, + } + sc := smartcontract.SmartContract{ + Config: config, + Gas: 100, + CacheDB: nil, + } + engine, err := sc.NewExecuteEngine(bytecode[i]) + + _, err = engine.Invoke() + + assert.EqualError(t, err, "[NeoVmService] vm execution error!: "+errors.ERR_NOT_SUPPORT_OPCODE.Error()) + } +} diff --git a/vm/neovm/common_test.go b/vm/neovm/common_test.go index 7b25a32fb2..f35469cc67 100644 --- a/vm/neovm/common_test.go +++ b/vm/neovm/common_test.go @@ -26,7 +26,7 @@ import ( ) func TestHash(t *testing.T) { - engine := NewExecutionEngine() + engine := NewExecutionEngine(0) engine.OpCode = HASH160 data := []byte{1, 2, 3, 4, 5, 6, 7, 8} diff --git a/vm/neovm/execution_engine.go b/vm/neovm/execution_engine.go index 814a20fcb7..fa6173f46a 100644 --- a/vm/neovm/execution_engine.go +++ b/vm/neovm/execution_engine.go @@ -22,12 +22,13 @@ import ( "github.com/ontio/ontology/vm/neovm/errors" ) -func NewExecutionEngine() *ExecutionEngine { +func NewExecutionEngine(BlockHeight uint32) *ExecutionEngine { var engine ExecutionEngine engine.EvaluationStack = NewRandAccessStack() engine.AltStack = NewRandAccessStack() engine.State = BREAK engine.OpCode = 0 + engine.BlockHeight = BlockHeight return &engine } @@ -37,6 +38,7 @@ type ExecutionEngine struct { State VMState Contexts []*ExecutionContext Context *ExecutionContext + BlockHeight uint32 OpCode OpCode OpExec OpExec } diff --git a/vm/neovm/func_array.go b/vm/neovm/func_array.go index c41ffaf3ec..5e9f5073d2 100644 --- a/vm/neovm/func_array.go +++ b/vm/neovm/func_array.go @@ -87,7 +87,7 @@ func opPickItem(e *ExecutionEngine) (VMState, error) { PushData(e, s[i]) case *types.Map: PushData(e, items.(*types.Map).TryGetValue(index)) - case *types.ByteArray: + default: bi, _ := index.GetBigInteger() i := int(bi.Int64()) a, _ := items.GetByteArray() diff --git a/vm/neovm/func_validate.go b/vm/neovm/func_validate.go index 3ba7639017..d2987b34f4 100644 --- a/vm/neovm/func_validate.go +++ b/vm/neovm/func_validate.go @@ -26,6 +26,7 @@ import ( "fmt" "github.com/ontio/ontology/common" + "github.com/ontio/ontology/common/config" "github.com/ontio/ontology/vm/neovm/errors" "github.com/ontio/ontology/vm/neovm/types" ) @@ -480,7 +481,7 @@ func validatePickItem(e *ExecutionEngine) error { if v := item.(*types.Map).TryGetValue(key); v == nil { return errors.ERR_MAP_NOT_EXIST } - case *types.ByteArray: + default: index, err := PeekBigInteger(e) if err != nil { return err @@ -495,8 +496,6 @@ func validatePickItem(e *ExecutionEngine) error { if index.Cmp(big.NewInt(int64(len(barr)))) >= 0 { return errors.ERR_OVER_MAX_ARRAY_SIZE } - default: - return fmt.Errorf("validatePickItem error: %s", errors.ERR_NOT_SUPPORT_TYPE) } return nil } @@ -670,6 +669,11 @@ func LogStackTrace(e *ExecutionEngine, needStackCount int, desc string) error { } func validatorHasKey(e *ExecutionEngine) error { + OpCodeUpdateHeight := config.GetOpcodeUpdateCheckHeight(config.DefConfig.P2PNode.NetworkId) + if e.BlockHeight <= OpCodeUpdateHeight { + return errors.ERR_NOT_SUPPORT_OPCODE + } + if err := LogStackTrace(e, 2, "[validatorHasKey]"); err != nil { return err } @@ -682,6 +686,11 @@ func validatorHasKey(e *ExecutionEngine) error { } func validatorKeys(e *ExecutionEngine) error { + OpCodeUpdateHeight := config.GetOpcodeUpdateCheckHeight(config.DefConfig.P2PNode.NetworkId) + if e.BlockHeight <= OpCodeUpdateHeight { + return errors.ERR_NOT_SUPPORT_OPCODE + } + if err := LogStackTrace(e, 1, "[validatorKeys]"); err != nil { return err } @@ -690,6 +699,11 @@ func validatorKeys(e *ExecutionEngine) error { } func validatorValues(e *ExecutionEngine) error { + OpCodeUpdateHeight := config.GetOpcodeUpdateCheckHeight(config.DefConfig.P2PNode.NetworkId) + if e.BlockHeight <= OpCodeUpdateHeight { + return errors.ERR_NOT_SUPPORT_OPCODE + } + if err := LogStackTrace(e, 1, "[validatorValues]"); err != nil { return err } @@ -698,6 +712,11 @@ func validatorValues(e *ExecutionEngine) error { } func validateDCALL(e *ExecutionEngine) error { + OpCodeUpdateHeight := config.GetOpcodeUpdateCheckHeight(config.DefConfig.P2PNode.NetworkId) + if e.BlockHeight <= OpCodeUpdateHeight { + return errors.ERR_NOT_SUPPORT_OPCODE + } + if err := LogStackTrace(e, 1, "[validatorValues]"); err != nil { return err } From cada27a24a15e7f3337917676a0efb5541642089 Mon Sep 17 00:00:00 2001 From: JunXi Xie Date: Fri, 28 Jun 2019 11:12:22 +0800 Subject: [PATCH 02/17] fix test faied (#987) --- consensus/vbft/node_utils_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/consensus/vbft/node_utils_test.go b/consensus/vbft/node_utils_test.go index d00485cae6..4d0aa6e56d 100644 --- a/consensus/vbft/node_utils_test.go +++ b/consensus/vbft/node_utils_test.go @@ -206,7 +206,7 @@ func testCalcParticipantPeers(t *testing.T, n, c int) { for _, p := range pc { peers[p] = true } - if len(peers) <= 2*c+1 { + if len(peers) < 2*c+1 { t.Fatalf("peers(%d, %d, %d, %d, %d, %d): %v, %v, %v", n, c, len(peers), len(pp), len(pe), len(pc), pp, pe, pc) } } From 6475ec61dc8def1c29670032f234d2d0524ca499 Mon Sep 17 00:00:00 2001 From: Edmond Date: Fri, 28 Jun 2019 19:48:51 +0800 Subject: [PATCH 03/17] fix Vbft Block serdes (#989) * fix Vbft Block serdes * enforce merkleRoot data in Block msg * fix error handlings --- consensus/vbft/msg_types_test.go | 28 +++++++++++++++++++++++++++ consensus/vbft/types.go | 33 +++++++++++++++++++------------- 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/consensus/vbft/msg_types_test.go b/consensus/vbft/msg_types_test.go index 04e75422f3..ad5f765614 100644 --- a/consensus/vbft/msg_types_test.go +++ b/consensus/vbft/msg_types_test.go @@ -434,3 +434,31 @@ func TestBlockFetchRespMsgDeserialize(t *testing.T) { } t.Logf("BlockFetchRespMsg Serialize succ: %v\n", respmsg.BlockNumber) } + +func TestBlockSerialization(t *testing.T) { + blk, err := constructBlock() + if err != nil { + t.Errorf("constructBlock failed: %v", err) + return + } + + data, err := blk.Serialize() + if err != nil { + t.Fatalf("serialize blk: %s", err) + } + + blk2 := &Block{} + if err := blk2.Deserialize(data); err != nil { + t.Fatalf("deserialize blk: %s", err) + } + + blk.EmptyBlock = nil + data2, err := blk.Serialize() + if err != nil { + t.Fatalf("serialize blk2: %s", err) + } + blk3 := &Block{} + if err := blk3.Deserialize(data2); err != nil { + t.Fatalf("deserialize blk2: %s", err) + } +} diff --git a/consensus/vbft/types.go b/consensus/vbft/types.go index 564ba884c0..3e5a54d72d 100644 --- a/consensus/vbft/types.go +++ b/consensus/vbft/types.go @@ -24,7 +24,6 @@ import ( "io" "github.com/ontio/ontology/common" - "github.com/ontio/ontology/common/log" "github.com/ontio/ontology/consensus/vbft/config" "github.com/ontio/ontology/core/types" ) @@ -78,6 +77,7 @@ func (blk *Block) Serialize() ([]byte, error) { payload := common.NewZeroCopySink(nil) payload.WriteVarBytes(sink.Bytes()) + payload.WriteBool(blk.EmptyBlock != nil) if blk.EmptyBlock != nil { sink2 := common.NewZeroCopySink(nil) blk.EmptyBlock.Serialization(sink2) @@ -109,22 +109,29 @@ func (blk *Block) Deserialize(data []byte) error { } var emptyBlock *types.Block - if source.Len() > 0 { + hasEmptyBlock, irr, eof := source.NextBool() + if irr { + return fmt.Errorf("read empty-block-bool: %s", common.ErrIrregularData) + } + if eof { + return fmt.Errorf("read empty-block-bool: %s", io.ErrUnexpectedEOF) + } + if hasEmptyBlock { buf2, _, irregular, eof := source.NextVarBytes() - if irregular == false && eof == false { - block2, err := types.BlockFromRawBytes(buf2) - if err == nil { - emptyBlock = block2 - } + if irregular || eof { + return fmt.Errorf("read empty block failed: %v, %v", irregular, eof) + } + block2, err := types.BlockFromRawBytes(buf2) + if err != nil { + return fmt.Errorf("deserialize empty blk failed: %s", err) } + emptyBlock = block2 } + var merkleRoot common.Uint256 - if source.Len() > 0 { - merkleRoot, eof = source.NextHash() - if eof { - log.Errorf("Block Deserialize merkleRoot") - return io.ErrUnexpectedEOF - } + merkleRoot, eof = source.NextHash() + if eof { + return fmt.Errorf("block deserialize merkleRoot: %s", io.ErrUnexpectedEOF) } blk.Block = block blk.EmptyBlock = emptyBlock From 0a679b195cd060a150741d8a1d1b4b0723eee30d Mon Sep 17 00:00:00 2001 From: lucas Date: Fri, 12 Jul 2019 22:47:16 +0800 Subject: [PATCH 04/17] Add repeat tx check in p2p (#995) * add repeat tx check in p2p * add lru cache to save tx in Link * gofmt * move duplicate tx check to TransactionHandle * fix checkDuplicateTx bug * go fmt * change printf fmt * change txCache init * refactor code * change store tx to store txhash --- p2pserver/common/p2p_common.go | 1 + p2pserver/link/link.go | 1 + p2pserver/message/utils/msg_handler.go | 12 ++++++++++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/p2pserver/common/p2p_common.go b/p2pserver/common/p2p_common.go index 519337bbc3..eb5d89b032 100644 --- a/p2pserver/common/p2p_common.go +++ b/p2pserver/common/p2p_common.go @@ -41,6 +41,7 @@ const ( REQ_INTERVAL = 3 //single request max interval in second MAX_REQ_RECORD_SIZE = 1000 //the maximum request record size MAX_RESP_CACHE_SIZE = 50 //the maximum response cache + MAX_TX_CACHE_SIZE = 100000 //the maximum txHash cache size ) //msg cmd const diff --git a/p2pserver/link/link.go b/p2pserver/link/link.go index 1a5fcb32ab..fa52db5371 100644 --- a/p2pserver/link/link.go +++ b/p2pserver/link/link.go @@ -131,6 +131,7 @@ func (this *Link) Rx() { log.Debugf("skip handle msgType:%s from:%d", msg.CmdType(), this.id) continue } + this.addReqRecord(msg) this.recvChan <- &types.MsgPayload{ Id: this.id, diff --git a/p2pserver/message/utils/msg_handler.go b/p2pserver/message/utils/msg_handler.go index 5af737ab1d..becad73fb2 100644 --- a/p2pserver/message/utils/msg_handler.go +++ b/p2pserver/message/utils/msg_handler.go @@ -43,6 +43,10 @@ import ( //respCache cache for some response data var respCache *lru.ARCCache +//Store txHash, using for rejecting duplicate tx +// thread safe +var txCache, _ = lru.NewARC(msgCommon.MAX_TX_CACHE_SIZE) + // AddrReqHandle handles the neighbor address request from peer func AddrReqHandle(data *msgTypes.MsgPayload, p2p p2p.P2P, pid *evtActor.PID, args ...interface{}) { log.Trace("[p2p]receive addr request message", data.Addr, data.Id) @@ -208,9 +212,13 @@ func TransactionHandle(data *msgTypes.MsgPayload, p2p p2p.P2P, pid *evtActor.PID log.Trace("[p2p]receive transaction message", data.Addr, data.Id) var trn = data.Payload.(*msgTypes.Trn) - actor.AddTransaction(trn.Txn) - log.Trace("[p2p]receive Transaction message hash", trn.Txn.Hash()) + if !txCache.Contains(trn.Txn.Hash()) { + txCache.Add(trn.Txn.Hash(), nil) + actor.AddTransaction(trn.Txn) + } else { + log.Tracef("[p2p]receive duplicate Transaction message, txHash: %x\n", trn.Txn.Hash()) + } } // VersionHandle handles version handshake protocol from peer From 7e356b18f88484573ddba1bdc89688b8d71eac66 Mon Sep 17 00:00:00 2001 From: Edmond Date: Wed, 17 Jul 2019 14:56:22 +0800 Subject: [PATCH 05/17] fix peerPool map concurrent accessing (#1032) --- consensus/vbft/peer_pool.go | 11 +++++++++++ consensus/vbft/service.go | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/consensus/vbft/peer_pool.go b/consensus/vbft/peer_pool.go index 1d0bc4ba7c..4196a061dd 100644 --- a/consensus/vbft/peer_pool.go +++ b/consensus/vbft/peer_pool.go @@ -234,6 +234,17 @@ func (pool *PeerPool) GetPeerPubKey(peerIdx uint32) keypair.PublicKey { return nil } +func (pool *PeerPool) GetAllPubKeys() map[uint32]keypair.PublicKey { + pool.lock.RLock() + defer pool.lock.RUnlock() + + keys := make(map[uint32]keypair.PublicKey) + for idx, peer := range pool.peers { + keys[idx] = peer.PubKey + } + return keys +} + func (pool *PeerPool) isPeerAlive(peerIdx uint32) bool { pool.lock.RLock() defer pool.lock.RUnlock() diff --git a/consensus/vbft/service.go b/consensus/vbft/service.go index 457b273a93..fdf6e6b71c 100644 --- a/consensus/vbft/service.go +++ b/consensus/vbft/service.go @@ -403,7 +403,7 @@ func (self *Server) updateChainConfig() error { log.Infof("updateChainConfig add peer index:%v,id:%v", p.ID, p.Index) } } - for index, peer := range self.peerPool.peers { + for index, peerPubKey := range self.peerPool.GetAllPubKeys() { _, present := peermap[index] if !present { if index == self.Index { @@ -411,7 +411,7 @@ func (self *Server) updateChainConfig() error { log.Infof("updateChainConfig remove index :%d", index) } else { if C, present := self.msgRecvC[index]; present { - pubkey := vconfig.PubkeyID(peer.PubKey) + pubkey := vconfig.PubkeyID(peerPubKey) self.peerPool.RemovePeerIndex(pubkey) log.Infof("updateChainConfig remove consensus:index:%d,id:%v", index, pubkey) C <- nil From d20429d02f0bb001ecac4c9a53720956f9734aef Mon Sep 17 00:00:00 2001 From: lucas Date: Thu, 18 Jul 2019 11:32:29 +0800 Subject: [PATCH 06/17] add disablelogfile support (#1015) --- cmd/usage.go | 1 + cmd/utils/flags.go | 4 ++++ main.go | 11 +++++++++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/cmd/usage.go b/cmd/usage.go index 820c0a675c..973bae9a02 100644 --- a/cmd/usage.go +++ b/cmd/usage.go @@ -99,6 +99,7 @@ var AppHelpFlagGroups = []flagGroup{ Flags: []cli.Flag{ utils.ConfigFlag, utils.LogLevelFlag, + utils.DisableLogFileFlag, utils.DisableEventLogFlag, utils.DataDirFlag, }, diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 10824171a9..16fdcfc908 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -44,6 +44,10 @@ var ( Usage: "Set the log level to `` (0~6). 0:Trace 1:Debug 2:Info 3:Warn 4:Error 5:Fatal 6:MaxLevel", Value: config.DEFAULT_LOG_LEVEL, } + DisableLogFileFlag = cli.BoolFlag{ + Name: "disable-log-file", + Usage: "Discard log output to file", + } DisableEventLogFlag = cli.BoolFlag{ Name: "disable-event-log", Usage: "Discard event log output by smart contract execution", diff --git a/main.go b/main.go index 749616a7ad..efc2eb980c 100644 --- a/main.go +++ b/main.go @@ -85,6 +85,7 @@ func setupAPP() *cli.App { //common setting utils.ConfigFlag, utils.LogLevelFlag, + utils.DisableLogFileFlag, utils.DisableEventLogFlag, utils.DataDirFlag, //account setting @@ -198,8 +199,14 @@ func startOntology(ctx *cli.Context) { func initLog(ctx *cli.Context) { //init log module logLevel := ctx.GlobalInt(utils.GetFlagName(utils.LogLevelFlag)) - alog.InitLog(log.PATH) - log.InitLog(logLevel, log.PATH, log.Stdout) + //if true, the log will not be output to the file + disableLogFile := ctx.GlobalBool(utils.GetFlagName(utils.DisableLogFileFlag)) + if disableLogFile { + log.InitLog(logLevel, log.Stdout) + } else { + alog.InitLog(log.PATH) + log.InitLog(logLevel, log.PATH, log.Stdout) + } } func initConfig(ctx *cli.Context) (*config.OntologyConfig, error) { From fef7a1f278068bb24808a9748ca4f58a432ea70e Mon Sep 17 00:00:00 2001 From: JunXi Xie Date: Thu, 18 Jul 2019 18:40:50 +0800 Subject: [PATCH 07/17] optimize chainstore call function,fix operator map panic (#1031) --- .gitignore | 1 + consensus/vbft/block_pool.go | 25 ++++++++- consensus/vbft/block_pool_test.go | 90 ++++++++++++++++++++++++++++++ consensus/vbft/chain_store.go | 25 +++++---- consensus/vbft/chain_store_test.go | 7 +-- consensus/vbft/msg_builder.go | 10 ++-- consensus/vbft/node_sync.go | 6 +- consensus/vbft/service.go | 30 +++++----- 8 files changed, 153 insertions(+), 41 deletions(-) create mode 100644 consensus/vbft/block_pool_test.go diff --git a/.gitignore b/.gitignore index 3054043a1c..efab609817 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ GoOnchain.iml vendor/* !vendor/github.com/ontio/ontology-crypto/* Chain/* +Chain /config/* nodectl ontology diff --git a/consensus/vbft/block_pool.go b/consensus/vbft/block_pool.go index 3af96680af..1e10e8c4a4 100644 --- a/consensus/vbft/block_pool.go +++ b/consensus/vbft/block_pool.go @@ -28,6 +28,7 @@ import ( "github.com/ontio/ontology-crypto/keypair" "github.com/ontio/ontology/common" "github.com/ontio/ontology/common/log" + "github.com/ontio/ontology/core/store/overlaydb" ) type BlockList []*Block @@ -88,7 +89,7 @@ func newBlockPool(server *Server, historyLen uint32, store *ChainStore) (*BlockP // load history blocks from chainstore for ; blkNum <= store.GetChainedBlockNum(); blkNum++ { - blk, err := store.GetBlock(blkNum) + blk, err := store.getBlock(blkNum) if err != nil { return nil, fmt.Errorf("failed to load block %d: %s", blkNum, err) } @@ -660,7 +661,7 @@ func (pool *BlockPool) setBlockSealed(block *Block, forEmpty bool, sigdata bool) if err := pool.chainStore.AddBlock(c.SealedBlock); err != nil { return fmt.Errorf("failed to seal block (%d) to chainstore: %s", blkNum, err) } - stateRoot, err := pool.chainStore.GetExecMerkleRoot(pool.chainStore.GetChainedBlockNum()) + stateRoot, err := pool.chainStore.getExecMerkleRoot(pool.chainStore.GetChainedBlockNum()) if err != nil { log.Errorf("handleBlockSubmit failed:%s", err) return nil @@ -691,7 +692,7 @@ func (pool *BlockPool) getSealedBlock(blockNum uint32) (*Block, common.Uint256) } // get from chainstore - blk, err := pool.chainStore.GetBlock(blockNum) + blk, err := pool.chainStore.getBlock(blockNum) if err != nil { log.Errorf("getSealedBlock %d err:%v", blockNum, err) return nil, common.Uint256{} @@ -755,3 +756,21 @@ func (pool *BlockPool) onBlockSealed(blockNum uint32) { delete(pool.candidateBlocks, n) } } + +func (pool *BlockPool) getExecMerkleRoot(blkNum uint32) (common.Uint256, error) { + pool.lock.RLock() + defer pool.lock.RUnlock() + return pool.chainStore.getExecMerkleRoot(blkNum) +} + +func (pool *BlockPool) getExecWriteSet(blkNum uint32) *overlaydb.MemDB { + pool.lock.RLock() + defer pool.lock.RUnlock() + return pool.chainStore.getExecWriteSet(blkNum) +} + +func (pool *BlockPool) submitBlock(blkNum uint32) error { + pool.lock.Lock() + defer pool.lock.Unlock() + return pool.chainStore.submitBlock(blkNum) +} diff --git a/consensus/vbft/block_pool_test.go b/consensus/vbft/block_pool_test.go new file mode 100644 index 0000000000..fcb49efb3b --- /dev/null +++ b/consensus/vbft/block_pool_test.go @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2018 The ontology Authors + * This file is part of The ontology library. + * + * The ontology is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ontology is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The ontology. If not, see . + */ + +package vbft + +import ( + "testing" + "time" + + "github.com/ontio/ontology/common" + "github.com/ontio/ontology/core/ledger" + "github.com/ontio/ontology/core/types" +) + +func buildTestBlockPool(t *testing.T) (*BlockPool, error) { + store := newTestChainStore(t) + return newBlockPool(nil, 64, store) +} + +func buildTestBlock(t *testing.T, lastBlock *types.Block, lgr *ledger.Ledger) (*Block, error) { + timestamp := uint32(time.Now().Unix()) + if timestamp <= lastBlock.Header.Timestamp { + timestamp = lastBlock.Header.Timestamp + 1 + } + txs := []*types.Transaction{} + txHash := []common.Uint256{} + txRoot := common.ComputeMerkleRoot(txHash) + blockRoot := lgr.GetBlockRootWithNewTxRoots(lastBlock.Header.Height, []common.Uint256{lastBlock.Header.TransactionsRoot, txRoot}) + + blkHeader := &types.Header{ + PrevBlockHash: lastBlock.Header.Hash(), + TransactionsRoot: txRoot, + BlockRoot: blockRoot, + Timestamp: timestamp, + Height: lastBlock.Header.Height + 1, + ConsensusData: common.GetNonce(), + ConsensusPayload: nil, + } + blk := &types.Block{ + Header: blkHeader, + Transactions: txs, + } + block := &Block{ + Block: blk, + } + return block, nil +} +func TestAddBlock(t *testing.T) { + blockpool, err := buildTestBlockPool(t) + if err != nil { + t.Errorf("buildTestBlockPool err:%s", err) + } + lastBlock, _ := blockpool.getSealedBlock(0) + if lastBlock == nil { + t.Errorf("getblock err") + } + t.Logf("block height:%d", blockpool.chainStore.GetChainedBlockNum()) + blk, err := buildTestBlock(t, lastBlock.Block, blockpool.chainStore.db) + if err != nil { + t.Errorf("buildTestBlock err:%s", err) + } + err = blockpool.chainStore.AddBlock(blk) + if err != nil { + t.Errorf("AddBlock err:%s", err) + } + merkleRoot, err := blockpool.getExecMerkleRoot(blockpool.chainStore.GetChainedBlockNum()) + if err != nil { + t.Errorf("getExecMerkleRoot err:%s", err) + } + t.Logf("block height:%d,merkleRoot:%s", blockpool.chainStore.GetChainedBlockNum(), merkleRoot.ToHexString()) + err = blockpool.submitBlock(blockpool.chainStore.GetChainedBlockNum()) + if err != nil { + t.Errorf("submitBlock err:%s", err) + } +} diff --git a/consensus/vbft/chain_store.go b/consensus/vbft/chain_store.go index 0336ec5433..cdfa88f4f6 100644 --- a/consensus/vbft/chain_store.go +++ b/consensus/vbft/chain_store.go @@ -55,7 +55,7 @@ func OpenBlockStore(db *ledger.Ledger, serverPid *actor.PID) (*ChainStore, error return nil, fmt.Errorf("GetStateMerkleRoot blockNum:%d, error :%s", chainstore.chainedBlockNum, err) } writeSet := overlaydb.NewMemDB(1, 1) - block, err := chainstore.GetBlock(chainstore.chainedBlockNum) + block, err := chainstore.getBlock(chainstore.chainedBlockNum) if err != nil { return nil, err } @@ -71,7 +71,7 @@ func (self *ChainStore) GetChainedBlockNum() uint32 { return self.chainedBlockNum } -func (self *ChainStore) GetExecMerkleRoot(blkNum uint32) (common.Uint256, error) { +func (self *ChainStore) getExecMerkleRoot(blkNum uint32) (common.Uint256, error) { if blk, present := self.pendingBlocks[blkNum]; blk != nil && present { return blk.execResult.MerkleRoot, nil } @@ -85,7 +85,7 @@ func (self *ChainStore) GetExecMerkleRoot(blkNum uint32) (common.Uint256, error) } -func (self *ChainStore) GetExecWriteSet(blkNum uint32) *overlaydb.MemDB { +func (self *ChainStore) getExecWriteSet(blkNum uint32) *overlaydb.MemDB { if blk, present := self.pendingBlocks[blkNum]; blk != nil && present { return blk.execResult.WriteSet } @@ -123,7 +123,7 @@ func (self *ChainStore) AddBlock(block *Block) error { panic("nil block header") } blkNum := self.GetChainedBlockNum() + 1 - err := self.SubmitBlock(blkNum - 1) + err := self.submitBlock(blkNum - 1) if err != nil { log.Errorf("chainstore blkNum:%d, SubmitBlock: %s", blkNum-1, err) } @@ -133,15 +133,18 @@ func (self *ChainStore) AddBlock(block *Block) error { return fmt.Errorf("chainstore AddBlock GetBlockExecResult: %s", err) } self.pendingBlocks[blkNum] = &PendingBlock{block: block, execResult: &execResult, hasSubmitted: false} - self.pid.Tell( - &message.BlockConsensusComplete{ - Block: block.Block, - }) + + if self.pid != nil { + self.pid.Tell( + &message.BlockConsensusComplete{ + Block: block.Block, + }) + } self.chainedBlockNum = blkNum return nil } -func (self *ChainStore) SubmitBlock(blkNum uint32) error { +func (self *ChainStore) submitBlock(blkNum uint32) error { if blkNum == 0 { return nil } @@ -150,15 +153,15 @@ func (self *ChainStore) SubmitBlock(blkNum uint32) error { if err != nil && blkNum > self.GetChainedBlockNum() { return fmt.Errorf("ledger add submitBlk (%d, %d) failed: %s", blkNum, self.GetChainedBlockNum(), err) } - submitBlk.hasSubmitted = true if _, present := self.pendingBlocks[blkNum-1]; present { delete(self.pendingBlocks, blkNum-1) } + submitBlk.hasSubmitted = true } return nil } -func (self *ChainStore) GetBlock(blockNum uint32) (*Block, error) { +func (self *ChainStore) getBlock(blockNum uint32) (*Block, error) { if blk, present := self.pendingBlocks[blockNum]; present { return blk.block, nil } diff --git a/consensus/vbft/chain_store_test.go b/consensus/vbft/chain_store_test.go index 70dd862b5d..548f19d55c 100644 --- a/consensus/vbft/chain_store_test.go +++ b/consensus/vbft/chain_store_test.go @@ -19,15 +19,14 @@ package vbft import ( - "os" - "testing" - "github.com/ontio/ontology-crypto/keypair" "github.com/ontio/ontology/account" "github.com/ontio/ontology/common/config" "github.com/ontio/ontology/common/log" "github.com/ontio/ontology/core/genesis" "github.com/ontio/ontology/core/ledger" + "os" + "testing" ) func newTestChainStore(t *testing.T) *ChainStore { @@ -37,7 +36,7 @@ func newTestChainStore(t *testing.T) *ChainStore { if acct == nil { t.Fatalf("GetDefaultAccount error: acc is nil") } - + os.RemoveAll(config.DEFAULT_DATA_DIR) db, err := ledger.NewLedger(config.DEFAULT_DATA_DIR, 0) if err != nil { t.Fatalf("NewLedger error %s", err) diff --git a/consensus/vbft/msg_builder.go b/consensus/vbft/msg_builder.go index 32621c8564..d82b2595cd 100644 --- a/consensus/vbft/msg_builder.go +++ b/consensus/vbft/msg_builder.go @@ -188,10 +188,10 @@ func (self *Server) constructBlock(blkNum uint32, prevBlkHash common.Uint256, tx for _, t := range txs { txHash = append(txHash, t.Hash()) } - lastBlock, err := self.chainStore.GetBlock(blkNum - 1) - if err != nil { - log.Errorf("constructBlock getlastblock err:%s,blknum:%d", err, blkNum-1) - return nil, err + lastBlock, _ := self.blockPool.getSealedBlock(blkNum - 1) + if lastBlock == nil { + log.Errorf("constructBlock getlastblock failed blknum:%d", blkNum-1) + return nil, fmt.Errorf("constructBlock getlastblock failed blknum:%d", blkNum-1) } txRoot := common.ComputeMerkleRoot(txHash) @@ -264,7 +264,7 @@ func (self *Server) constructProposalMsg(blkNum uint32, sysTxs, userTxs []*types if err != nil { return nil, fmt.Errorf("failed to constuct blk: %s", err) } - merkleRoot, err := self.chainStore.GetExecMerkleRoot(blkNum - 1) + merkleRoot, err := self.blockPool.getExecMerkleRoot(blkNum - 1) if err != nil { return nil, fmt.Errorf("failed to GetExecMerkleRoot: %s,blkNum:%d", err, (blkNum - 1)) } diff --git a/consensus/vbft/node_sync.go b/consensus/vbft/node_sync.go index 4a0fb893b3..73aab17a1c 100644 --- a/consensus/vbft/node_sync.go +++ b/consensus/vbft/node_sync.go @@ -131,7 +131,7 @@ func (self *Syncer) run() { self.server.Index, req.startBlockNum) } for ; req.startBlockNum <= req.targetBlockNum; req.startBlockNum++ { - blk, _ := self.server.chainStore.GetBlock(req.startBlockNum) + blk, _ := self.server.blockPool.getSealedBlock(req.startBlockNum) if blk == nil { log.Infof("server %d, on starting syncing %d, nil block from ledger", self.server.Index, req.startBlockNum) @@ -180,7 +180,7 @@ func (self *Syncer) run() { // FIXME: compete with ledger syncing var blk *Block if self.nextReqBlkNum <= ledger.DefLedger.GetCurrentBlockHeight() { - blk, _ = self.server.chainStore.GetBlock(self.nextReqBlkNum) + blk, _ = self.server.blockPool.getSealedBlock(self.nextReqBlkNum) } if blk == nil { blk = self.blockConsensusDone(self.pendingBlocks[self.nextReqBlkNum]) @@ -192,7 +192,7 @@ func (self *Syncer) run() { break } } else { - merkleRoot, err := self.server.chainStore.GetExecMerkleRoot(blkNum - 1) + merkleRoot, err := self.server.blockPool.getExecMerkleRoot(blkNum - 1) if err != nil { log.Errorf("failed to GetExecMerkleRoot: %s,blkNum:%d", err, (blkNum - 1)) break diff --git a/consensus/vbft/service.go b/consensus/vbft/service.go index fdf6e6b71c..9aaee67403 100644 --- a/consensus/vbft/service.go +++ b/consensus/vbft/service.go @@ -275,12 +275,12 @@ func (self *Server) NewConsensusPayload(payload *p2pmsg.ConsensusPayload) { } } -func (self *Server) LoadChainConfig(chainStore *ChainStore) error { +func (self *Server) LoadChainConfig(blkNum uint32) error { //get chainconfig from genesis block - block, err := chainStore.GetBlock(chainStore.GetChainedBlockNum()) - if err != nil { - return err + block, _ := self.blockPool.getSealedBlock(blkNum) + if block == nil { + return fmt.Errorf("getSealedBlock err height:%d", blkNum) } var cfg vconfig.ChainConfig if block.getNewChainConfig() != nil { @@ -289,9 +289,9 @@ func (self *Server) LoadChainConfig(chainStore *ChainStore) error { } else { cfgBlock := block if block.getLastConfigBlockNum() != math.MaxUint32 { - cfgBlock, err = chainStore.GetBlock(block.getLastConfigBlockNum()) - if err != nil { - return fmt.Errorf("failed to get cfg block: %s", err) + cfgBlock, _ = self.blockPool.getSealedBlock(block.getLastConfigBlockNum()) + if cfgBlock == nil { + return fmt.Errorf("failed to get cfg block height:%d", block.getLastConfigBlockNum()) } } if cfgBlock.getNewChainConfig() == nil { @@ -329,11 +329,11 @@ func (self *Server) LoadChainConfig(chainStore *ChainStore) error { if block == nil { return fmt.Errorf("failed to get sealed block (%d)", self.GetCommittedBlockNo()) } - - self.currentParticipantConfig, err = self.buildParticipantConfig(self.GetCurrentBlockNo(), block, self.config) + currentParticipantConfig, err := self.buildParticipantConfig(self.GetCurrentBlockNo(), block, self.config) if err != nil { return fmt.Errorf("failed to build participant config: %s", err) } + self.currentParticipantConfig = currentParticipantConfig return nil } @@ -453,7 +453,7 @@ func (self *Server) initialize() error { self.msgSendC = make(chan *SendMsgEvent, CAP_MSG_SEND_CHANNEL) self.quitC = make(chan struct{}) - if err := self.LoadChainConfig(store); err != nil { + if err := self.LoadChainConfig(store.GetChainedBlockNum()); err != nil { log.Errorf("failed to load config: %s", err) return fmt.Errorf("failed to load config: %s", err) } @@ -1096,7 +1096,7 @@ func (self *Server) processProposalMsg(msg *blockProposalMsg) { log.Errorf("BlockPrposalMessage check LastConfigBlockNum blocknum:%d,prvLastConfigBlockNum:%d,self LastConfigBlockNum:%d", msg.GetBlockNum(), blk.Info.LastConfigBlockNum, self.LastConfigBlockNum) return } - merkleRoot, err := self.chainStore.GetExecMerkleRoot(msgBlkNum - 1) + merkleRoot, err := self.blockPool.getExecMerkleRoot(msgBlkNum - 1) if err != nil { log.Errorf("failed to GetExecMerkleRoot: %s,blkNum:%d", err, (msgBlkNum - 1)) return @@ -1601,13 +1601,13 @@ func (self *Server) actionLoop() { if action.BlockNum > blkNum { continue } - stateRoot, err := self.chainStore.GetExecMerkleRoot(action.BlockNum) + stateRoot, err := self.blockPool.getExecMerkleRoot(action.BlockNum) if err != nil { log.Infof("handleBlockSubmit failed:%s", err) continue } if self.CheckSubmitBlock(action.BlockNum, stateRoot) { - if err := self.chainStore.SubmitBlock(action.BlockNum); err != nil { + if err := self.blockPool.submitBlock(action.BlockNum); err != nil { log.Errorf("SubmitBlock err:%s", err) } } @@ -2143,7 +2143,7 @@ func (self *Server) checkNeedUpdateChainConfig(blockNum uint32) bool { //checkUpdateChainConfig query leveldb check is force update func (self *Server) checkUpdateChainConfig(blkNum uint32) bool { - force, err := isUpdate(self.chainStore.GetExecWriteSet(blkNum-1), self.config.View) + force, err := isUpdate(self.blockPool.getExecWriteSet(blkNum-1), self.config.View) if err != nil { log.Errorf("checkUpdateChainConfig err:%s", err) return false @@ -2192,7 +2192,7 @@ func (self *Server) makeProposal(blkNum uint32, forEmpty bool) error { cfg := &vconfig.ChainConfig{} cfg = nil if self.checkNeedUpdateChainConfig(blkNum) || self.checkUpdateChainConfig(blkNum) { - chainconfig, err := getChainConfig(self.chainStore.GetExecWriteSet(blkNum-1), blkNum) + chainconfig, err := getChainConfig(self.blockPool.getExecWriteSet(blkNum-1), blkNum) if err != nil { return fmt.Errorf("getChainConfig failed:%s", err) } From 8ee5ac79260d2002703bf64e638f347d644103fd Mon Sep 17 00:00:00 2001 From: Edmond Date: Mon, 29 Jul 2019 15:15:44 +0800 Subject: [PATCH 08/17] NetMask: ignore mask if addr request is from mskPeer (#1041) * make no mask if addr request is from masked peers * update addr-req testcase --- p2pserver/message/utils/msg_handler.go | 36 +++-- p2pserver/message/utils/msg_handler_test.go | 166 +++++++++++++++++++- 2 files changed, 186 insertions(+), 16 deletions(-) diff --git a/p2pserver/message/utils/msg_handler.go b/p2pserver/message/utils/msg_handler.go index becad73fb2..69f37396bf 100644 --- a/p2pserver/message/utils/msg_handler.go +++ b/p2pserver/message/utils/msg_handler.go @@ -56,25 +56,37 @@ func AddrReqHandle(data *msgTypes.MsgPayload, p2p p2p.P2P, pid *evtActor.PID, ar return } - var addrStr []msgCommon.PeerAddr - addrStr = p2p.GetNeighborAddrs() + addrStr := p2p.GetNeighborAddrs() //check mask peers mskPeers := config.DefConfig.P2PNode.ReservedCfg.MaskPeers if config.DefConfig.P2PNode.ReservedPeersOnly && len(mskPeers) > 0 { - for i := 0; i < len(addrStr); i++ { - var ip net.IP - ip = addrStr[i].IpAddr[:] - address := ip.To16().String() - for j := 0; j < len(mskPeers); j++ { - if address == mskPeers[j] { - addrStr = append(addrStr[:i], addrStr[i+1:]...) - i-- - break + mskPeerMap := make(map[string]bool) + for _, mskAddr := range mskPeers { + mskPeerMap[mskAddr] = true + } + + // get remote peer IP + // if get remotePeerAddr failed, do masking anyway + remoteAddr, _ := remotePeer.GetAddr16() + var remoteIp net.IP = remoteAddr[:] + + // remove msk peers from neigh-addr-list + // if remotePeer is in msk-list, skip masking + if _, isMskPeer := mskPeerMap[remoteIp.String()]; !isMskPeer { + mskAddrList := make([]msgCommon.PeerAddr, 0) + for _, addr := range addrStr { + var ip net.IP + ip = addr.IpAddr[:] + address := ip.To16().String() + if _, present := mskPeerMap[address]; !present { + mskAddrList = append(mskAddrList, addr) } } + // replace with mskAddrList + addrStr = mskAddrList } - } + msg := msgpack.NewAddrs(addrStr) err := p2p.Send(remotePeer, msg) if err != nil { diff --git a/p2pserver/message/utils/msg_handler_test.go b/p2pserver/message/utils/msg_handler_test.go index d6f059e75a..f3cc8495c0 100644 --- a/p2pserver/message/utils/msg_handler_test.go +++ b/p2pserver/message/utils/msg_handler_test.go @@ -22,6 +22,8 @@ import ( "bytes" "encoding/binary" "encoding/hex" + "fmt" + "net" "os" "testing" "time" @@ -45,13 +47,27 @@ import ( ) var ( - network p2p.P2P + network *MockP2P ) +type MockP2P struct { + p2p.P2P + SentMsgs []types.Message // stores all mock msgs +} + +func (mock *MockP2P) Send(p *peer.Peer, msg types.Message) error { + mock.SentMsgs = append(mock.SentMsgs, msg) + return nil +} + +func NewMockP2p() *MockP2P { + return &MockP2P{netserver.NewNetServer(), make([]types.Message, 0)} +} + func TestMain(m *testing.M) { log.InitLog(log.InfoLog, log.Stdout) // Start local network server and create message router - network = netserver.NewNetServer() + network = NewMockP2p() events.Init() // Initial a ledger @@ -165,7 +181,10 @@ func TestVerAckHandle(t *testing.T) { } // TestAddrReqHandle tests Function AddrReqHandle handling an address req +// testcase: no-mask neighbor func TestAddrReqHandle(t *testing.T) { + network = NewMockP2p() + // Simulate a remote peer to be added to the neighbor peers var testID uint64 _, testPub, _ := keypair.GenerateKeyPair(keypair.PK_ECDSA, keypair.P256) @@ -178,22 +197,161 @@ func TestAddrReqHandle(t *testing.T) { remotePeer.UpdateInfo(time.Now(), 1, 12345678, 20336, testID, 0, 12345, "1.5.2") - remotePeer.Link.SetAddr("127.0.0.1:50010") + remotePeer.Link.SetAddr("127.0.0.1:1234") + remotePeer.Link.SetPort(1234) network.AddNbrNode(remotePeer) + remotePeer.SetState(msgCommon.ESTABLISH) // Construct an address request packet buf := msgpack.NewAddrReq() msg := &types.MsgPayload{ Id: testID, - Addr: "127.0.0.1:50010", + Addr: "test", + Payload: buf, + } + + // Invoke AddrReqHandle to handle the msg + AddrReqHandle(msg, network, nil) + + // all neighbor peers should be in rsp msg + for _, msg := range network.SentMsgs { + addrMsg, ok := msg.(*types.Addr) + if !ok { + t.Fatalf("invalid addr msg %s", msg.CmdType()) + } + if len(addrMsg.NodeAddrs) != 1 { + t.Fatalf("invalid addr count: %v", addrMsg.NodeAddrs) + } + var ip net.IP + ip = addrMsg.NodeAddrs[0].IpAddr[:] + addr := fmt.Sprintf("%v:%d", ip, addrMsg.NodeAddrs[0].Port) + if addr != remotePeer.Link.GetAddr() { + t.Fatalf("invalid addr: %s vs %s", addr, remotePeer.Link.GetAddr()) + } + } + + network.DelNbrNode(testID) +} + +// +// create two neighbors, one masked, one un-masked +// send addr-req from un-mask peer, get itself in addr-rsp +// +func TestAddrReqHandle_maskok(t *testing.T) { + network = NewMockP2p() + + // Simulate a remote peer to be added to the neighbor peers + testID := uint64(123456) + remotePeer := peer.NewPeer() + remotePeer.UpdateInfo(time.Now(), 1, 12345678, 20336, + testID, 0, 12345, "1.5.2") + remotePeer.Link.SetAddr("1.2.3.4:5001") + remotePeer.Link.SetPort(5001) + network.AddNbrNode(remotePeer) + remotePeer.SetState(msgCommon.ESTABLISH) + + testID2 := uint64(1234567) + remotePeer2 := peer.NewPeer() + remotePeer2.UpdateInfo(time.Now(), 1, 12345678, 20336, + testID2, 0, 12345, "1.5.2") + remotePeer2.Link.SetAddr("1.2.3.5:5002") + remotePeer2.Link.SetPort(5002) + network.AddNbrNode(remotePeer2) + remotePeer2.SetState(msgCommon.ESTABLISH) + + // Construct an address request packet + buf := msgpack.NewAddrReq() + + msg := &types.MsgPayload{ + Id: testID2, + Addr: "test", + Payload: buf, + } + + config.DefConfig.P2PNode.ReservedPeersOnly = true + config.DefConfig.P2PNode.ReservedCfg.MaskPeers = []string{"1.2.3.4"} + + // Invoke AddrReqHandle to handle the msg + AddrReqHandle(msg, network, nil) + + // verify 1.2.3.4 is masked + for _, msg := range network.SentMsgs { + addrMsg, ok := msg.(*types.Addr) + if !ok { + t.Fatalf("invalid addr msg %s", msg.CmdType()) + } + if len(addrMsg.NodeAddrs) != 1 { + t.Fatalf("invalid addr count: %v", addrMsg.NodeAddrs) + } + var ip net.IP + ip = addrMsg.NodeAddrs[0].IpAddr[:] + addr := fmt.Sprintf("%v:%d", ip, addrMsg.NodeAddrs[0].Port) + if addr != remotePeer2.Link.GetAddr() { + t.Fatalf("invalid addr: %s vs %s", addr, remotePeer2.Link.GetAddr()) + } + } + + network.DelNbrNode(testID) +} + +// +// create one masked neighbor +// send addr-req, get itself in addr-rsp +// +func TestAddrReqHandle_unmaskok(t *testing.T) { + network = NewMockP2p() + + // Simulate a remote peer to be added to the neighbor peers + var testID uint64 + _, testPub, _ := keypair.GenerateKeyPair(keypair.PK_ECDSA, keypair.P256) + key := keypair.SerializePublicKey(testPub) + err := binary.Read(bytes.NewBuffer(key[:8]), binary.LittleEndian, &(testID)) + assert.Nil(t, err) + + remotePeer := peer.NewPeer() + assert.NotNil(t, remotePeer) + + remotePeer.UpdateInfo(time.Now(), 1, 12345678, 20336, + testID, 0, 12345, "1.5.2") + remotePeer.Link.SetAddr("1.2.3.4:5001") + remotePeer.Link.SetPort(5001) + + network.AddNbrNode(remotePeer) + remotePeer.SetState(msgCommon.ESTABLISH) + + // Construct an address request packet + buf := msgpack.NewAddrReq() + + msg := &types.MsgPayload{ + Id: testID, + Addr: "test", Payload: buf, } + config.DefConfig.P2PNode.ReservedPeersOnly = true + config.DefConfig.P2PNode.ReservedCfg.MaskPeers = []string{"1.2.3.4"} + // Invoke AddrReqHandle to handle the msg AddrReqHandle(msg, network, nil) + for _, msg := range network.SentMsgs { + addrMsg, ok := msg.(*types.Addr) + if !ok { + t.Fatalf("invalid addr msg %s", msg.CmdType()) + } + if len(addrMsg.NodeAddrs) != 1 { + t.Fatalf("invalid addr count: %v", addrMsg.NodeAddrs) + } + var ip net.IP + ip = addrMsg.NodeAddrs[0].IpAddr[:] + addr := fmt.Sprintf("%v:%d", ip, addrMsg.NodeAddrs[0].Port) + if addr != remotePeer.Link.GetAddr() { + t.Fatalf("invalid addr: %s vs %s", addr, remotePeer.Link.GetAddr()) + } + } + network.DelNbrNode(testID) } From 919cd68b68aeff48828b1e53f051399bd82c7b42 Mon Sep 17 00:00:00 2001 From: steven Date: Mon, 29 Jul 2019 16:05:43 +0800 Subject: [PATCH 09/17] update neovm new opecode height restriction (#1042) * update neovm new opecode height restriction * fixed testnet neovm opcode height --- common/constants/constants.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/constants/constants.go b/common/constants/constants.go index e0d9bb5508..dd00cd16f0 100644 --- a/common/constants/constants.go +++ b/common/constants/constants.go @@ -84,5 +84,5 @@ const STATE_HASH_HEIGHT_MAINNET = 3000000 const STATE_HASH_HEIGHT_POLARIS = 850000 // neovm opcode update check height -const OPCODE_HEIGHT_UPDATE_FIRST_MAINNET = 6000000 +const OPCODE_HEIGHT_UPDATE_FIRST_MAINNET = 6300000 const OPCODE_HEIGHT_UPDATE_FIRST_POLARIS = 2100000 From 10ffce928d74131dc25844b713161d2ae7b1187c Mon Sep 17 00:00:00 2001 From: Alver Date: Fri, 2 Aug 2019 15:40:14 +0800 Subject: [PATCH 10/17] update ontology-crypto (#1045) --- glide.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glide.yaml b/glide.yaml index eae227a116..b8a13e3b1f 100644 --- a/glide.yaml +++ b/glide.yaml @@ -3,7 +3,7 @@ import: - package: github.com/ontio/ontology-eventbus version: v0.9.1 - package: github.com/ontio/ontology-crypto - version: v1.0.4 + version: v1.0.5 - package: github.com/howeyc/gopass - package: github.com/gorilla/websocket version: v1.2.0 From e5213d78c5c4cdd5819ab48f5d5f86e4174f479a Mon Sep 17 00:00:00 2001 From: Edmond Date: Tue, 13 Aug 2019 20:43:39 +0800 Subject: [PATCH 11/17] support go mod (#1053) * add go.mod * add golang.org/x/text and tools * update travis for gomod * fix .travis.yml, build image firstly * add GO111MODULE to travis config * format peer_pool.go with gofmt v1.12.x * remove .travis script test on windows --- .travis.yml | 11 ++--- consensus/vbft/peer_pool.go | 12 +++--- go.mod | 43 +++++++++++++++++++ go.sum | 86 +++++++++++++++++++++++++++++++++++++ 4 files changed, 141 insertions(+), 11 deletions(-) create mode 100644 go.mod create mode 100644 go.sum diff --git a/.travis.yml b/.travis.yml index e7c8d16389..0198455c9a 100755 --- a/.travis.yml +++ b/.travis.yml @@ -2,15 +2,16 @@ language: go go_import_path: github.com/ontio/ontology -install: - - go get github.com/Masterminds/glide - - glide install +os: + - linux + - osx go: - - 1.10.x + - "1.12.x" script: + - env GO111MODULE=on make all-cross + - env GO111MODULE=on go mod vendor - bash ./.travis.check-license.sh - bash ./.travis.gofmt.sh - - make all-cross - bash ./.travis.gotest.sh diff --git a/consensus/vbft/peer_pool.go b/consensus/vbft/peer_pool.go index 4196a061dd..8def86fdf4 100644 --- a/consensus/vbft/peer_pool.go +++ b/consensus/vbft/peer_pool.go @@ -51,12 +51,12 @@ type PeerPool struct { func NewPeerPool(maxSize int, server *Server) *PeerPool { return &PeerPool{ - maxSize: maxSize, - server: server, - configs: make(map[uint32]*vconfig.PeerConfig), - IDMap: make(map[string]uint32), - P2pMap: make(map[uint32]uint64), - peers: make(map[uint32]*Peer), + maxSize: maxSize, + server: server, + configs: make(map[uint32]*vconfig.PeerConfig), + IDMap: make(map[string]uint32), + P2pMap: make(map[uint32]uint64), + peers: make(map[uint32]*Peer), peerConnectionWaitings: make(map[uint32]chan struct{}), } } diff --git a/go.mod b/go.mod new file mode 100644 index 0000000000..1c2293eab1 --- /dev/null +++ b/go.mod @@ -0,0 +1,43 @@ +module github.com/ontio/ontology + +go 1.12 + +require ( + github.com/Workiva/go-datastructures v1.0.50 // indirect + github.com/emirpasic/gods v1.12.0 // indirect + github.com/ethereum/go-ethereum v1.8.23 + github.com/gogo/protobuf v1.2.1 // indirect + github.com/gorilla/websocket v1.2.0 + github.com/gosuri/uilive v0.0.3 // indirect + github.com/gosuri/uiprogress v0.0.1 + github.com/hashicorp/golang-lru v0.5.3 + github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c + github.com/itchyny/base58-go v0.0.5 + github.com/mattn/go-isatty v0.0.8 // indirect + github.com/ontio/ontology-crypto v1.0.5 + github.com/ontio/ontology-eventbus v0.9.1 + github.com/orcaman/concurrent-map v0.0.0-20190314100340-2693aad1ed75 // indirect + github.com/pborman/uuid v1.2.0 + github.com/stretchr/testify v1.3.0 + github.com/syndtr/goleveldb v1.0.0 + github.com/urfave/cli v1.21.0 + github.com/valyala/bytebufferpool v1.0.0 + golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 + golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 + golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f + golang.org/x/sys v0.0.0-20190412213103-97732733099d + golang.org/x/text v0.3.0 + golang.org/x/tools v0.0.0-20180221164845-07fd8470d635 +) + +replace golang.org/x/crypto => github.com/golang/crypto v0.0.0-20190701094942-4def268fd1a4 + +replace golang.org/x/net => github.com/golang/net v0.0.0-20190724013045-ca1201d0de80 + +replace golang.org/x/sys => github.com/golang/sys v0.0.0-20190412213103-97732733099d + +replace golang.org/x/text => github.com/golang/text v0.3.0 + +replace golang.org/x/sync => github.com/golang/sync v0.0.0-20180314180146-1d60e4601c6f + +replace golang.org/x/tools => github.com/golang/tools v0.0.0-20180221164845-07fd8470d635 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000000..6e117a834e --- /dev/null +++ b/go.sum @@ -0,0 +1,86 @@ +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Workiva/go-datastructures v1.0.50 h1:slDmfW6KCHcC7U+LP3DDBbm4fqTwZGn1beOFPfGaLvo= +github.com/Workiva/go-datastructures v1.0.50/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= +github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +github.com/ethereum/go-ethereum v1.8.23 h1:xVKYpRpe3cbkaWN8gsRgStsyTvz3s82PcQsbEofjhEQ= +github.com/ethereum/go-ethereum v1.8.23/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/crypto v0.0.0-20190701094942-4def268fd1a4 h1:SqpWDZAu6UkmbvUTCtyNpBZLY8110TJ7bgxIki3pZw0= +github.com/golang/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +github.com/golang/net v0.0.0-20190724013045-ca1201d0de80 h1:et5OvDLSg9BPhXWDs+vjO0wjO1cBLagpqT3346OSWsI= +github.com/golang/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:YCHYtYb9c8Q7XgYVYjmJBPtFPKx5QvOcPxHZWjldabE= +github.com/golang/sys v0.0.0-20190412213103-97732733099d h1:blRtD+FQOxZ6P7jigy+HS0R8zyGOMOv8TET4wCpzVwM= +github.com/golang/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +github.com/golang/text v0.3.0/go.mod h1:GUiq9pdJKRKKAZXiVgWFEvocYuREvC14NhI4OPgEjeE= +github.com/golang/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:BZR6KJOI/IQ5FlSQroxL7yevEMRCz1dARTXHD9s4mHE= +github.com/google/uuid v1.0.0 h1:b4Gk+7WdP/d3HZH8EJsZpvV7EtDOgaZLtnaNGIu1adA= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.2.0 h1:VJtLvh6VQym50czpZzx07z/kw9EgAxI3x1ZB8taTMQQ= +github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gosuri/uilive v0.0.3 h1:kvo6aB3pez9Wbudij8srWo4iY6SFTTxTKOkb+uRCE8I= +github.com/gosuri/uilive v0.0.3/go.mod h1:qkLSc0A5EXSP6B04TrN4oQoxqFI7A8XvoXSlJi8cwk8= +github.com/gosuri/uiprogress v0.0.1 h1:0kpv/XY/qTmFWl/SkaJykZXrBBzwwadmW8fRb7RJSxw= +github.com/gosuri/uiprogress v0.0.1/go.mod h1:C1RTYn4Sc7iEyf6j8ft5dyoZ4212h8G1ol9QQluh5+0= +github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= +github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c h1:kQWxfPIHVLbgLzphqk3QUflDy9QdksZR4ygR807bpy0= +github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/itchyny/base58-go v0.0.5 h1:uv3ieMgCtuE9HtN0Gux375+GOApFnifLkyvSseHBaH0= +github.com/itchyny/base58-go v0.0.5/go.mod h1:SrMWPE3DFuJJp1M/RUhu4fccp/y9AlB8AL3o3duPToU= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/ontio/ontology-crypto v1.0.5 h1:VYIEL9yF1d8vWxgLedqoQXKdyw2oY46NliGCQn1IKDM= +github.com/ontio/ontology-crypto v1.0.5/go.mod h1:ebrQJ4/VS2F6pwHGktHDYtY/7Y2ca/ogfnlYABrQI2c= +github.com/ontio/ontology-eventbus v0.9.1 h1:nt3AXWx3gOyqtLiU4EwI92Yc4ik/pWHu9xRK15uHSOs= +github.com/ontio/ontology-eventbus v0.9.1/go.mod h1:hCQIlbdPckcfykMeVUdWrqHZ8d30TBdmLfXCVWGkYhM= +github.com/orcaman/concurrent-map v0.0.0-20190314100340-2693aad1ed75 h1:IV56VwUb9Ludyr7s53CMuEh4DdTnnQtEPLEgLyJ0kHI= +github.com/orcaman/concurrent-map v0.0.0-20190314100340-2693aad1ed75/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI= +github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/urfave/cli v1.21.0 h1:wYSSj06510qPIzGSua9ZqsncMmWE3Zr55KBERygyrxE= +github.com/urfave/cli v1.21.0/go.mod h1:lxDj6qX9Q6lWQxIrbrT0nwecwUtRnhVZAJjJZrVUZZQ= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= From 18eee75e57656e194b840da3bb087f9d57f576f1 Mon Sep 17 00:00:00 2001 From: steven Date: Thu, 15 Aug 2019 16:08:43 +0800 Subject: [PATCH 12/17] add check block height for pickitem opcode (#1055) * add check block height for pickitem opcode * move block strict to neovm engine structure --- smartcontract/test/height_test.go | 14 ++++++++++++-- vm/neovm/execution_engine.go | 3 +++ vm/neovm/func_validate.go | 14 +++++++++----- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/smartcontract/test/height_test.go b/smartcontract/test/height_test.go index 5a21bca5ab..3c70aa9e30 100644 --- a/smartcontract/test/height_test.go +++ b/smartcontract/test/height_test.go @@ -43,9 +43,19 @@ func TestHeight(t *testing.T) { byte(neovm.VALUES), } - bytecode := [...][]byte{byteCode0, byteCode1, byteCode2} + byteCode3 := []byte{ + byte(0x4), + byte(0x0), + byte(0x1), + byte(0x2), + byte(0x3), + byte(neovm.PUSH1), + byte(neovm.PICKITEM), + } + + bytecode := [...][]byte{byteCode0, byteCode1, byteCode2, byteCode3} - for i := 0; i < 3; i++ { + for i := 0; i < 4; i++ { config := &smartcontract.Config{ Time: 10, Height: 10, diff --git a/vm/neovm/execution_engine.go b/vm/neovm/execution_engine.go index fa6173f46a..6e911115e2 100644 --- a/vm/neovm/execution_engine.go +++ b/vm/neovm/execution_engine.go @@ -19,6 +19,7 @@ package neovm import ( + "github.com/ontio/ontology/common/config" "github.com/ontio/ontology/vm/neovm/errors" ) @@ -29,6 +30,7 @@ func NewExecutionEngine(BlockHeight uint32) *ExecutionEngine { engine.State = BREAK engine.OpCode = 0 engine.BlockHeight = BlockHeight + engine.BlockHtLevel0 = config.GetOpcodeUpdateCheckHeight(config.DefConfig.P2PNode.NetworkId) return &engine } @@ -39,6 +41,7 @@ type ExecutionEngine struct { Contexts []*ExecutionContext Context *ExecutionContext BlockHeight uint32 + BlockHtLevel0 uint32 OpCode OpCode OpExec OpExec } diff --git a/vm/neovm/func_validate.go b/vm/neovm/func_validate.go index d2987b34f4..3f4a744968 100644 --- a/vm/neovm/func_validate.go +++ b/vm/neovm/func_validate.go @@ -26,7 +26,6 @@ import ( "fmt" "github.com/ontio/ontology/common" - "github.com/ontio/ontology/common/config" "github.com/ontio/ontology/vm/neovm/errors" "github.com/ontio/ontology/vm/neovm/types" ) @@ -482,6 +481,11 @@ func validatePickItem(e *ExecutionEngine) error { return errors.ERR_MAP_NOT_EXIST } default: + OpCodeUpdateHeight := e.BlockHtLevel0 + if e.BlockHeight <= OpCodeUpdateHeight { + return errors.ERR_NOT_SUPPORT_OPCODE + } + index, err := PeekBigInteger(e) if err != nil { return err @@ -669,7 +673,7 @@ func LogStackTrace(e *ExecutionEngine, needStackCount int, desc string) error { } func validatorHasKey(e *ExecutionEngine) error { - OpCodeUpdateHeight := config.GetOpcodeUpdateCheckHeight(config.DefConfig.P2PNode.NetworkId) + OpCodeUpdateHeight := e.BlockHtLevel0 if e.BlockHeight <= OpCodeUpdateHeight { return errors.ERR_NOT_SUPPORT_OPCODE } @@ -686,7 +690,7 @@ func validatorHasKey(e *ExecutionEngine) error { } func validatorKeys(e *ExecutionEngine) error { - OpCodeUpdateHeight := config.GetOpcodeUpdateCheckHeight(config.DefConfig.P2PNode.NetworkId) + OpCodeUpdateHeight := e.BlockHtLevel0 if e.BlockHeight <= OpCodeUpdateHeight { return errors.ERR_NOT_SUPPORT_OPCODE } @@ -699,7 +703,7 @@ func validatorKeys(e *ExecutionEngine) error { } func validatorValues(e *ExecutionEngine) error { - OpCodeUpdateHeight := config.GetOpcodeUpdateCheckHeight(config.DefConfig.P2PNode.NetworkId) + OpCodeUpdateHeight := e.BlockHtLevel0 if e.BlockHeight <= OpCodeUpdateHeight { return errors.ERR_NOT_SUPPORT_OPCODE } @@ -712,7 +716,7 @@ func validatorValues(e *ExecutionEngine) error { } func validateDCALL(e *ExecutionEngine) error { - OpCodeUpdateHeight := config.GetOpcodeUpdateCheckHeight(config.DefConfig.P2PNode.NetworkId) + OpCodeUpdateHeight := e.BlockHtLevel0 if e.BlockHeight <= OpCodeUpdateHeight { return errors.ERR_NOT_SUPPORT_OPCODE } From f8da8e9a3f127b2395089b9d8ef385a3136c01d2 Mon Sep 17 00:00:00 2001 From: NashMiao <18191964+NashMiao@users.noreply.github.com> Date: Wed, 21 Aug 2019 16:30:12 +0800 Subject: [PATCH 13/17] add omit block height in transaction list (#1057) --- http/base/common/common.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/http/base/common/common.go b/http/base/common/common.go index bedd09dde9..7e5ded1de5 100644 --- a/http/base/common/common.go +++ b/http/base/common/common.go @@ -264,7 +264,9 @@ func GetBlockInfo(block *types.Block) BlockInfo { trans := make([]*Transactions, len(block.Transactions)) for i := 0; i < len(block.Transactions); i++ { - trans[i] = TransArryByteToHexString(block.Transactions[i]) + tran := TransArryByteToHexString(block.Transactions[i]) + tran.Height = block.Header.Height + trans[i] = tran } b := BlockInfo{ From 2af0104a7f47fff86b5d7bf98b51c6390119de1e Mon Sep 17 00:00:00 2001 From: Zhou Peiwen Date: Thu, 22 Aug 2019 16:45:13 +0800 Subject: [PATCH 14/17] support address type in sigsvr (#1058) --- cmd/utils/params.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cmd/utils/params.go b/cmd/utils/params.go index 9f369f0324..228834d132 100644 --- a/cmd/utils/params.go +++ b/cmd/utils/params.go @@ -21,6 +21,7 @@ package utils import ( "encoding/hex" "fmt" + "github.com/ontio/ontology/common" "reflect" "strconv" "strings" @@ -34,6 +35,7 @@ const ( PARAM_TYPE_STRING = "string" PARAM_TYPE_INTEGER = "int" PARAM_TYPE_BOOLEAN = "bool" + PARAM_TYPE_ADDRESS = "address" PARAM_LEFT_BRACKET = "[" PARAM_RIGHT_BRACKET = "]" PARAM_ESC_CHAR = `/` @@ -194,6 +196,12 @@ func parseRawParamValue(pType string, pValue string) (interface{}, error) { default: return nil, fmt.Errorf("parse boolean param:%s failed", pValue) } + case PARAM_TYPE_ADDRESS: + address, err := common.AddressFromBase58(pValue) + if err != nil { + return nil, fmt.Errorf("parse address param:%s failed", pValue) + } + return address[:], nil default: return nil, fmt.Errorf("unspport param type:%s", pType) } From 888adb99280293d5adf2dda17b5068b931da97af Mon Sep 17 00:00:00 2001 From: tanyuan <1067598718@qq.com> Date: Wed, 28 Aug 2019 16:29:04 +0800 Subject: [PATCH 15/17] add assert api support --- smartcontract/service/neovm/config.go | 1 + smartcontract/service/neovm/neovm_service.go | 1 + smartcontract/service/neovm/runtime.go | 19 +++++++++++++++++++ smartcontract/service/neovm/runtime_test.go | 10 ++++++++++ 4 files changed, 31 insertions(+) diff --git a/smartcontract/service/neovm/config.go b/smartcontract/service/neovm/config.go index 6c0f3ecd9d..11249a7c42 100644 --- a/smartcontract/service/neovm/config.go +++ b/smartcontract/service/neovm/config.go @@ -104,6 +104,7 @@ var ( RUNTIME_ADDRESSTOBASE58_NAME = "Ontology.Runtime.AddressToBase58" RUNTIME_GETCURRENTBLOCKHASH_NAME = "Ontology.Runtime.GetCurrentBlockHash" RUNTIME_VERIFYMUTISIG_NAME = "Ontology.Runtime.VerifyMutiSig" + RUNTIME_ASSERT_NAME = "Ontology.Runtime.Assert" NATIVE_INVOKE_NAME = "Ontology.Native.Invoke" diff --git a/smartcontract/service/neovm/neovm_service.go b/smartcontract/service/neovm/neovm_service.go index 8b4ea20554..5afeebc244 100644 --- a/smartcontract/service/neovm/neovm_service.go +++ b/smartcontract/service/neovm/neovm_service.go @@ -89,6 +89,7 @@ var ( RUNTIME_BASE58TOADDRESS_NAME: {Execute: RuntimeBase58ToAddress}, RUNTIME_ADDRESSTOBASE58_NAME: {Execute: RuntimeAddressToBase58}, RUNTIME_GETCURRENTBLOCKHASH_NAME: {Execute: RuntimeGetCurrentBlockHash}, + RUNTIME_ASSERT_NAME: {Execute: RuntimeAssert}, } ) diff --git a/smartcontract/service/neovm/runtime.go b/smartcontract/service/neovm/runtime.go index 820a55c7f1..322a899326 100644 --- a/smartcontract/service/neovm/runtime.go +++ b/smartcontract/service/neovm/runtime.go @@ -20,6 +20,7 @@ package neovm import ( "bytes" + "fmt" "io" "reflect" "sort" @@ -212,6 +213,24 @@ func RuntimeGetCurrentBlockHash(service *NeoVmService, engine *vm.ExecutionEngin return nil } +func RuntimeAssert(service *NeoVmService, engine *vm.ExecutionEngine) error { + if vm.EvaluationStackCount(engine) < 2 { + return errors.NewErr("[RuntimeAssert] Too few input parameters") + } + ok, err := vm.PopBoolean(engine) + if err != nil { + return err + } + msg, err := vm.PopByteArray(engine) + if err != nil { + return err + } + if !ok { + return fmt.Errorf("%s", string(msg)) + } + return nil +} + func SerializeStackItem(item vmtypes.StackItems) ([]byte, error) { if CircularRefAndDepthDetection(item) { return nil, errors.NewErr("runtime serialize: can not serialize circular reference data") diff --git a/smartcontract/service/neovm/runtime_test.go b/smartcontract/service/neovm/runtime_test.go index 4e4e31e332..989503ea8f 100644 --- a/smartcontract/service/neovm/runtime_test.go +++ b/smartcontract/service/neovm/runtime_test.go @@ -175,3 +175,13 @@ func TestRuntimeAddressToBase58(t *testing.T) { assert.NoError(t, err) assert.Equal(t, base58, string(result)) } + +func TestRuntimeAssert(t *testing.T) { + engine := neovm.NewExecutionEngine(0) + + msg := "invalid parameters" + engine.EvaluationStack.Push(types.NewByteArray([]byte(msg))) + engine.EvaluationStack.Push(types.NewBoolean(false)) + err := RuntimeAssert(nil, engine) + assert.Equal(t, msg, err.Error()) +} From bd2782744a2f059b70f33198aba18ed873f2d2c3 Mon Sep 17 00:00:00 2001 From: tanyuan <1067598718@qq.com> Date: Thu, 29 Aug 2019 10:53:40 +0800 Subject: [PATCH 16/17] rename --- smartcontract/service/neovm/config.go | 2 +- smartcontract/service/neovm/neovm_service.go | 2 +- smartcontract/service/neovm/runtime.go | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/smartcontract/service/neovm/config.go b/smartcontract/service/neovm/config.go index 11249a7c42..7f19434b57 100644 --- a/smartcontract/service/neovm/config.go +++ b/smartcontract/service/neovm/config.go @@ -104,7 +104,7 @@ var ( RUNTIME_ADDRESSTOBASE58_NAME = "Ontology.Runtime.AddressToBase58" RUNTIME_GETCURRENTBLOCKHASH_NAME = "Ontology.Runtime.GetCurrentBlockHash" RUNTIME_VERIFYMUTISIG_NAME = "Ontology.Runtime.VerifyMutiSig" - RUNTIME_ASSERT_NAME = "Ontology.Runtime.Assert" + RUNTIME_ONTASSERT_NAME = "Ontology.Runtime.OntAssert" NATIVE_INVOKE_NAME = "Ontology.Native.Invoke" diff --git a/smartcontract/service/neovm/neovm_service.go b/smartcontract/service/neovm/neovm_service.go index 5afeebc244..2f0d0b9ca3 100644 --- a/smartcontract/service/neovm/neovm_service.go +++ b/smartcontract/service/neovm/neovm_service.go @@ -89,7 +89,7 @@ var ( RUNTIME_BASE58TOADDRESS_NAME: {Execute: RuntimeBase58ToAddress}, RUNTIME_ADDRESSTOBASE58_NAME: {Execute: RuntimeAddressToBase58}, RUNTIME_GETCURRENTBLOCKHASH_NAME: {Execute: RuntimeGetCurrentBlockHash}, - RUNTIME_ASSERT_NAME: {Execute: RuntimeAssert}, + RUNTIME_ONTASSERT_NAME: {Execute: RuntimeOntAssert}, } ) diff --git a/smartcontract/service/neovm/runtime.go b/smartcontract/service/neovm/runtime.go index 322a899326..64bae91bda 100644 --- a/smartcontract/service/neovm/runtime.go +++ b/smartcontract/service/neovm/runtime.go @@ -213,9 +213,9 @@ func RuntimeGetCurrentBlockHash(service *NeoVmService, engine *vm.ExecutionEngin return nil } -func RuntimeAssert(service *NeoVmService, engine *vm.ExecutionEngine) error { +func RuntimeOntAssert(service *NeoVmService, engine *vm.ExecutionEngine) error { if vm.EvaluationStackCount(engine) < 2 { - return errors.NewErr("[RuntimeAssert] Too few input parameters") + return errors.NewErr("[RuntimeOntAssert] Too few input parameters") } ok, err := vm.PopBoolean(engine) if err != nil { From 040450470c9f7a8a6eb8fea3025e630437866689 Mon Sep 17 00:00:00 2001 From: tanyuan <1067598718@qq.com> Date: Thu, 29 Aug 2019 11:16:42 +0800 Subject: [PATCH 17/17] fix test error --- smartcontract/service/neovm/runtime_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smartcontract/service/neovm/runtime_test.go b/smartcontract/service/neovm/runtime_test.go index 989503ea8f..ca2e183009 100644 --- a/smartcontract/service/neovm/runtime_test.go +++ b/smartcontract/service/neovm/runtime_test.go @@ -182,6 +182,6 @@ func TestRuntimeAssert(t *testing.T) { msg := "invalid parameters" engine.EvaluationStack.Push(types.NewByteArray([]byte(msg))) engine.EvaluationStack.Push(types.NewBoolean(false)) - err := RuntimeAssert(nil, engine) + err := RuntimeOntAssert(nil, engine) assert.Equal(t, msg, err.Error()) }