From c7a8ae519b46538d15a854e640afcf1e8f4c4ade Mon Sep 17 00:00:00 2001 From: eve2adam Date: Mon, 1 Apr 2019 11:37:51 +0900 Subject: [PATCH 001/148] [ctr/lua]add feature about getting state data at blockheight - system.getItem(key, blockheight) - state.snapget(map object, key, blockheight) - state.snapget(array object, index, blockheight) - state.snapget(value object, blockheight) --- chain/chainhandle.go | 11 +++-- chain/chainhandle_test.go | 18 +++---- chain/chainservice.go | 2 +- consensus/impl/dpos/blockfactory.go | 6 +-- consensus/impl/raft/blockfactory.go | 6 +-- consensus/impl/sbp/sbp.go | 6 +-- contract/contract.go | 6 +-- contract/state_module.c | 72 ++++++++++++++++++++++++++- contract/system_module.c | 24 +++++++-- contract/vm.go | 16 ++++-- contract/vm_callback.go | 48 +++++++++++++++++- contract/vm_dummy.go | 29 +++++++---- contract/vm_test.go | 76 +++++++++++++++++++++++++++++ 13 files changed, 273 insertions(+), 47 deletions(-) diff --git a/chain/chainhandle.go b/chain/chainhandle.go index 75f87ebbc..c3807ad37 100644 --- a/chain/chainhandle.go +++ b/chain/chainhandle.go @@ -524,7 +524,7 @@ func newBlockExecutor(cs *ChainService, bState *state.BlockState, block *types.B bState = state.NewBlockState(cs.sdb.OpenNewStateDB(cs.sdb.GetRoot())) - exec = NewTxExecutor(block.BlockNo(), block.GetHeader().GetTimestamp(), block.GetHeader().GetPrevBlockHash(), contract.ChainService) + exec = NewTxExecutor(cs.cdb, block.BlockNo(), block.GetHeader().GetTimestamp(), block.GetHeader().GetPrevBlockHash(), contract.ChainService) validateSignWait = func() error { return cs.validator.WaitVerifyDone() @@ -551,7 +551,7 @@ func newBlockExecutor(cs *ChainService, bState *state.BlockState, block *types.B } // NewTxExecutor returns a new TxExecFn. -func NewTxExecutor(blockNo types.BlockNo, ts int64, prevBlockHash []byte, preLoadService int) TxExecFn { +func NewTxExecutor(cdb contract.ChainAccessor, blockNo types.BlockNo, ts int64, prevBlockHash []byte, preLoadService int) TxExecFn { return func(bState *state.BlockState, tx types.Transaction) error { if bState == nil { logger.Error().Msg("bstate is nil in txexec") @@ -559,7 +559,7 @@ func NewTxExecutor(blockNo types.BlockNo, ts int64, prevBlockHash []byte, preLoa } snapshot := bState.Snapshot() - err := executeTx(bState, tx, blockNo, ts, prevBlockHash, preLoadService) + err := executeTx(cdb, bState, tx, blockNo, ts, prevBlockHash, preLoadService) if err != nil { logger.Error().Err(err).Str("hash", enc.ToString(tx.GetHash())).Msg("tx failed") bState.Rollback(snapshot) @@ -701,7 +701,7 @@ func (cs *ChainService) notifyEvents(block *types.Block, bstate *state.BlockStat } } -func executeTx(bs *state.BlockState, tx types.Transaction, blockNo uint64, ts int64, prevBlockHash []byte, preLoadService int) error { +func executeTx(cdb contract.ChainAccessor, bs *state.BlockState, tx types.Transaction, blockNo uint64, ts int64, prevBlockHash []byte, preLoadService int) error { txBody := tx.GetBody() @@ -751,7 +751,8 @@ func executeTx(bs *state.BlockState, tx types.Transaction, blockNo uint64, ts in var events []*types.Event switch txBody.Type { case types.TxType_NORMAL: - rv, txFee, events, err = contract.Execute(bs, tx.GetTx(), blockNo, ts, prevBlockHash, sender, receiver, preLoadService) + rv, txFee, events, err = contract.Execute(bs, cdb, tx.GetTx(), blockNo, ts, prevBlockHash, + sender, receiver, preLoadService) sender.SubBalance(txFee) case types.TxType_GOVERNANCE: txFee = new(big.Int).SetUint64(0) diff --git a/chain/chainhandle_test.go b/chain/chainhandle_test.go index 80d7af8c1..2e0489177 100644 --- a/chain/chainhandle_test.go +++ b/chain/chainhandle_test.go @@ -62,31 +62,31 @@ func TestErrorInExecuteTx(t *testing.T) { tx := &types.Tx{} - err := executeTx(bs, types.NewTransaction(tx), 0, 0, nil, contract.ChainService) + err := executeTx(nil, bs, types.NewTransaction(tx), 0, 0, nil, contract.ChainService) assert.EqualError(t, err, types.ErrTxFormatInvalid.Error(), "execute empty tx") tx.Body = &types.TxBody{} - err = executeTx(bs, types.NewTransaction(tx), 0, 0, nil, contract.ChainService) + err = executeTx(nil, bs, types.NewTransaction(tx), 0, 0, nil, contract.ChainService) assert.EqualError(t, err, types.ErrTxFormatInvalid.Error(), "execute empty tx body") tx.Body.Account = makeTestAddress(t) tx.Body.Recipient = makeTestAddress(t) - err = executeTx(bs, types.NewTransaction(tx), 0, 0, nil, contract.ChainService) + err = executeTx(nil, bs, types.NewTransaction(tx), 0, 0, nil, contract.ChainService) assert.EqualError(t, err, types.ErrTxHasInvalidHash.Error(), "execute tx body with account") signTestAddress(t, tx) - err = executeTx(bs, types.NewTransaction(tx), 0, 0, nil, contract.ChainService) + err = executeTx(nil, bs, types.NewTransaction(tx), 0, 0, nil, contract.ChainService) assert.EqualError(t, err, types.ErrTxNonceTooLow.Error(), "execute tx body with account") tx.Body.Nonce = 1 tx.Body.Amount = new(big.Int).SetUint64(math.MaxUint64).Bytes() signTestAddress(t, tx) - err = executeTx(bs, types.NewTransaction(tx), 0, 0, nil, contract.ChainService) + err = executeTx(nil, bs, types.NewTransaction(tx), 0, 0, nil, contract.ChainService) assert.EqualError(t, err, types.ErrInsufficientBalance.Error(), "execute tx body with nonce") tx.Body.Amount = types.MaxAER.Bytes() signTestAddress(t, tx) - err = executeTx(bs, types.NewTransaction(tx), 0, 0, nil, contract.ChainService) + err = executeTx(nil, bs, types.NewTransaction(tx), 0, 0, nil, contract.ChainService) assert.EqualError(t, err, types.ErrInsufficientBalance.Error(), "execute tx body with nonce") } @@ -101,13 +101,13 @@ func TestBasicExecuteTx(t *testing.T) { tx.Body.Recipient = makeTestAddress(t) tx.Body.Nonce = 1 signTestAddress(t, tx) - err := executeTx(bs, types.NewTransaction(tx), 0, 0, nil, contract.ChainService) + err := executeTx(nil, bs, types.NewTransaction(tx), 0, 0, nil, contract.ChainService) assert.NoError(t, err, "execute amount 0") tx.Body.Nonce = 2 tx.Body.Amount = new(big.Int).SetUint64(1000).Bytes() signTestAddress(t, tx) - err = executeTx(bs, types.NewTransaction(tx), 0, 0, nil, contract.ChainService) + err = executeTx(nil, bs, types.NewTransaction(tx), 0, 0, nil, contract.ChainService) assert.NoError(t, err, "execute amount 1000") tx.Body.Nonce = 3 @@ -116,7 +116,7 @@ func TestBasicExecuteTx(t *testing.T) { tx.Body.Type = types.TxType_GOVERNANCE tx.Body.Payload = []byte(`{"Name":"v1stake"}`) signTestAddress(t, tx) - err = executeTx(bs, types.NewTransaction(tx), 0, 0, nil, contract.ChainService) + err = executeTx(nil, bs, types.NewTransaction(tx), 0, 0, nil, contract.ChainService) assert.NoError(t, err, "execute governance type") } diff --git a/chain/chainservice.go b/chain/chainservice.go index aa7e77d22..75e7eda8f 100644 --- a/chain/chainservice.go +++ b/chain/chainservice.go @@ -671,7 +671,7 @@ func (cw *ChainWorker) Receive(context actor.Context) { context.Respond(message.GetQueryRsp{Result: nil, Err: err}) } else { bs := state.NewBlockState(cw.sdb.OpenNewStateDB(cw.sdb.GetRoot())) - ret, err := contract.Query(msg.Contract, bs, ctrState, msg.Queryinfo) + ret, err := contract.Query(msg.Contract, bs, cw.cdb, ctrState, msg.Queryinfo) context.Respond(message.GetQueryRsp{Result: ret, Err: err}) } case *message.GetStateQuery: diff --git a/consensus/impl/dpos/blockfactory.go b/consensus/impl/dpos/blockfactory.go index bc7ea3707..fe46faaa6 100644 --- a/consensus/impl/dpos/blockfactory.go +++ b/consensus/impl/dpos/blockfactory.go @@ -31,10 +31,10 @@ type txExec struct { execTx bc.TxExecFn } -func newTxExec(blockNo types.BlockNo, ts int64, prevHash []byte) chain.TxOp { +func newTxExec(cdb contract.ChainAccessor, blockNo types.BlockNo, ts int64, prevHash []byte) chain.TxOp { // Block hash not determined yet return &txExec{ - execTx: bc.NewTxExecutor(blockNo, ts, prevHash, contract.BlockFactory), + execTx: bc.NewTxExecutor(cdb, blockNo, ts, prevHash, contract.BlockFactory), } } @@ -217,7 +217,7 @@ func (bf *BlockFactory) generateBlock(bpi *bpInfo, lpbNo types.BlockNo) (block * txOp := chain.NewCompTxOp( bf.txOp, - newTxExec(bpi.bestBlock.GetHeader().GetBlockNo()+1, ts, bpi.bestBlock.GetHeader().GetPrevBlockHash()), + newTxExec(contract.ChainAccessor(bpi.ChainDB), bpi.bestBlock.GetHeader().GetBlockNo()+1, ts, bpi.bestBlock.GetHeader().GetPrevBlockHash()), ) block, err = chain.GenerateBlock(bf, bpi.bestBlock, bs, txOp, ts, false) diff --git a/consensus/impl/raft/blockfactory.go b/consensus/impl/raft/blockfactory.go index 8969c3151..c1796ba4d 100644 --- a/consensus/impl/raft/blockfactory.go +++ b/consensus/impl/raft/blockfactory.go @@ -50,10 +50,10 @@ type txExec struct { execTx bc.TxExecFn } -func newTxExec(blockNo types.BlockNo, ts int64, prevHash []byte) chain.TxOp { +func newTxExec(cdb consensus.ChainDB, blockNo types.BlockNo, ts int64, prevHash []byte) chain.TxOp { // Block hash not determined yet return &txExec{ - execTx: bc.NewTxExecutor(blockNo, ts, prevHash, contract.BlockFactory), + execTx: bc.NewTxExecutor(contract.ChainAccessor(cdb), blockNo, ts, prevHash, contract.BlockFactory), } } @@ -270,7 +270,7 @@ func (bf *BlockFactory) Start() { txOp := chain.NewCompTxOp( bf.txOp, - newTxExec(prevBlock.GetHeader().GetBlockNo()+1, ts, prevBlock.GetHash()), + newTxExec(bf.ChainDB, prevBlock.GetHeader().GetBlockNo()+1, ts, prevBlock.GetHash()), ) block, err := chain.GenerateBlock(bf, prevBlock, blockState, txOp, ts, RaftSkipEmptyBlock) diff --git a/consensus/impl/sbp/sbp.go b/consensus/impl/sbp/sbp.go index 33210952c..86ac3d928 100644 --- a/consensus/impl/sbp/sbp.go +++ b/consensus/impl/sbp/sbp.go @@ -31,10 +31,10 @@ type txExec struct { execTx bc.TxExecFn } -func newTxExec(blockNo types.BlockNo, ts int64, prevHash []byte) chain.TxOp { +func newTxExec(cdb consensus.ChainDB, blockNo types.BlockNo, ts int64, prevHash []byte) chain.TxOp { // Block hash not determined yet return &txExec{ - execTx: bc.NewTxExecutor(blockNo, ts, prevHash, contract.BlockFactory), + execTx: bc.NewTxExecutor(contract.ChainAccessor(cdb), blockNo, ts, prevHash, contract.BlockFactory), } } @@ -184,7 +184,7 @@ func (s *SimpleBlockFactory) Start() { txOp := chain.NewCompTxOp( s.txOp, - newTxExec(prevBlock.GetHeader().GetBlockNo()+1, ts, prevBlock.GetHash()), + newTxExec(s.ChainDB, prevBlock.GetHeader().GetBlockNo()+1, ts, prevBlock.GetHash()), ) block, err := chain.GenerateBlock(s, prevBlock, blockState, txOp, ts, false) diff --git a/contract/contract.go b/contract/contract.go index ea42bd27f..5caed16d5 100644 --- a/contract/contract.go +++ b/contract/contract.go @@ -48,7 +48,7 @@ func SetPreloadTx(tx *types.Tx, service int) { preLoadInfos[service].requestedTx = tx } -func Execute(bs *state.BlockState, tx *types.Tx, blockNo uint64, ts int64, prevBlockHash []byte, +func Execute(bs *state.BlockState, cdb ChainAccessor, tx *types.Tx, blockNo uint64, ts int64, prevBlockHash []byte, sender, receiver *state.V, preLoadService int) (rv string, fee *big.Int, events []*types.Event, err error) { txBody := tx.GetBody() @@ -94,7 +94,7 @@ func Execute(bs *state.BlockState, tx *types.Tx, blockNo uint64, ts int64, prevB if ex != nil { rv, events, err = PreCall(ex, bs, sender, contractState, blockNo, ts, receiver.RP(), prevBlockHash) } else { - stateSet := NewContext(bs, sender, receiver, contractState, sender.ID(), + stateSet := NewContext(bs, cdb, sender, receiver, contractState, sender.ID(), tx.GetHash(), blockNo, ts, prevBlockHash, "", true, false, receiver.RP(), preLoadService, txBody.GetAmountBigInt()) @@ -161,7 +161,7 @@ func preLoadWorker() { replyCh <- &loadedReply{tx, nil, err} continue } - stateSet := NewContext(bs, nil, receiver, contractState, txBody.GetAccount(), + stateSet := NewContext(bs, nil, nil, receiver, contractState, txBody.GetAccount(), tx.GetHash(), 0, 0, nil, "", false, false, receiver.RP(), reqInfo.preLoadService, txBody.GetAmountBigInt()) diff --git a/contract/state_module.c b/contract/state_module.c index 794ec02d5..139589935 100644 --- a/contract/state_module.c +++ b/contract/state_module.c @@ -78,12 +78,16 @@ static void state_map_push_key(lua_State *L) static int state_map_get(lua_State *L) { + int arg = lua_gettop(L); luaL_checktype(L, 1, LUA_TTABLE); /* m key */ state_map_check_index(L, 2); lua_pushcfunction(L, getItemWithPrefix); /* m key f */ state_map_push_key(L); /* m key f id-key */ + if (arg == 3) { + lua_pushvalue(L, 3); + } lua_pushstring(L, STATE_VAR_KEY_PREFIX); /* m key f id-key prefix */ - lua_call(L, 2, 1); /* m key rv */ + lua_call(L, arg, 1); /* m key rv */ return 1; } @@ -194,6 +198,7 @@ static int state_array_get(lua_State *L) const char *method; const char *idx; state_array_t *arr; + int arg = lua_gettop(L); arr = luaL_checkudata(L, 1, STATE_ARRAY_ID); state_array_load_len(L, arr); @@ -211,11 +216,17 @@ static int state_array_get(lua_State *L) return 1; } } + if (arg == 3) { + lua_pushvalue(L, 2); + } state_array_checkarg(L, arr); /* a i */ lua_pushcfunction(L, getItemWithPrefix); /* a i f */ state_array_push_key(L, arr->id); /* a i f id-i */ + if (arg == 3) { + lua_pushvalue(L, 3); /* a i s i f id-i s */ + } lua_pushstring(L, STATE_VAR_KEY_PREFIX); /* a i f id-i prefix */ - lua_call(L, 2, 1); /* a i rv */ + lua_call(L, arg, 1); /* a i rv */ return 1; } @@ -321,6 +332,23 @@ static int state_value_get(lua_State *L) return 1; } +static int state_value_snapget(lua_State *L) +{ + int arg = lua_gettop(L); + luaL_checktype(L, 1, LUA_TTABLE); /* t */ + lua_pushcfunction(L, getItemWithPrefix); /* t f */ + lua_getfield(L, 1, "id"); /* t f id */ + if (!lua_isstring(L, -1)) { + luaL_error(L, "the value is not a state.value type"); + } + if (arg == 2) { + lua_pushvalue(L, 2); + } + lua_pushstring(L, STATE_VAR_KEY_PREFIX); /* t f id prefix */ + lua_call(L, arg + 1, 1); /* t rv */ + return 1; +} + static int state_value_set(lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); /* t */ @@ -387,6 +415,45 @@ static int state_var(lua_State *L) return 0; } +static int state_get_snap(lua_State *L) +{ + const char *state_name; + int type = lua_type(L, 1); + switch(type) { + case LUA_TUSERDATA: + if (lua_gettop(L) != 3) + luaL_error(L, "invalid argument at getsnap, need (state.array, index, blockheight)"); + return state_array_get(L); + case LUA_TTABLE: + lua_pushstring(L, TYPE_NAME); /* T key value _type_ */ + lua_rawget(L, 1); /* T key value "type_name" */ + if (lua_isnil (L, -1)) { + lua_pushfstring(L, "bad argument #1 at getsnap: state.value, state.map or state.array expected, got %s", + lua_typename(L, type)); + lua_error(L); + } + state_name = lua_tostring(L, -1); + + if (strcmp(state_name,"map") == 0) { + lua_pop(L, 1); + if (lua_gettop(L) != 3) + luaL_error(L, "invalid argument at getsnap, need (state.map, key, blockheight)"); + return state_map_get(L); + } + else if (strcmp(state_name,"value") == 0) { + lua_pop(L, 1); + if (lua_gettop(L) != 2) + luaL_error(L, "invalid argument at getsnap, need (state.value, blockheight)"); + return state_value_snapget(L); + } + default: + lua_pushfstring(L, "bad argument #1 at getsnap: state.value, state.map or state.array expected, got %s", + lua_typename(L, type)); + lua_error(L); + } + return 0; +} + int luaopen_state(lua_State *L) { static const luaL_Reg state_map_metas[] = { @@ -414,6 +481,7 @@ int luaopen_state(lua_State *L) {"array", state_array}, {"value", state_value}, {"var", state_var}, + {"getsnap", state_get_snap}, {NULL, NULL} }; diff --git a/contract/system_module.c b/contract/system_module.c index 8581d8a32..8eeaf8bbf 100644 --- a/contract/system_module.c +++ b/contract/system_module.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "vm.h" #include "util.h" #include "_cgo_export.h" @@ -72,14 +73,27 @@ int getItemWithPrefix(lua_State *L) int *service = (int *)getLuaExecContext(L); char *jsonValue; int ret; + char *blkno = NULL; if (service == NULL) { luaL_error(L, "cannot find execution context"); } luaL_checkstring(L, 1); - luaL_checkstring(L, 2); + if(lua_gettop(L) == 2) { + luaL_checkstring(L, 2); + } + else if (lua_gettop(L) == 3) { + if (!lua_isnil(L, 2)) { + int type = lua_type(L,2); + if (type != LUA_TNUMBER && type != LUA_TSTRING) + luaL_error(L, "snap height permitted number or string type"); + blkno = (char *)lua_tostring(L, 2); + } + luaL_checkstring(L, 3); + } dbKey = getDbKey(L); - ret = LuaGetDB(L, service, dbKey); + + ret = LuaGetDB(L, service, dbKey, blkno); if (ret < 0) { lua_error(L); } @@ -98,6 +112,10 @@ int getItem(lua_State *L) { luaL_checkstring(L, 1); lua_pushstring(L, STATE_DB_KEY_PREFIX); + if (lua_gettop(L) == 3) { + if (!lua_isnil(L, 2)) + luaL_checknumber(L, 2); + } return getItemWithPrefix(L); } @@ -179,7 +197,7 @@ static int getCreator(lua_State *L) if (service == NULL) { luaL_error(L, "cannot find execution context"); } - ret = LuaGetDB(L, service, "Creator"); + ret = LuaGetDB(L, service, "Creator", 0); if (ret < 0) { lua_error(L); } diff --git a/contract/vm.go b/contract/vm.go index 6d14d6d7c..68f80bdba 100644 --- a/contract/vm.go +++ b/contract/vm.go @@ -53,6 +53,11 @@ var ( querySync sync.Mutex ) +type ChainAccessor interface { + GetBlockByNo(blockNo types.BlockNo) (*types.Block, error) + GetBestBlock() (*types.Block, error) +} + type CallState struct { ctrState *state.ContractState prevState *types.State @@ -71,6 +76,7 @@ type ContractInfo struct { type StateSet struct { curContract *ContractInfo bs *state.BlockState + cdb ChainAccessor origin []byte txHash []byte blockHeight uint64 @@ -128,7 +134,7 @@ func newContractInfo(callState *CallState, sender, contractId []byte, rp uint64, } } -func NewContext(blockState *state.BlockState, sender, reciever *state.V, +func NewContext(blockState *state.BlockState, cdb ChainAccessor, sender, reciever *state.V, contractState *state.ContractState, senderID []byte, txHash []byte, blockHeight uint64, timestamp int64, prevBlockHash []byte, node string, confirmed bool, query bool, rp uint64, service int, amount *big.Int) *StateSet { @@ -138,6 +144,7 @@ func NewContext(blockState *state.BlockState, sender, reciever *state.V, stateSet := &StateSet{ curContract: newContractInfo(callState, senderID, reciever.ID(), rp, amount), bs: blockState, + cdb: cdb, origin: senderID, txHash: txHash, node: node, @@ -157,7 +164,7 @@ func NewContext(blockState *state.BlockState, sender, reciever *state.V, return stateSet } -func NewContextQuery(blockState *state.BlockState, receiverId []byte, +func NewContextQuery(blockState *state.BlockState, cdb ChainAccessor, receiverId []byte, contractState *state.ContractState, node string, confirmed bool, rp uint64) *StateSet { @@ -166,6 +173,7 @@ func NewContextQuery(blockState *state.BlockState, receiverId []byte, stateSet := &StateSet{ curContract: newContractInfo(callState, nil, receiverId, rp, big.NewInt(0)), bs: blockState, + cdb: cdb, node: node, confirmed: confirmed, timestamp: time.Now().UnixNano(), @@ -734,7 +742,7 @@ func setQueryContext(stateSet *StateSet) { } } -func Query(contractAddress []byte, bs *state.BlockState, contractState *state.ContractState, queryInfo []byte) (res []byte, err error) { +func Query(contractAddress []byte, bs *state.BlockState, cdb ChainAccessor, contractState *state.ContractState, queryInfo []byte) (res []byte, err error) { var ci types.CallInfo contract := getContract(contractState, nil) if contract != nil { @@ -749,7 +757,7 @@ func Query(contractAddress []byte, bs *state.BlockState, contractState *state.Co var ce *Executor - stateSet := NewContextQuery(bs, contractAddress, contractState, "", true, + stateSet := NewContextQuery(bs, cdb, contractAddress, contractState, "", true, contractState.SqlRecoveryPoint) setQueryContext(stateSet) diff --git a/contract/vm_callback.go b/contract/vm_callback.go index a15a3b89b..af8250cbd 100644 --- a/contract/vm_callback.go +++ b/contract/vm_callback.go @@ -15,6 +15,7 @@ import ( "encoding/hex" "errors" "fmt" + "github.com/aergoio/aergo/internal/common" "index/suffixarray" "math/big" "regexp" @@ -77,12 +78,57 @@ func LuaSetDB(L *LState, service *C.int, key *C.char, value *C.char) C.int { } //export LuaGetDB -func LuaGetDB(L *LState, service *C.int, key *C.char) C.int { +func LuaGetDB(L *LState, service *C.int, key *C.char, blkno *C.char) C.int { stateSet := curStateSet[*service] if stateSet == nil { luaPushStr(L, "[System.LuaGetDB] contract state not found") return -1 } + if blkno != nil { + bigNo, _ := new(big.Int).SetString(strings.TrimSpace(C.GoString(blkno)), 10) + if bigNo == nil || bigNo.Sign() < 0 { + luaPushStr(L, "[System.LuaGetDB] invalid blockheight value :"+C.GoString(blkno)) + return -1 + } + blkNo := bigNo.Uint64() + + chainBlockHeight := stateSet.blockHeight + if chainBlockHeight == 0 { + bestBlock, err := stateSet.cdb.GetBestBlock() + if err != nil { + luaPushStr(L, "[System.LuaGetDB] get best block error") + } + chainBlockHeight = bestBlock.GetHeader().GetBlockNo() + } + if blkNo < chainBlockHeight { + blk, err := stateSet.cdb.GetBlockByNo(blkNo) + if err != nil { + luaPushStr(L, err.Error()) + return -1 + } + accountId := types.ToAccountID(stateSet.curContract.contractId) + contractProof, err := stateSet.bs.GetAccountAndProof(accountId[:], blk.GetHeader().GetBlocksRootHash(), false) + if err != nil { + luaPushStr(L, "[System.LuaGetDB] failed to get snapshot state for account") + return -1 + } else if contractProof.Inclusion { + trieKey := common.Hasher([]byte(C.GoString(key))) + varProof, err := stateSet.bs.GetVarAndProof(trieKey, contractProof.GetState().GetStorageRoot(), false) + if err != nil { + luaPushStr(L, "[System.LuaGetDB] failed to get snapshot state variable in contract") + return -1 + } + if varProof.Inclusion { + if len(varProof.GetValue()) == 0 { + return 0 + } + luaPushStr(L, string(varProof.GetValue())) + return 1 + } + } + return 0 + } + } data, err := stateSet.curContract.callState.ctrState.GetData([]byte(C.GoString(key))) if err != nil { diff --git a/contract/vm_dummy.go b/contract/vm_dummy.go index 50012563d..434029fea 100644 --- a/contract/vm_dummy.go +++ b/contract/vm_dummy.go @@ -111,8 +111,16 @@ func (bc *DummyChain) GetStaking(name string) (*types.Staking, error) { return system.GetStaking(scs, strHash(name)) } +func (bc *DummyChain) GetBlockByNo(blockNo types.BlockNo) (*types.Block, error) { + return bc.blocks[blockNo], nil +} + +func (bc *DummyChain) GetBestBlock() (*types.Block, error) { + return bc.bestBlock, nil +} + type luaTx interface { - run(bs *state.BlockState, blockNo uint64, ts int64, prevBlockHash []byte, receiptTx db.Transaction) error + run(bs *state.BlockState, bc *DummyChain, blockNo uint64, ts int64, prevBlockHash []byte, receiptTx db.Transaction) error } type luaTxAccount struct { @@ -134,7 +142,7 @@ func NewLuaTxAccountBig(name string, balance *big.Int) *luaTxAccount { } } -func (l *luaTxAccount) run(bs *state.BlockState, blockNo uint64, ts int64, prevBlockHash []byte, +func (l *luaTxAccount) run(bs *state.BlockState, bc *DummyChain, blockNo uint64, ts int64, prevBlockHash []byte, receiptTx db.Transaction) error { id := types.ToAccountID(l.name) @@ -162,7 +170,7 @@ func NewLuaTxSendBig(sender, receiver string, balance *big.Int) *luaTxSend { } } -func (l *luaTxSend) run(bs *state.BlockState, blockNo uint64, ts int64, prevBlockHash []byte, +func (l *luaTxSend) run(bs *state.BlockState, bc *DummyChain, blockNo uint64, ts int64, prevBlockHash []byte, receiptTx db.Transaction) error { senderID := types.ToAccountID(l.sender) @@ -352,7 +360,7 @@ func contractFrame(l *luaTxCommon, bs *state.BlockState, } -func (l *luaTxDef) run(bs *state.BlockState, blockNo uint64, ts int64, prevBlockHash []byte, +func (l *luaTxDef) run(bs *state.BlockState, bc *DummyChain, blockNo uint64, ts int64, prevBlockHash []byte, receiptTx db.Transaction) error { if l.cErr != nil { @@ -363,7 +371,7 @@ func (l *luaTxDef) run(bs *state.BlockState, blockNo uint64, ts int64, prevBlock func(sender, contract *state.V, contractId types.AccountID, eContractState *state.ContractState) error { contract.State().SqlRecoveryPoint = 1 - stateSet := NewContext(bs, sender, contract, eContractState, sender.ID(), + stateSet := NewContext(bs, nil, sender, contract, eContractState, sender.ID(), l.hash(), blockNo, ts, prevBlockHash, "", true, false, contract.State().SqlRecoveryPoint, ChainService, l.luaTxCommon.amount) @@ -421,11 +429,11 @@ func (l *luaTxCall) Fail(expectedErr string) *luaTxCall { return l } -func (l *luaTxCall) run(bs *state.BlockState, blockNo uint64, ts int64, prevBlockHash []byte, +func (l *luaTxCall) run(bs *state.BlockState, bc *DummyChain, blockNo uint64, ts int64, prevBlockHash []byte, receiptTx db.Transaction) error { err := contractFrame(&l.luaTxCommon, bs, func(sender, contract *state.V, contractId types.AccountID, eContractState *state.ContractState) error { - stateSet := NewContext(bs, sender, contract, eContractState, sender.ID(), + stateSet := NewContext(bs, bc, sender, contract, eContractState, sender.ID(), l.hash(), blockNo, ts, prevBlockHash, "", true, false, contract.State().SqlRecoveryPoint, ChainService, l.luaTxCommon.amount) rv, evs, err := Call(eContractState, l.code, l.contract, stateSet) @@ -468,7 +476,7 @@ func (bc *DummyChain) ConnectBlock(txs ...luaTx) error { defer tx.Commit() for _, x := range txs { - if err := x.run(blockState, bc.cBlock.Header.BlockNo, bc.cBlock.Header.Timestamp, + if err := x.run(blockState, bc, bc.cBlock.Header.BlockNo, bc.cBlock.Header.Timestamp, bc.cBlock.Header.PrevBlockHash, tx); err != nil { return err } @@ -484,6 +492,7 @@ func (bc *DummyChain) ConnectBlock(txs ...luaTx) error { //FIXME newblock must be created after sdb.apply() bc.cBlock.SetBlocksRootHash(bc.sdb.GetRoot()) bc.bestBlockNo = bc.bestBlockNo + 1 + bc.bestBlock = bc.cBlock bc.bestBlockId = types.ToBlockID(bc.cBlock.BlockHash()) bc.blockIds = append(bc.blockIds, bc.bestBlockId) bc.blocks = append(bc.blocks, bc.cBlock) @@ -514,7 +523,7 @@ func (bc *DummyChain) Query(contract, queryInfo, expectedErr string, expectedRvs if err != nil { return err } - rv, err := Query(strHash(contract), bc.newBState(), cState, []byte(queryInfo)) + rv, err := Query(strHash(contract), bc.newBState(), bc, cState, []byte(queryInfo)) if expectedErr != "" { if err == nil { return fmt.Errorf("no error, expected: %s", expectedErr) @@ -543,7 +552,7 @@ func (bc *DummyChain) QueryOnly(contract, queryInfo string) (string, error) { if err != nil { return "", err } - rv, err := Query(strHash(contract), bc.newBState(), cState, []byte(queryInfo)) + rv, err := Query(strHash(contract), bc.newBState(), nil, cState, []byte(queryInfo)) if err != nil { return "", err diff --git a/contract/vm_test.go b/contract/vm_test.go index bb95ad37d..22ab57324 100644 --- a/contract/vm_test.go +++ b/contract/vm_test.go @@ -3487,4 +3487,80 @@ func TestGovernance(t *testing.T) { } } +func TestSnapshot(t *testing.T) { + bc, err := LoadDummyChain() + if err != nil { + t.Errorf("failed to create test database: %v", err) + } + definition := ` + state.var{ + counts = state.map(), + data = state.value(), + array = state.array(10) + } + + function inc() + a = system.getItem("key1") + if (a == nil) then + system.setItem("key1", 1) + return + end + system.setItem("key1", a + 1) + counts["key1"] = a + 1 + data:set(a+1) + array[1] = a + 1 + end + function query(a) + return system.getItem("key1", a), state.getsnap(counts, "key1", a), state.getsnap(data,a), state.getsnap(array, 1, a) + end + function query2() + return state.getsnap(array, 1) + end + abi.register(inc, query, query2) + abi.payable(inc)` + + err = bc.ConnectBlock( + NewLuaTxAccount("ktlee", 100), + NewLuaTxDef("ktlee", "snap", 0, definition), + ) + if err != nil { + t.Error(err) + } + err = bc.ConnectBlock( + NewLuaTxCall("ktlee", "snap", 0, `{"Name": "inc", "Args":[]}`), + ) + if err != nil { + t.Error(err) + } + err = bc.ConnectBlock( + NewLuaTxCall("ktlee", "snap", 0, `{"Name": "inc", "Args":[]}`), + ) + if err != nil { + t.Error(err) + } + err = bc.ConnectBlock( + NewLuaTxCall("ktlee", "snap", 0, `{"Name": "inc", "Args":[]}`), + ) + if err != nil { + t.Error(err) + } + err = bc.Query("snap", `{"Name":"query"}`, "", "[3,3,3,3]") + if err != nil { + t.Error(err) + } + err = bc.Query("snap", `{"Name":"query", "Args":[2]}`, "", "[1,{},{},{}]") + if err != nil { + t.Error(err) + } + err = bc.Query("snap", `{"Name":"query", "Args":[3]}`, "", "[2,2,2,2]") + if err != nil { + t.Error(err) + } + err = bc.Query("snap", `{"Name":"query2", "Args":[]}`, + "invalid argument at getsnap, need (state.array, index, blockheight)", "") + if err != nil { + t.Error(err) + } +} + // end of test-cases From 472bb9026e50bc853d4965319924259e408b4442 Mon Sep 17 00:00:00 2001 From: bjjeon Date: Tue, 2 Apr 2019 14:46:27 +0900 Subject: [PATCH 002/148] [brick] add length check --- cmd/brick/exec/callContract.go | 2 ++ cmd/brick/exec/deployContract.go | 2 ++ cmd/brick/exec/getstateAccount.go | 2 ++ cmd/brick/exec/queryContract.go | 2 ++ 4 files changed, 8 insertions(+) diff --git a/cmd/brick/exec/callContract.go b/cmd/brick/exec/callContract.go index 6eaef19d9..0968757e1 100644 --- a/cmd/brick/exec/callContract.go +++ b/cmd/brick/exec/callContract.go @@ -65,6 +65,8 @@ func (c *callContract) parse(args string) (string, *big.Int, string, string, str expectedResult := "" if len(splitArgs) == 6 { expectedResult = splitArgs[5].Text + } else if len(splitArgs) > 6 { + return "", nil, "", "", "", "", fmt.Errorf("too many arguments. usage: %s", c.Usage()) } return splitArgs[0].Text, //accountName diff --git a/cmd/brick/exec/deployContract.go b/cmd/brick/exec/deployContract.go index 174a79fd1..59b720d94 100644 --- a/cmd/brick/exec/deployContract.go +++ b/cmd/brick/exec/deployContract.go @@ -62,6 +62,8 @@ func (c *deployContract) parse(args string) (string, uint64, string, string, str constuctorArg := "[]" if len(splitArgs) == 5 { constuctorArg = splitArgs[4].Text + } else if len(splitArgs) > 5 { + return "", 0, "", "", "", fmt.Errorf("too many arguments. usage: %s", c.Usage()) } return splitArgs[0].Text, //accountName diff --git a/cmd/brick/exec/getstateAccount.go b/cmd/brick/exec/getstateAccount.go index c898c502d..6a6e266fb 100644 --- a/cmd/brick/exec/getstateAccount.go +++ b/cmd/brick/exec/getstateAccount.go @@ -49,6 +49,8 @@ func (c *getStateAccount) parse(args string) (string, string, error) { expectedResult := "" if len(splitArgs) == 2 { expectedResult = splitArgs[1].Text + } else if len(splitArgs) > 2 { + return "", "", fmt.Errorf("too many arguments. usage: %s", c.Usage()) } return splitArgs[0].Text, expectedResult, nil diff --git a/cmd/brick/exec/queryContract.go b/cmd/brick/exec/queryContract.go index 9978d3f19..658704f68 100644 --- a/cmd/brick/exec/queryContract.go +++ b/cmd/brick/exec/queryContract.go @@ -57,6 +57,8 @@ func (c *queryContract) parse(args string) (string, string, string, string, erro expectedResult := "" if len(splitArgs) == 4 { expectedResult = splitArgs[3].Text + } else if len(splitArgs) > 4 { + return "", "", "", "", fmt.Errorf("too many arguments. usage: %s", c.Usage()) } return splitArgs[0].Text, // contractName From 67b6be552d945ed110994039dcd87e5a9664e029 Mon Sep 17 00:00:00 2001 From: bjjeon Date: Tue, 2 Apr 2019 14:50:12 +0900 Subject: [PATCH 003/148] [brick] add forward command --- cmd/brick/README.md | 11 +++++- cmd/brick/exec/forward.go | 70 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 cmd/brick/exec/forward.go diff --git a/cmd/brick/README.md b/cmd/brick/README.md index 0320f396c..d8ce1ac62 100644 --- a/cmd/brick/README.md +++ b/cmd/brick/README.md @@ -122,12 +122,21 @@ cancels the last tx (inject, send, deploy, call). `undo` INF Undo, Succesfully cmd=undo module=brick ``` +### forward + +skip blocks. `forward [height_to_skip]` + +``` lua +7> forward 100 + INF fast forward blocks successfully cmd=forward module=brick +``` + ### reset clear all txs and reset the chain. `reset` ``` lua -7> reset +107> reset INF reset a dummy chain successfully cmd=reset module=brick 0> ``` diff --git a/cmd/brick/exec/forward.go b/cmd/brick/exec/forward.go new file mode 100644 index 000000000..11be6bfb4 --- /dev/null +++ b/cmd/brick/exec/forward.go @@ -0,0 +1,70 @@ +package exec + +import ( + "fmt" + "strconv" + + "github.com/aergoio/aergo/cmd/brick/context" +) + +func init() { + registerExec(&forward{}) +} + +type forward struct{} + +func (c *forward) Command() string { + return "forward" +} + +func (c *forward) Syntax() string { + return context.AmountSymbol +} + +func (c *forward) Usage() string { + return "forward [height_to_skip]" +} + +func (c *forward) Describe() string { + return "fast forward blocks n times (default = 1)" +} + +func (c *forward) Validate(args string) error { + // is chain is loaded? + if context.Get() == nil { + return fmt.Errorf("load chain first") + } + + _, err := c.parse(args) + + return err +} + +func (c *forward) parse(args string) (int, error) { + splitArgs := context.SplitSpaceAndAccent(args, false) + if len(splitArgs) == 0 { + height, _ := strconv.Atoi("1") + return height, nil + } else if len(splitArgs) > 1 { + return 0, fmt.Errorf("need 1 or 0 arguments. usage: %s", c.Usage()) + } + + amount, err := strconv.Atoi(splitArgs[0].Text) + if err != nil { + return 0, fmt.Errorf("fail to parse number %s: %s", splitArgs[0].Text, err.Error()) + } + + return amount, nil +} + +func (c *forward) Run(args string) (string, error) { + amount, _ := c.parse(args) + + for i := 0; i < amount; i++ { + if err := context.Get().ConnectBlock(); err != nil { + return "", err + } + } + + return "fast forward blocks successfully", nil +} From a73396e442d8fc1f66773033d3b9b162dd6a4c51 Mon Sep 17 00:00:00 2001 From: asteroid Date: Wed, 3 Apr 2019 18:08:53 +0900 Subject: [PATCH 004/148] [state] add function to check key existence --- state/contract.go | 5 +++++ state/contract_test.go | 44 +++++++++++++++++++++++++++++++++++++++ state/statebuffer.go | 4 ++++ state/statebuffer_test.go | 17 +++++++++++++++ state/storage.go | 11 ++++++++++ state/storage_test.go | 36 ++++++++++++++++++++++++++++++++ 6 files changed, 117 insertions(+) diff --git a/state/contract.go b/state/contract.go index 9ae5f469d..45df493e8 100644 --- a/state/contract.go +++ b/state/contract.go @@ -90,6 +90,11 @@ func (st *ContractState) GetCode() ([]byte, error) { return st.code, nil } +// HasKey returns existence of the key +func (st *ContractState) HasKey(key []byte) bool { + return st.storage.has(types.GetHashID(key), true) +} + // SetData store key and value pair to the storage. func (st *ContractState) SetData(key, value []byte) error { st.storage.put(newValueEntry(types.GetHashID(key), value)) diff --git a/state/contract_test.go b/state/contract_test.go index 6db0a04f3..bb9981a67 100644 --- a/state/contract_test.go +++ b/state/contract_test.go @@ -162,6 +162,50 @@ func TestContractStateDataDelete(t *testing.T) { assert.NoError(t, err, "stage contract state") } +func TestContractStateHasKey(t *testing.T) { + initTest(t) + defer deinitTest() + testAddress := []byte("test_address") + testBytes := []byte("test_bytes") + testKey := []byte("test_key") + + // open contract state and set test data + contractState, err := stateDB.OpenContractStateAccount(types.ToAccountID(testAddress)) + assert.NoError(t, err, "could not open contract state") + assert.False(t, contractState.HasKey(testKey)) + + err = contractState.SetData(testKey, testBytes) + assert.NoError(t, err, "set data to contract state") + assert.True(t, contractState.HasKey(testKey)) + + // get test data + _, err = contractState.GetData(testKey) + assert.NoError(t, err, "get data from contract state") + assert.True(t, contractState.HasKey(testKey)) + + // delete test data + err = contractState.DeleteData(testKey) + assert.NoError(t, err, "delete data from contract state") + assert.True(t, contractState.HasKey(testKey)) + + // stage contract state + err = stateDB.StageContractState(contractState) + assert.NoError(t, err, "stage contract state") + + // update and commit + err = stateDB.Update() + assert.NoError(t, err, "failed to update stateDB") + err = stateDB.Commit() + assert.NoError(t, err, "failed to commit stateDB") + + // re-open contract state + contractState, err = stateDB.OpenContractState(types.ToAccountID(testAddress), contractState.State) + assert.NoError(t, err, "could not open contract state") + + // check key existence + assert.False(t, contractState.HasKey(testKey)) +} + func TestContractStateEmpty(t *testing.T) { initTest(t) defer deinitTest() diff --git a/state/statebuffer.go b/state/statebuffer.go index 5f52980f8..9a7fecc0b 100644 --- a/state/statebuffer.go +++ b/state/statebuffer.go @@ -109,6 +109,10 @@ func (buffer *stateBuffer) get(key types.HashID) entry { } return nil } +func (buffer *stateBuffer) has(key types.HashID) bool { + _, ok := buffer.indexes[key] + return ok +} func (buffer *stateBuffer) put(et entry) { snapshot := buffer.snapshot() diff --git a/state/statebuffer_test.go b/state/statebuffer_test.go index 61710166d..e21501420 100644 --- a/state/statebuffer_test.go +++ b/state/statebuffer_test.go @@ -132,3 +132,20 @@ func TestBufferRollback(t *testing.T) { assert.Equal(t, []byte{5}, stb.get(k1).Value()) t.Logf("k0: %v, k1: %v", stb.get(k0).Value(), stb.get(k1).Value()) } + +func TestBufferHasKey(t *testing.T) { + stb := newStateBuffer() + assert.False(t, stb.has(k0)) + + stb.put(newValueEntry(k0, []byte{1})) + assert.True(t, stb.has(k0)) // buffer has key + + stb.put(newValueEntryDelete(k0)) + assert.True(t, stb.has(k0)) // buffer has key for ValueEntryDelete + + stb.put(newValueEntry(k0, []byte{2})) + assert.True(t, stb.has(k0)) // buffer has key + + stb.reset() + assert.False(t, stb.has(k0)) // buffer doesn't have key +} diff --git a/state/storage.go b/state/storage.go index deba6a59d..c053ea9b7 100644 --- a/state/storage.go +++ b/state/storage.go @@ -54,6 +54,17 @@ func newBufferedStorage(root []byte, store db.DB) *bufferedStorage { } } +func (storage *bufferedStorage) has(key types.HashID, lookupTrie bool) bool { + if storage.buffer.has(key) { + return true + } + if lookupTrie { + if buf, _ := storage.trie.Get(key.Bytes()); buf != nil { + return true + } + } + return false +} func (storage *bufferedStorage) get(key types.HashID) entry { return storage.buffer.get(key) } diff --git a/state/storage_test.go b/state/storage_test.go index e0782e492..6992bf3c0 100644 --- a/state/storage_test.go +++ b/state/storage_test.go @@ -84,3 +84,39 @@ func TestStorageDelete(t *testing.T) { assert.Equal(t, []byte{0}, storage.get(v2).Hash()) assert.Nil(t, storage.get(v2).Value()) } + +func TestStorageHasKey(t *testing.T) { + storage := newBufferedStorage(nil, nil) + v1 := types.GetHashID([]byte("v1")) + + assert.False(t, storage.has(v1, false)) // check buffer only + assert.False(t, storage.has(v1, true)) // check buffer and trie + + // put entry + storage.put(newValueEntry(v1, []byte{1})) + assert.True(t, storage.has(v1, false)) // buffer has key + assert.True(t, storage.has(v1, true)) // buffer has key + + // update storage and reset buffer + err := storage.update() + assert.NoError(t, err, "failed to update storage") + err = storage.buffer.reset() + assert.NoError(t, err, "failed to reset buffer") + // after update and reset + assert.False(t, storage.has(v1, false)) // buffer doesn't have key + assert.True(t, storage.has(v1, true)) // buffer doesn't have, but trie has key + + // delete entry + storage.put(newValueEntryDelete(v1)) + assert.True(t, storage.has(v1, false)) // buffer has key + assert.True(t, storage.has(v1, true)) // buffer has key + + // update storage and reset buffer + err = storage.update() + assert.NoError(t, err, "failed to update storage") + err = storage.buffer.reset() + assert.NoError(t, err, "failed to reset buffer") + // after update and reset + assert.False(t, storage.has(v1, false)) // buffer doesn't have key + assert.False(t, storage.has(v1, true)) // buffer and trie don't have key +} From c350704ea07611173cf137b8a524e1cdce0fcd49 Mon Sep 17 00:00:00 2001 From: bjjeon Date: Fri, 5 Apr 2019 13:04:42 +0900 Subject: [PATCH 005/148] [brick] change type of amount: uint64 -> big.int --- cmd/brick/exec/deployContract.go | 20 ++++--- contract/vm_dummy.go | 4 +- mempool/mempool_dump_test | 100 +++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 11 deletions(-) create mode 100644 mempool/mempool_dump_test diff --git a/cmd/brick/exec/deployContract.go b/cmd/brick/exec/deployContract.go index 59b720d94..bab7732be 100644 --- a/cmd/brick/exec/deployContract.go +++ b/cmd/brick/exec/deployContract.go @@ -3,8 +3,8 @@ package exec import ( "fmt" "io/ioutil" + "math/big" "os" - "strconv" "github.com/aergoio/aergo/cmd/brick/context" "github.com/aergoio/aergo/contract" @@ -45,25 +45,27 @@ func (c *deployContract) Validate(args string) error { return err } -func (c *deployContract) parse(args string) (string, uint64, string, string, string, error) { +func (c *deployContract) parse(args string) (string, *big.Int, string, string, string, error) { splitArgs := context.SplitSpaceAndAccent(args, false) if len(splitArgs) < 4 { - return "", 0, "", "", "", fmt.Errorf("need 4 arguments. usage: %s", c.Usage()) + return "", nil, "", "", "", fmt.Errorf("need 4 arguments. usage: %s", c.Usage()) } - amount, err := strconv.ParseUint(splitArgs[1].Text, 10, 64) - if err != nil { - return "", 0, "", "", "", fmt.Errorf("fail to parse number %s: %s", splitArgs[1].Text, err.Error()) + + amount, success := new(big.Int).SetString(splitArgs[1].Text, 10) + if success == false { + return "", nil, "", "", "", fmt.Errorf("fail to parse number %s", splitArgs[1].Text) } + defPath := splitArgs[3].Text if _, err := os.Stat(defPath); os.IsNotExist(err) { - return "", 0, "", "", "", fmt.Errorf("fail to read a contrat def file %s: %s", splitArgs[3].Text, err.Error()) + return "", nil, "", "", "", fmt.Errorf("fail to read a contrat def file %s: %s", splitArgs[3].Text, err.Error()) } constuctorArg := "[]" if len(splitArgs) == 5 { constuctorArg = splitArgs[4].Text } else if len(splitArgs) > 5 { - return "", 0, "", "", "", fmt.Errorf("too many arguments. usage: %s", c.Usage()) + return "", nil, "", "", "", fmt.Errorf("too many arguments. usage: %s", c.Usage()) } return splitArgs[0].Text, //accountName @@ -85,7 +87,7 @@ func (c *deployContract) Run(args string) (string, error) { updateContractInfoInterface(contractName, defPath) err = context.Get().ConnectBlock( - contract.NewRawLuaTxDef(accountName, contractName, amount, string(defByte)).Constructor(constuctorArg), + contract.NewRawLuaTxDefBig(accountName, contractName, amount, string(defByte)).Constructor(constuctorArg), ) Index(context.ContractSymbol, contractName) diff --git a/contract/vm_dummy.go b/contract/vm_dummy.go index 434029fea..362c2b56f 100644 --- a/contract/vm_dummy.go +++ b/contract/vm_dummy.go @@ -257,7 +257,7 @@ func getCompiledABI(code string) ([]byte, error) { return b[4+codeLen:], nil } -func NewRawLuaTxDef(sender, contract string, amount uint64, code string) *luaTxDef { +func NewRawLuaTxDefBig(sender, contract string, amount *big.Int, code string) *luaTxDef { byteAbi, err := getCompiledABI(code) if err != nil { @@ -276,7 +276,7 @@ func NewRawLuaTxDef(sender, contract string, amount uint64, code string) *luaTxD sender: strHash(sender), contract: strHash(contract), code: payload, - amount: new(big.Int).SetUint64(amount), + amount: amount, id: newTxId(), }, cErr: nil, diff --git a/mempool/mempool_dump_test b/mempool/mempool_dump_test new file mode 100644 index 000000000..24dfe200b --- /dev/null +++ b/mempool/mempool_dump_test @@ -0,0 +1,100 @@ +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 From ebe2cbb6320798a62511f14b2fb8d613b3b5a861 Mon Sep 17 00:00:00 2001 From: bjjeon Date: Fri, 5 Apr 2019 16:23:58 +0900 Subject: [PATCH 006/148] remove temporal test file --- mempool/mempool_dump_test | 100 -------------------------------------- 1 file changed, 100 deletions(-) delete mode 100644 mempool/mempool_dump_test diff --git a/mempool/mempool_dump_test b/mempool/mempool_dump_test deleted file mode 100644 index 24dfe200b..000000000 --- a/mempool/mempool_dump_test +++ /dev/null @@ -1,100 +0,0 @@ -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 From 084138cb960fdf35a07af95c702d4fcf42350c6a Mon Sep 17 00:00:00 2001 From: bjjeon Date: Fri, 12 Apr 2019 11:10:47 +0900 Subject: [PATCH 007/148] dummy vm bug fix even if contract is failed, when there is expected error, states in the errored contract applied. This is invalid behavior --- contract/vm_dummy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contract/vm_dummy.go b/contract/vm_dummy.go index 20d5f8007..1520ad2d5 100644 --- a/contract/vm_dummy.go +++ b/contract/vm_dummy.go @@ -435,7 +435,6 @@ func (l *luaTxCall) run(bs *state.BlockState, bc *DummyChain, blockNo uint64, ts l.hash(), blockNo, ts, prevBlockHash, "", true, false, contract.State().SqlRecoveryPoint, ChainService, l.luaTxCommon.amount) rv, evs, _, err := Call(eContractState, l.code, l.contract, stateSet) - _ = bs.StageContractState(eContractState) if err != nil { r := types.NewReceipt(l.contract, err.Error(), "") r.TxHash = l.hash() @@ -443,6 +442,7 @@ func (l *luaTxCall) run(bs *state.BlockState, bc *DummyChain, blockNo uint64, ts receiptTx.Set(l.hash(), b) return err } + _ = bs.StageContractState(eContractState) r := types.NewReceipt(l.contract, "SUCCESS", rv) r.Events = evs r.TxHash = l.hash() From 945dd2749b4439d3525c20e31224ea8e81466268 Mon Sep 17 00:00:00 2001 From: Paul Grau Date: Tue, 16 Apr 2019 10:58:03 +0800 Subject: [PATCH 008/148] Update Dockerfile to use mainnet config by default --- Dockerfile | 4 ++-- node/arglog.toml | 2 +- node/local.toml | 1 - node/mainnet.toml | 41 +++++++++++++++++++++++++++++++++++++++ node/testmode.toml | 1 - node/testnet-genesis.json | 32 ------------------------------ node/testnet.toml | 2 -- 7 files changed, 44 insertions(+), 39 deletions(-) create mode 100644 node/mainnet.toml delete mode 100644 node/testnet-genesis.json diff --git a/Dockerfile b/Dockerfile index 3a7b70ce4..52164b2cf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,12 +14,12 @@ COPY --from=builder $HOME/go/src/github.com/aergoio/aergo/libtool/lib/* /usr/loc ADD node/testnet.toml /aergo/testnet.toml ADD node/testnet.toml /root/.aergo/config.toml -ADD node/testnet-genesis.json /aergo/testnet-genesis.json +ADD node/mainnet.toml /root/.aergo/mainnet.toml ADD node/local.toml /aergo/local.toml ADD node/testmode.toml /aergo/testmode.toml ADD node/arglog.toml /aergo/arglog.toml ENV LD_LIBRARY_PATH="/usr/local/lib:${LD_LIBRARY_PATH}" WORKDIR /aergo/ -CMD ["aergosvr", "--config", "/aergo/testnet.toml"] +CMD ["aergosvr", "--config", "/aergo/mainnet.toml"] EXPOSE 7845 7846 6060 8080 diff --git a/node/arglog.toml b/node/arglog.toml index db06c1506..52b405a22 100644 --- a/node/arglog.toml +++ b/node/arglog.toml @@ -22,7 +22,7 @@ level = "info" level = "info" [syncer] -level = "debug" +level = "info" [bp] level = "info" \ No newline at end of file diff --git a/node/local.toml b/node/local.toml index 6d0966208..484ca3e00 100644 --- a/node/local.toml +++ b/node/local.toml @@ -1,7 +1,6 @@ datadir = "/aergo/data" enableprofile = false profileport = 6060 -enablerest = false [rpc] netserviceaddr = "0.0.0.0" diff --git a/node/mainnet.toml b/node/mainnet.toml new file mode 100644 index 000000000..77db5bbf9 --- /dev/null +++ b/node/mainnet.toml @@ -0,0 +1,41 @@ +datadir = "/aergo/data" +enableprofile = false +profileport = 6060 + +[rpc] +netserviceaddr = "0.0.0.0" +netserviceport = 7845 +nstls = false +nscert = "" +nskey = "" +nsallowcors = false + +[rest] +restport = "8080" + +[p2p] +netprotocoladdr = "" +netprotocolport = 7846 +npbindaddr = "0.0.0.0" +npbindport = 7846 +nptls = false +npcert = "" +npkey = "" +npmaxpeers = "100" +nppeerpool = "100" +npaddpeers = [ +] +npexposeself = false +npusepolaris = true + +[blockchain] +blockchainplaceholder = false + +[mempool] +showmetrics = false +dumpfilepath = "/aergo/mempool.dump" +enablefadeout = true +fadeoutperiod = 12 + +[consensus] +enablebp = false diff --git a/node/testmode.toml b/node/testmode.toml index 331d461f3..576455c73 100644 --- a/node/testmode.toml +++ b/node/testmode.toml @@ -1,7 +1,6 @@ datadir = "/aergo/data" enableprofile = false profileport = 6060 -enablerest = false enabletestmode = true [rpc] diff --git a/node/testnet-genesis.json b/node/testnet-genesis.json deleted file mode 100644 index 2d0da7189..000000000 --- a/node/testnet-genesis.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "chain_id":{ - "magic":"testnet.aergo.io", - "public":true, - "mainnet":false, - "consensus":"dpos" - }, - "timestamp":1553679000000000000, - "balance": { - "AmMK3LZiR1oEf66xzXir7mA5SUVVHSinWUYmh5FwueoVmciH3CuJ": "499100000000000000000000000", - "AmNmkKXKgwXGLBc5oFhi1MuxNxnJLwvWUPHV5wr5unHVNwX1MfXe": "100000000000000000000000", - "AmLsSfxo9aQRZJBvMBoLFb9QZABQK2RiG3Uq1JBhyAfbDYPf31J2": "100000000000000000000000", - "AmPJRLHDKtzLpsaC8ubmPuRkxnMCyBSq5wBwYNDD6DJdgiRhAhYR": "100000000000000000000000", - "AmNSmkDtwwSSrGHk4EP8yLP7YaC629fjnPg977JJfLpTe9zXtpsd": "100000000000000000000000", - "AmMR1CLHNnBCq7itY5XRX4LqLs5Ve1nZKxAcBRVZtwcsRdrytFqk": "100000000000000000000000", - "AmMvmu6HxRhYMjVgih4sXSYyDiM8HpuvZFnP9VHUtUd95qTUENR6": "100000000000000000000000", - "AmP5vYXeHBjGuvqDaGrZBoHyTHEJcUztUDvTam2HzqvA9jseqekd": "100000000000000000000000", - "AmNEfsKt1v2gosbu6eMg7fGBchkJzvEcmbG8A4EeMyusAU3M38mk": "100000000000000000000000", - "AmNJRh4ntQWT145jQwDHQGuHYdATmMWCEbENW2DN7mztfr5pqPbP": "100000000000000000000000" - }, - "bps": [ - "16Uiu2HAmAokYAtLbZxJAPRgp2jCc4bD35cJD921trqUANh59Rc4n", - "16Uiu2HAm4xYtGsqk7WGKUxr8prfVpJ25hD23AQ3Be6anEL9Kxkgw", - "16Uiu2HAmGiJ2QgVAWHMUtzLKKNM5eFUJ3Ds3FN7nYJq1mHN5ZPj9", - "16Uiu2HAmRNY6CEDMQKuUkUbix7QDpp1fFAg3yRVMoJJDNztbGzdH", - "16Uiu2HAm18LyTb9WWVNWcj5Gn83fUP4ckqxgy9AzHgzYsXpiZ8JA", - "16Uiu2HAmNaert6HsSaW1bbs8Jb3hUq2nW6iyiMgj1hBwTg5FkBsP", - "16Uiu2HAmV6iVGuN31sZTz2GDicFPpBr6eaHn1mVM499BGwSBf6Nb", - "16Uiu2HAm7mv81gkeLMtw27b5doXHvhELQnHwfHhBfZLGqrLjZLVZ", - "16Uiu2HAm4NtvcqNKFWU1z3oMRB3Zuge8jvZi3ybn6xBtZkLAEvUW" - ] -} diff --git a/node/testnet.toml b/node/testnet.toml index 1e53b1e8a..91bb75497 100644 --- a/node/testnet.toml +++ b/node/testnet.toml @@ -1,7 +1,6 @@ datadir = "/aergo/data" enableprofile = false profileport = 6060 -enablerest = false usetestnet = true [rpc] @@ -31,7 +30,6 @@ npexposeself = false npusepolaris = true [blockchain] -usefastsyncer = true blockchainplaceholder = false [mempool] From c2002db6a973f7c0170f2af932d2938483f351cc Mon Sep 17 00:00:00 2001 From: Paul Grau Date: Tue, 16 Apr 2019 11:33:00 +0800 Subject: [PATCH 009/148] Fix path to config file; reduce default log verbosity --- Dockerfile | 4 ++-- node/arglog.toml | 2 +- node/local.toml | 3 --- node/mainnet.toml | 4 +--- node/testmode.toml | 3 --- node/testnet.toml | 3 --- 6 files changed, 4 insertions(+), 15 deletions(-) diff --git a/Dockerfile b/Dockerfile index 52164b2cf..aa391d303 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,7 +14,7 @@ COPY --from=builder $HOME/go/src/github.com/aergoio/aergo/libtool/lib/* /usr/loc ADD node/testnet.toml /aergo/testnet.toml ADD node/testnet.toml /root/.aergo/config.toml -ADD node/mainnet.toml /root/.aergo/mainnet.toml +ADD node/mainnet.toml /aergo/mainnet.toml ADD node/local.toml /aergo/local.toml ADD node/testmode.toml /aergo/testmode.toml ADD node/arglog.toml /aergo/arglog.toml @@ -22,4 +22,4 @@ ENV LD_LIBRARY_PATH="/usr/local/lib:${LD_LIBRARY_PATH}" WORKDIR /aergo/ CMD ["aergosvr", "--config", "/aergo/mainnet.toml"] -EXPOSE 7845 7846 6060 8080 +EXPOSE 7845 7846 6060 diff --git a/node/arglog.toml b/node/arglog.toml index 52b405a22..7346e9c13 100644 --- a/node/arglog.toml +++ b/node/arglog.toml @@ -22,7 +22,7 @@ level = "info" level = "info" [syncer] -level = "info" +level = "error" [bp] level = "info" \ No newline at end of file diff --git a/node/local.toml b/node/local.toml index 484ca3e00..2ed8e1422 100644 --- a/node/local.toml +++ b/node/local.toml @@ -10,9 +10,6 @@ nscert = "" nskey = "" nsallowcors = false -[rest] -restport = "8080" - [p2p] netprotocoladdr = "127.0.0.1" netprotocolport = 7846 diff --git a/node/mainnet.toml b/node/mainnet.toml index 77db5bbf9..ba0f8c5df 100644 --- a/node/mainnet.toml +++ b/node/mainnet.toml @@ -1,4 +1,5 @@ datadir = "/aergo/data" +authdir = "/aergo/auth" enableprofile = false profileport = 6060 @@ -10,9 +11,6 @@ nscert = "" nskey = "" nsallowcors = false -[rest] -restport = "8080" - [p2p] netprotocoladdr = "" netprotocolport = 7846 diff --git a/node/testmode.toml b/node/testmode.toml index 576455c73..178e81c30 100644 --- a/node/testmode.toml +++ b/node/testmode.toml @@ -11,9 +11,6 @@ nscert = "" nskey = "" nsallowcors = false -[rest] -restport = "8080" - [p2p] netprotocoladdr = "127.0.0.1" netprotocolport = 7846 diff --git a/node/testnet.toml b/node/testnet.toml index 91bb75497..3283af5b2 100644 --- a/node/testnet.toml +++ b/node/testnet.toml @@ -11,9 +11,6 @@ nscert = "" nskey = "" nsallowcors = false -[rest] -restport = "8080" - [p2p] netprotocoladdr = "" netprotocolport = 7846 From e302a72da492fc89055928a60e77af84850d48ee Mon Sep 17 00:00:00 2001 From: Paul Grau Date: Tue, 16 Apr 2019 12:22:09 +0800 Subject: [PATCH 010/148] Remove config files, use default config --- Dockerfile | 8 +------- node/local.toml | 36 ------------------------------------ node/mainnet.toml | 39 --------------------------------------- node/testmode.toml | 4 +--- node/testnet.toml | 39 --------------------------------------- 5 files changed, 2 insertions(+), 124 deletions(-) delete mode 100644 node/local.toml delete mode 100644 node/mainnet.toml delete mode 100644 node/testnet.toml diff --git a/Dockerfile b/Dockerfile index aa391d303..db9b25e56 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,15 +11,9 @@ FROM alpine:3.8 RUN apk add libgcc COPY --from=builder $HOME/go/src/github.com/aergoio/aergo/bin/aergosvr /usr/local/bin/ COPY --from=builder $HOME/go/src/github.com/aergoio/aergo/libtool/lib/* /usr/local/lib/ - -ADD node/testnet.toml /aergo/testnet.toml -ADD node/testnet.toml /root/.aergo/config.toml -ADD node/mainnet.toml /aergo/mainnet.toml -ADD node/local.toml /aergo/local.toml ADD node/testmode.toml /aergo/testmode.toml ADD node/arglog.toml /aergo/arglog.toml ENV LD_LIBRARY_PATH="/usr/local/lib:${LD_LIBRARY_PATH}" - WORKDIR /aergo/ -CMD ["aergosvr", "--config", "/aergo/mainnet.toml"] +CMD ["aergosvr", "--home", "/aergo"] EXPOSE 7845 7846 6060 diff --git a/node/local.toml b/node/local.toml deleted file mode 100644 index 2ed8e1422..000000000 --- a/node/local.toml +++ /dev/null @@ -1,36 +0,0 @@ -datadir = "/aergo/data" -enableprofile = false -profileport = 6060 - -[rpc] -netserviceaddr = "0.0.0.0" -netserviceport = 7845 -nstls = false -nscert = "" -nskey = "" -nsallowcors = false - -[p2p] -netprotocoladdr = "127.0.0.1" -netprotocolport = 7846 -npbindaddr = "0.0.0.0" -npbindport = 7846 -nptls = false -npcert = "" -npkey = "" -npaddpeers = [ -] -npmaxpeers = "0" -nppeerpool = "0" - -[blockchain] -blockchainplaceholder = false - -[mempool] -showmetrics = false -dumpfilepath = "/aergo/mempool.dump" - -[consensus] -enablebp = true -enabledpos = false -blockinterval = 1 diff --git a/node/mainnet.toml b/node/mainnet.toml deleted file mode 100644 index ba0f8c5df..000000000 --- a/node/mainnet.toml +++ /dev/null @@ -1,39 +0,0 @@ -datadir = "/aergo/data" -authdir = "/aergo/auth" -enableprofile = false -profileport = 6060 - -[rpc] -netserviceaddr = "0.0.0.0" -netserviceport = 7845 -nstls = false -nscert = "" -nskey = "" -nsallowcors = false - -[p2p] -netprotocoladdr = "" -netprotocolport = 7846 -npbindaddr = "0.0.0.0" -npbindport = 7846 -nptls = false -npcert = "" -npkey = "" -npmaxpeers = "100" -nppeerpool = "100" -npaddpeers = [ -] -npexposeself = false -npusepolaris = true - -[blockchain] -blockchainplaceholder = false - -[mempool] -showmetrics = false -dumpfilepath = "/aergo/mempool.dump" -enablefadeout = true -fadeoutperiod = 12 - -[consensus] -enablebp = false diff --git a/node/testmode.toml b/node/testmode.toml index 178e81c30..b85c326b3 100644 --- a/node/testmode.toml +++ b/node/testmode.toml @@ -23,9 +23,7 @@ npaddpeers = [ ] npmaxpeers = "0" nppeerpool = "0" - -[blockchain] -blockchainplaceholder = false +npusepolaris = false [mempool] showmetrics = false diff --git a/node/testnet.toml b/node/testnet.toml deleted file mode 100644 index 3283af5b2..000000000 --- a/node/testnet.toml +++ /dev/null @@ -1,39 +0,0 @@ -datadir = "/aergo/data" -enableprofile = false -profileport = 6060 -usetestnet = true - -[rpc] -netserviceaddr = "0.0.0.0" -netserviceport = 7845 -nstls = false -nscert = "" -nskey = "" -nsallowcors = false - -[p2p] -netprotocoladdr = "" -netprotocolport = 7846 -npbindaddr = "0.0.0.0" -npbindport = 7846 -nptls = false -npcert = "" -npkey = "" -npmaxpeers = "100" -nppeerpool = "100" -npaddpeers = [ -] -npexposeself = false -npusepolaris = true - -[blockchain] -blockchainplaceholder = false - -[mempool] -showmetrics = false -dumpfilepath = "/aergo/mempool.dump" -enablefadeout = true -fadeoutperiod = 12 - -[consensus] -enablebp = false From 84eb1f72edc7ca96770c93b6af5c556daf1d2df1 Mon Sep 17 00:00:00 2001 From: kjunu Date: Tue, 16 Apr 2019 16:47:24 +0900 Subject: [PATCH 011/148] [aergo.name] Bugfix, add missing error handling --- types/transaction.go | 8 ++++++-- types/transaction_test.go | 17 ++++++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/types/transaction.go b/types/transaction.go index 60c5a44d9..ce3f0adf1 100644 --- a/types/transaction.go +++ b/types/transaction.go @@ -191,12 +191,16 @@ func validateNameTx(tx *TxBody) error { } switch ci.Name { case NameCreate: - _validateNameTx(tx, &ci) + if err := _validateNameTx(tx, &ci); err != nil { + return err + } if len(ci.Args) != 1 { return fmt.Errorf("invalid arguments in %s", ci) } case NameUpdate: - _validateNameTx(tx, &ci) + if err := _validateNameTx(tx, &ci); err != nil { + return err + } if len(ci.Args) != 2 { return fmt.Errorf("invalid arguments in %s", ci) } diff --git a/types/transaction_test.go b/types/transaction_test.go index 2c887f061..9c818f8ee 100644 --- a/types/transaction_test.go +++ b/types/transaction_test.go @@ -99,13 +99,16 @@ func TestGovernanceTypeTransaction(t *testing.T) { err = transaction.Validate(chainid) assert.EqualError(t, err, ErrTxInvalidPayload.Error(), "only one candidate allowed") - /* - transaction.GetTx().GetBody().Payload = buildVoteNumBPPayloadEx(1, TestNormal) - transaction.GetTx().Hash = transaction.CalculateTxHash() - t.Log(string(transaction.GetTx().GetBody().Payload)) - err = transaction.Validate() - assert.NoError(t, err, "should success") - */ + transaction.GetTx().GetBody().Recipient = []byte(`aergo.name`) + transaction.GetTx().GetBody().Payload = []byte(`{"Name":"v1createName", "Args":["1"]}`) + transaction.GetTx().Hash = transaction.CalculateTxHash() + err = transaction.Validate(chainid) + assert.Error(t, err, "invalid name length in create") + + transaction.GetTx().GetBody().Payload = []byte(`{"Name":"v1updateName", "Args":["1234567890","AmPNYHyzyh9zweLwDyuoiUuTVCdrdksxkRWDjVJS76WQLExa2Jr4"]}`) + transaction.GetTx().Hash = transaction.CalculateTxHash() + err = transaction.Validate(chainid) + assert.Error(t, err, "invalid name length in update") } func buildVoteBPPayloadEx(count int, err int) []byte { From d482a63c68af14c23afa69ec84bdce1c8ee8699d Mon Sep 17 00:00:00 2001 From: Hayarobi Park Date: Tue, 16 Apr 2019 19:38:00 +0900 Subject: [PATCH 012/148] [P2P] Improve logging --- p2p/remotepeer.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/p2p/remotepeer.go b/p2p/remotepeer.go index 3f1ad88a2..f4d679265 100644 --- a/p2p/remotepeer.go +++ b/p2p/remotepeer.go @@ -7,6 +7,7 @@ package p2p import ( "fmt" + "runtime/debug" "sync" "time" @@ -195,7 +196,7 @@ func (p *remotePeerImpl) runWrite() { cleanupTicker := time.NewTicker(cleanRequestInterval) defer func() { if r := recover(); r != nil { - p.logger.Panic().Str(p2putil.LogPeerName, p.Name()).Str("recover", fmt.Sprint(r)).Msg("There were panic in runWrite ") + p.logger.Panic().Str("callstack", string(debug.Stack())).Str(p2putil.LogPeerName, p.Name()).Str("recover", fmt.Sprint(r)).Msg("There were panic in runWrite ") } }() @@ -258,7 +259,7 @@ func (p *remotePeerImpl) handleMsg(msg p2pcommon.Message) error { subProto := msg.Subprotocol() defer func() { if r := recover(); r != nil { - p.logger.Error().Interface("panic", r).Msg("There were panic in handler.") + p.logger.Error().Str("callstack", string(debug.Stack())).Interface("panic", r).Msg("There were panic in handler.") err = fmt.Errorf("internal error") } }() From 09db43a0118dad2316c65573f76b3bbaaa2a51e1 Mon Sep 17 00:00:00 2001 From: Hayarobi Park Date: Tue, 16 Apr 2019 20:09:11 +0900 Subject: [PATCH 013/148] [P2P] Improve logging again --- p2p/remotepeer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/p2p/remotepeer.go b/p2p/remotepeer.go index f4d679265..8d5955725 100644 --- a/p2p/remotepeer.go +++ b/p2p/remotepeer.go @@ -259,7 +259,7 @@ func (p *remotePeerImpl) handleMsg(msg p2pcommon.Message) error { subProto := msg.Subprotocol() defer func() { if r := recover(); r != nil { - p.logger.Error().Str("callstack", string(debug.Stack())).Interface("panic", r).Msg("There were panic in handler.") + p.logger.Error().Str(p2putil.LogProtoID,subProto.String()).Str("callstack", string(debug.Stack())).Interface("panic", r).Msg("There were panic in handler.") err = fmt.Errorf("internal error") } }() From 549077e36c30300d80838536d01c6bf855bca288 Mon Sep 17 00:00:00 2001 From: kjunu Date: Mon, 15 Apr 2019 10:27:38 +0900 Subject: [PATCH 014/148] [CLI] Add stream flag in getblock command --- cmd/aergocli/cmd/getblock.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/cmd/aergocli/cmd/getblock.go b/cmd/aergocli/cmd/getblock.go index 2402da6da..433d3dac1 100644 --- a/cmd/aergocli/cmd/getblock.go +++ b/cmd/aergocli/cmd/getblock.go @@ -22,6 +22,7 @@ var getblockCmd = &cobra.Command{ Run: execGetBlock, } +var stream bool var number uint64 var hash string @@ -29,9 +30,30 @@ func init() { rootCmd.AddCommand(getblockCmd) getblockCmd.Flags().Uint64VarP(&number, "number", "n", 0, "Block height") getblockCmd.Flags().StringVarP(&hash, "hash", "", "", "Block hash") + getblockCmd.Flags().BoolVar(&stream, "stream", false, "Get the block information by streamming") } func execGetBlock(cmd *cobra.Command, args []string) { + if stream { + bs, err := client.ListBlockStream(context.Background(), &aergorpc.Empty{}) + if err != nil { + cmd.Printf("Failed: %s\n", err.Error()) + return + } + if err != nil { + cmd.Printf("Failed: %s", err.Error()) + return + } + for { + b, err := bs.Recv() + if err != nil { + cmd.Printf("Failed: %s\n", err.Error()) + return + } + cmd.Println(util.BlockConvBase58Addr(b)) + } + return + } fflags := cmd.Flags() if fflags.Changed("number") == false && fflags.Changed("hash") == false { cmd.Println("no block --hash or --number specified") From 5711907acbeec606b9cec3a749324fdf85de2463 Mon Sep 17 00:00:00 2001 From: eve2adam Date: Thu, 18 Apr 2019 15:26:25 +0900 Subject: [PATCH 015/148] [ctr/lua] changed to reduce size of aergoluac --- cmd/aergocli/cmd/contract.go | 21 +++++++++-------- cmd/aergocli/util/base58addr.go | 27 ---------------------- cmd/aergoluac/encoding/codeEncoding.go | 32 ++++++++++++++++++++++++++ cmd/aergoluac/util/luac_util.go | 7 +++--- 4 files changed, 46 insertions(+), 41 deletions(-) create mode 100644 cmd/aergoluac/encoding/codeEncoding.go diff --git a/cmd/aergocli/cmd/contract.go b/cmd/aergocli/cmd/contract.go index c381ac6cd..7ea7b17df 100644 --- a/cmd/aergocli/cmd/contract.go +++ b/cmd/aergocli/cmd/contract.go @@ -12,6 +12,7 @@ import ( "os" "github.com/aergoio/aergo/cmd/aergocli/util" + luacEncoding "github.com/aergoio/aergo/cmd/aergoluac/encoding" "github.com/aergoio/aergo/types" "github.com/mr-tron/base58/base58" "github.com/spf13/cobra" @@ -32,10 +33,10 @@ func init() { } deployCmd := &cobra.Command{ - Use: "deploy [flags] --payload 'payload string' creator\n aergocli contract deploy [flags] creator bcfile abifile", - Short: "Deploy a compiled contract to the server", - Args: cobra.MinimumNArgs(1), - Run: runDeployCmd, + Use: "deploy [flags] --payload 'payload string' creator\n aergocli contract deploy [flags] creator bcfile abifile", + Short: "Deploy a compiled contract to the server", + Args: cobra.MinimumNArgs(1), + Run: runDeployCmd, DisableFlagsInUseLine: true, } deployCmd.PersistentFlags().StringVar(&data, "payload", "", "result of compiling a contract") @@ -95,7 +96,7 @@ func runDeployCmd(cmd *cobra.Command, args []string) { var payload []byte if len(data) == 0 { if len(args) < 3 { - fmt.Fprint(os.Stderr, "Usage: aergocli contract deploy [args]") + _, _ = fmt.Fprint(os.Stderr, "Usage: aergocli contract deploy [args]") os.Exit(1) } var code []byte @@ -136,7 +137,7 @@ func runDeployCmd(cmd *cobra.Command, args []string) { } argLen = len(args[1]) } - code, err := util.DecodeCode(data) + code, err := luacEncoding.DecodeCode(data) payload = make([]byte, 4+len(code)+argLen) binary.LittleEndian.PutUint32(payload[0:], uint32(len(code)+4)) codeLen := copy(payload[4:], code) @@ -145,13 +146,13 @@ func runDeployCmd(cmd *cobra.Command, args []string) { } if err != nil { - fmt.Fprint(os.Stderr, err) + _, _ = fmt.Fprint(os.Stderr, err) os.Exit(1) } } amountBigInt, ok := new(big.Int).SetString(amount, 10) if !ok { - fmt.Fprint(os.Stderr, "failed to parse --amount flags") + _, _ = fmt.Fprint(os.Stderr, "failed to parse --amount flags") os.Exit(1) } tx := &types.Tx{ @@ -219,7 +220,7 @@ func runCallCmd(cmd *cobra.Command, args []string) { amountBigInt, ok := new(big.Int).SetString(amount, 10) if !ok { - fmt.Fprint(os.Stderr, "failed to parse --amount flags") + _, _ = fmt.Fprint(os.Stderr, "failed to parse --amount flags") os.Exit(1) } txType := types.TxType_NORMAL @@ -241,7 +242,7 @@ func runCallCmd(cmd *cobra.Command, args []string) { if chainIdHash != "" { rawCidHash, err := base58.Decode(chainIdHash) if err != nil { - fmt.Fprint(os.Stderr, "failed to parse --chainidhash flags\n") + _, _ = fmt.Fprint(os.Stderr, "failed to parse --chainidhash flags\n") os.Exit(1) } tx.Body.ChainIdHash = rawCidHash diff --git a/cmd/aergocli/util/base58addr.go b/cmd/aergocli/util/base58addr.go index 95344fdce..fd6bf9b96 100644 --- a/cmd/aergocli/util/base58addr.go +++ b/cmd/aergocli/util/base58addr.go @@ -1,16 +1,13 @@ package util import ( - "encoding/hex" "encoding/json" "errors" - "fmt" "math/big" "strconv" "time" "github.com/aergoio/aergo/types" - "github.com/anaskhan96/base58check" "github.com/mr-tron/base58/base58" ) @@ -303,27 +300,3 @@ func toString(out interface{}) string { } return string(jsonout) } - -const CodeVersion = 0xC0 - -func EncodeCode(code []byte) string { - encoded, _ := base58check.Encode(fmt.Sprintf("%x", CodeVersion), hex.EncodeToString(code)) - return encoded -} - -func DecodeCode(encodedCode string) ([]byte, error) { - decodedString, err := base58check.Decode(encodedCode) - if err != nil { - return nil, err - } - decodedBytes, err := hex.DecodeString(decodedString) - if err != nil { - return nil, err - } - version := decodedBytes[0] - if version != CodeVersion { - return nil, errors.New("Invalid code version") - } - decoded := decodedBytes[1:] - return decoded, nil -} diff --git a/cmd/aergoluac/encoding/codeEncoding.go b/cmd/aergoluac/encoding/codeEncoding.go new file mode 100644 index 000000000..cdc0af287 --- /dev/null +++ b/cmd/aergoluac/encoding/codeEncoding.go @@ -0,0 +1,32 @@ +package encoding + +import ( + "encoding/hex" + "errors" + "fmt" + "github.com/anaskhan96/base58check" +) + +const CodeVersion = 0xC0 + +func EncodeCode(code []byte) string { + encoded, _ := base58check.Encode(fmt.Sprintf("%x", CodeVersion), hex.EncodeToString(code)) + return encoded +} + +func DecodeCode(encodedCode string) ([]byte, error) { + decodedString, err := base58check.Decode(encodedCode) + if err != nil { + return nil, err + } + decodedBytes, err := hex.DecodeString(decodedString) + if err != nil { + return nil, err + } + version := decodedBytes[0] + if version != CodeVersion { + return nil, errors.New("Invalid code version") + } + decoded := decodedBytes[1:] + return decoded, nil +} diff --git a/cmd/aergoluac/util/luac_util.go b/cmd/aergoluac/util/luac_util.go index 5eba57a80..c61404d22 100644 --- a/cmd/aergoluac/util/luac_util.go +++ b/cmd/aergoluac/util/luac_util.go @@ -14,12 +14,11 @@ import ( "encoding/binary" "errors" "fmt" + "github.com/aergoio/aergo/cmd/aergoluac/encoding" "io/ioutil" "os" "runtime" "unsafe" - - "github.com/aergoio/aergo/cmd/aergocli/util" ) var ( @@ -83,7 +82,7 @@ func DumpFromFile(srcFileName string) error { return errors.New(C.GoString(errMsg)) } - fmt.Println(util.EncodeCode(b.Bytes())) + fmt.Println(encoding.EncodeCode(b.Bytes())) return nil } @@ -120,7 +119,7 @@ func DumpFromStdin() error { if errMsg := C.vm_stringdump(L); errMsg != nil { return errors.New(C.GoString(errMsg)) } - fmt.Println(util.EncodeCode(b.Bytes())) + fmt.Println(encoding.EncodeCode(b.Bytes())) return nil } From 54ef2fcddafc414ab74dc44dcdc95d3bbe394823 Mon Sep 17 00:00:00 2001 From: Hayarobi Park Date: Thu, 18 Apr 2019 10:16:16 +0900 Subject: [PATCH 016/148] [P2P] Fix bug that peermanager is not finished well - Fix wrong status check - Refactor peermanager for testabiliy; Changed some member type to interface from pointer --- p2p/peermanager.go | 35 +++++----- p2p/peermanager_test.go | 144 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 153 insertions(+), 26 deletions(-) diff --git a/p2p/peermanager.go b/p2p/peermanager.go index 49a39a7e8..e6530a740 100644 --- a/p2p/peermanager.go +++ b/p2p/peermanager.go @@ -29,6 +29,7 @@ const ( initial = iota running = iota stopping = iota + stopped = iota ) /** @@ -50,7 +51,7 @@ type peerManager struct { mutex *sync.Mutex manageNumber uint32 - remotePeers map[peer.ID]*remotePeerImpl + remotePeers map[peer.ID]p2pcommon.RemotePeer peerPool map[peer.ID]p2pcommon.PeerMeta conf *cfg.P2PConfig // peerCache is copy-on-write style @@ -101,7 +102,7 @@ func NewPeerManager(handlerFactory HandlerFactory, hsFactory HSHandlerFactory, i designatedPeers: make(map[peer.ID]p2pcommon.PeerMeta, len(cfg.P2P.NPAddPeers)), hiddenPeerSet: make(map[peer.ID]bool, len(cfg.P2P.NPHiddenPeers)), - remotePeers: make(map[peer.ID]*remotePeerImpl, p2pConf.NPMaxPeers), + remotePeers: make(map[peer.ID]p2pcommon.RemotePeer, p2pConf.NPMaxPeers), awaitPeers: make(map[peer.ID]*reconnectJob, p2pConf.NPPeerPool), peerPool: make(map[peer.ID]p2pcommon.PeerMeta, p2pConf.NPPeerPool), @@ -127,12 +128,6 @@ func (pm *peerManager) SelfNodeID() peer.ID { return pm.nt.ID() } -func (pm *peerManager) RegisterEventListener(listener PeerEventListener) { - pm.mutex.Lock() - defer pm.mutex.Unlock() - pm.eventListeners = append(pm.eventListeners, listener) -} - func (pm *peerManager) init() { // set designated peers pm.initDesignatedPeerList() @@ -165,15 +160,17 @@ func (pm *peerManager) Start() error { }() }() - if !atomic.CompareAndSwapInt32(&pm.status, initial, running) { - panic("wrong internal status") - } return nil } func (pm *peerManager) Stop() error { - if !atomic.CompareAndSwapInt32(&pm.status, running, stopping) { + if atomic.CompareAndSwapInt32(&pm.status, running, stopping) { pm.finishChannel <- struct{}{} + } else { + // leave stopped if already stopped + if atomic.SwapInt32(&pm.status, stopping) == stopped { + atomic.StoreInt32(&pm.status, stopped) + } } return nil } @@ -197,6 +194,9 @@ func (pm *peerManager) runManagePeers() { initialAddrDelay := time.Second * 20 initialTimer := time.NewTimer(initialAddrDelay) addrTicker := time.NewTicker(DiscoveryQueryInterval) + if !atomic.CompareAndSwapInt32(&pm.status, initial, running) { + panic("wrong internal status") + } MANLOOP: for { select { @@ -228,7 +228,7 @@ MANLOOP: } }() timer := time.NewTimer(time.Second * 30) - finishPoll := time.NewTicker(time.Second) + finishPoll := time.NewTicker(time.Millisecond << 6 ) CLEANUPLOOP: for { select { @@ -245,6 +245,7 @@ CLEANUPLOOP: break CLEANUPLOOP } } + atomic.StoreInt32(&pm.status, stopped) } // addOutboundPeer try to connect and handshake to remote peer. it can be called after peermanager is inited. @@ -393,7 +394,7 @@ func (pm *peerManager) removePeer(peer p2pcommon.RemotePeer) bool { pm.mutex.Unlock() return false } - if target.manageNum != peer.ManageNumber() { + if target.ManageNumber() != peer.ManageNumber() { pm.logger.Debug().Uint32("remove_num", peer.ManageNumber()).Uint32("exist_num", target.ManageNumber()).Str(p2putil.LogPeerID, p2putil.ShortForm(peerID)).Msg("remove peer is requested but already removed and other instance is on") pm.mutex.Unlock() return false @@ -623,8 +624,12 @@ func (pm *peerManager) cancelAwait(id peer.ID) { } func (pm *peerManager) cancelAllAwait() { + cancelCnt := 0 for id, _ := range pm.awaitPeers { go pm.cancelAwait(id) + cancelCnt++ + } + if cancelCnt > 0 { + <-pm.awaitDone } - <-pm.awaitDone } diff --git a/p2p/peermanager_test.go b/p2p/peermanager_test.go index 6ba819b66..4920d21c4 100644 --- a/p2p/peermanager_test.go +++ b/p2p/peermanager_test.go @@ -1,26 +1,23 @@ -/* - * @file - * @copyright defined in aergo/LICENSE.txt - */ package p2p import ( "fmt" "strconv" "sync" + "sync/atomic" "testing" + "time" + "github.com/aergoio/aergo-lib/log" + cfg "github.com/aergoio/aergo/config" + "github.com/aergoio/aergo/message" "github.com/aergoio/aergo/p2p/p2pcommon" "github.com/aergoio/aergo/p2p/p2pmock" "github.com/aergoio/aergo/p2p/p2putil" + "github.com/aergoio/aergo/types" "github.com/golang/mock/gomock" peer "github.com/libp2p/go-libp2p-peer" "github.com/stretchr/testify/assert" - - "github.com/aergoio/aergo-lib/log" - cfg "github.com/aergoio/aergo/config" - "github.com/aergoio/aergo/message" - "github.com/aergoio/aergo/types" ) func FailTestGetPeers(t *testing.T) { @@ -102,7 +99,7 @@ func TestPeerManager_GetPeers(t *testing.T) { for _ = range target.GetPeers() { cnt++ } - assert.True(t, cnt > (iterSize>>2)) + assert.True(t, cnt > (iterSize >> 2)) waitChan <- 0 }() @@ -125,7 +122,7 @@ func TestPeerManager_GetPeerAddresses(t *testing.T) { } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - pm := &peerManager{remotePeers: make(map[peer.ID]*remotePeerImpl)} + pm := &peerManager{remotePeers: make(map[peer.ID]p2pcommon.RemotePeer)} for _, peer := range samplePeers { pm.remotePeers[peer.ID()] = peer } @@ -181,3 +178,128 @@ func TestPeerManager_init(t *testing.T) { }) } } + +func Test_peerManager_Stop(t *testing.T) { + // check if Stop is working. + tests := []struct { + name string + + prevStatus int32 + + wantStatus int32 + wantSentChannel bool + }{ + // never send to finish channel twice. + {"TInitial", initial, stopping, false}, + {"TRunning", running, stopping, true}, + {"TStopping", stopping, stopping, false}, + {"TStopped", stopped, stopped, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + pm := &peerManager{ + logger: logger, + finishChannel: make(chan struct{},1 ), + } + + atomic.StoreInt32(&pm.status, tt.prevStatus) + pm.Stop() + + if atomic.LoadInt32(&pm.status) != tt.wantStatus { + t.Errorf("mansger status %v, want %v ", toMStatusName(atomic.LoadInt32(&pm.status)), + toMStatusName(tt.wantStatus)) + } + var sent bool + timeout := time.NewTimer(time.Millisecond<<6) + select { + case <-pm.finishChannel: + sent = true + case <-timeout.C: + sent = false + } + if sent != tt.wantSentChannel { + t.Errorf("signal sent %v, want %v ", sent, tt.wantSentChannel) + } + }) + } +} + +func Test_peerManager_StopInRun(t *testing.T) { + ctrl := gomock.NewController(t) + + // check if Stop is working. + tests := []struct { + name string + + callCnt int + wantStatus int32 + }{ + {"TStopOnce", 1, stopped}, + {"TStopTwice", 2, stopped}, + {"TInStopping", 3, stopped}, + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mockNT := p2pmock.NewMockNetworkTransport(ctrl) + mockNT.EXPECT().AddStreamHandler(gomock.Any(), gomock.Any()).AnyTimes() + mockNT.EXPECT().RemoveStreamHandler(gomock.Any()).AnyTimes() + pm := &peerManager{ + logger: logger, + nt: mockNT, + mutex: &sync.Mutex{}, + awaitDone: make(chan struct{}), + finishChannel: make(chan struct{}), + } + go pm.runManagePeers() + // wait status of pm is changed to running + for atomic.LoadInt32(&pm.status) != running { + time.Sleep(time.Millisecond) + } + // stopping will be done within one second if normal status + checkTimer := time.NewTimer(time.Second >> 3) + for i := 0; i < tt.callCnt; i++ { + pm.Stop() + time.Sleep(time.Millisecond << 6) + } + succ := false + failedTimeout := time.NewTimer(time.Second * 5) + + // check if status changed + VERIFYLOOP: + for { + select { + case <-checkTimer.C: + if atomic.LoadInt32(&pm.status) == tt.wantStatus { + succ = true + break VERIFYLOOP + } else { + checkTimer.Stop() + checkTimer.Reset(time.Second) + } + case <-failedTimeout.C: + break VERIFYLOOP + } + } + if !succ { + t.Errorf("mansger status %v, want %v within %v", toMStatusName(atomic.LoadInt32(&pm.status)), + toMStatusName(tt.wantStatus), time.Second*5) + } + }) + } +} + +func toMStatusName(status int32) string { + switch status { + case initial: + return "initial" + case running: + return "running" + case stopping: + return "stopping" + case stopped: + return "stopped" + default: + return "(invalid)" + strconv.Itoa(int(status)) + } +} From 2cca21b4e2cd9971b1efc57ab3bee857f53ab9e2 Mon Sep 17 00:00:00 2001 From: Kyungtae Lee Date: Thu, 18 Apr 2019 17:25:32 +0900 Subject: [PATCH 017/148] [ctr/lua] Add error checking and use null-safe APIs --- libtool/src/luajit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libtool/src/luajit b/libtool/src/luajit index a4015bd73..317711e07 160000 --- a/libtool/src/luajit +++ b/libtool/src/luajit @@ -1 +1 @@ -Subproject commit a4015bd73b6fb1b5f690741d6308d1004dc43236 +Subproject commit 317711e07ccd239038309266f0c087f30c29e94e From 1b5a497d1d0b544407c389de965a6dc83a48c9b8 Mon Sep 17 00:00:00 2001 From: bjjeon Date: Fri, 19 Apr 2019 19:41:19 +0900 Subject: [PATCH 018/148] [brick] minor bug fix - return error on deploy failure - watch deployed contract - remove defer in the for loop --- cmd/brick/exec/batch.go | 2 +- cmd/brick/exec/deployContract.go | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/cmd/brick/exec/batch.go b/cmd/brick/exec/batch.go index d1b63c3cc..6eeb10990 100644 --- a/cmd/brick/exec/batch.go +++ b/cmd/brick/exec/batch.go @@ -174,7 +174,6 @@ func (c *batch) Run(args string) (string, error) { } if c.level == 0 && enableWatch { - defer watcher.Close() // wait and check file changes fileWatching: for { @@ -188,6 +187,7 @@ func (c *batch) Run(args string) (string, error) { break fileWatching } } + watcher.Close() continue } break diff --git a/cmd/brick/exec/deployContract.go b/cmd/brick/exec/deployContract.go index bab7732be..4b9f517f9 100644 --- a/cmd/brick/exec/deployContract.go +++ b/cmd/brick/exec/deployContract.go @@ -5,6 +5,7 @@ import ( "io/ioutil" "math/big" "os" + "path/filepath" "github.com/aergoio/aergo/cmd/brick/context" "github.com/aergoio/aergo/contract" @@ -90,8 +91,17 @@ func (c *deployContract) Run(args string) (string, error) { contract.NewRawLuaTxDefBig(accountName, contractName, amount, string(defByte)).Constructor(constuctorArg), ) + if err != nil { + return "", err + } + Index(context.ContractSymbol, contractName) Index(context.AccountSymbol, contractName) + if enableWatch { + absPath, _ := filepath.Abs(defPath) + watcher.Add(absPath) + } + return "deploy a smart contract successfully", nil } From 8b6a0a73a4f0e27aea6b8d81efcbabd0356ad82a Mon Sep 17 00:00:00 2001 From: Hayarobi Park Date: Fri, 19 Apr 2019 18:26:57 +0900 Subject: [PATCH 019/148] [P2P] Tune to skip useless block notice - Skip almost all relay block notice to peer with too high block. - Relay block notices are sent at least interval of a quarter of second; notices will be skipped when node is syncing. --- p2p/configs.go | 11 +++ p2p/p2pcommon/others.go | 3 +- p2p/p2pmock/mock_remotepeer.go | 10 +-- p2p/peermanager.go | 2 +- p2p/peermanager_test.go | 6 +- p2p/protobufHelper.go | 24 ++++++ p2p/protobufHelper_test.go | 151 ++++++++++++++++++++++++++++++++- p2p/remotepeer.go | 16 ++-- p2p/remotepeer_test.go | 4 +- p2p/v030mofactory.go | 1 + types/p2pmore.go | 2 +- 11 files changed, 209 insertions(+), 21 deletions(-) diff --git a/p2p/configs.go b/p2p/configs.go index 6b24ca7d1..bb282eb1b 100644 --- a/p2p/configs.go +++ b/p2p/configs.go @@ -64,6 +64,17 @@ const ( cachePlaceHolder = true ) +// constants for block notice tuning +const ( + GapToSkipAll = 86400 + GapToSkipHourly = 3600 + GapToSkip5Min = 300 + + HourlyInterval = time.Hour + TenMiniteInterval = time.Minute * 10 + MinNewBlkNotiInterval = time.Second >> 2 +) + // constants about private key const ( DefaultPkKeyPrefix = "aergo-peer" diff --git a/p2p/p2pcommon/others.go b/p2p/p2pcommon/others.go index 9a8db4ffb..52e1003c3 100644 --- a/p2p/p2pcommon/others.go +++ b/p2p/p2pcommon/others.go @@ -21,7 +21,8 @@ type RemotePeer interface { Name() string State() types.PeerState - LastNotice() *types.LastBlockStatus + // LastStatus returns last observed status of remote peer. this value will be changed by notice, or ping + LastStatus() *types.LastBlockStatus RunPeer() Stop() diff --git a/p2p/p2pmock/mock_remotepeer.go b/p2p/p2pmock/mock_remotepeer.go index bbab189be..820d7156c 100644 --- a/p2p/p2pmock/mock_remotepeer.go +++ b/p2p/p2pmock/mock_remotepeer.go @@ -77,18 +77,18 @@ func (mr *MockRemotePeerMockRecorder) ID() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ID", reflect.TypeOf((*MockRemotePeer)(nil).ID)) } -// LastNotice mocks base method -func (m *MockRemotePeer) LastNotice() *types.LastBlockStatus { +// LastStatus mocks base method +func (m *MockRemotePeer) LastStatus() *types.LastBlockStatus { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "LastNotice") + ret := m.ctrl.Call(m, "LastStatus") ret0, _ := ret[0].(*types.LastBlockStatus) return ret0 } -// LastNotice indicates an expected call of LastNotice +// LastStatus indicates an expected call of LastStatus func (mr *MockRemotePeerMockRecorder) LastNotice() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LastNotice", reflect.TypeOf((*MockRemotePeer)(nil).LastNotice)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LastStatus", reflect.TypeOf((*MockRemotePeer)(nil).LastStatus)) } // MF mocks base method diff --git a/p2p/peermanager.go b/p2p/peermanager.go index e6530a740..5623287b0 100644 --- a/p2p/peermanager.go +++ b/p2p/peermanager.go @@ -560,7 +560,7 @@ func (pm *peerManager) GetPeerAddresses(noHidden bool, showSelf bool) []*message continue } addr := meta.ToPeerAddress() - lastNoti := aPeer.LastNotice() + lastNoti := aPeer.LastStatus() pi := &message.PeerInfo{ &addr, meta.Hidden, lastNoti.CheckTime, lastNoti.BlockHash, lastNoti.BlockNumber, aPeer.State(), false} peers = append(peers, pi) diff --git a/p2p/peermanager_test.go b/p2p/peermanager_test.go index 4920d21c4..48821b78f 100644 --- a/p2p/peermanager_test.go +++ b/p2p/peermanager_test.go @@ -112,9 +112,9 @@ func TestPeerManager_GetPeers(t *testing.T) { func TestPeerManager_GetPeerAddresses(t *testing.T) { peersLen := 3 samplePeers := make([]*remotePeerImpl, peersLen) - samplePeers[0] = &remotePeerImpl{meta: p2pcommon.PeerMeta{ID: dummyPeerID}, lastNotice: &types.LastBlockStatus{}} - samplePeers[1] = &remotePeerImpl{meta: p2pcommon.PeerMeta{ID: dummyPeerID2}, lastNotice: &types.LastBlockStatus{}} - samplePeers[2] = &remotePeerImpl{meta: p2pcommon.PeerMeta{ID: dummyPeerID3}, lastNotice: &types.LastBlockStatus{}} + samplePeers[0] = &remotePeerImpl{meta: p2pcommon.PeerMeta{ID: dummyPeerID}, lastStatus: &types.LastBlockStatus{}} + samplePeers[1] = &remotePeerImpl{meta: p2pcommon.PeerMeta{ID: dummyPeerID2}, lastStatus: &types.LastBlockStatus{}} + samplePeers[2] = &remotePeerImpl{meta: p2pcommon.PeerMeta{ID: dummyPeerID3}, lastStatus: &types.LastBlockStatus{}} tests := []struct { name string }{ diff --git a/p2p/protobufHelper.go b/p2p/protobufHelper.go index 5d0ae9bb6..54b701345 100644 --- a/p2p/protobufHelper.go +++ b/p2p/protobufHelper.go @@ -105,11 +105,33 @@ func (pr *pbResponseOrder) SendTo(pi p2pcommon.RemotePeer) error { type pbBlkNoticeOrder struct { pbMessageOrder blkHash []byte + blkNo uint64 } func (pr *pbBlkNoticeOrder) SendTo(pi p2pcommon.RemotePeer) error { p := pi.(*remotePeerImpl) var blkhash = types.ToBlockID(pr.blkHash) + passedTime := time.Now().Sub(p.lastBlkNoticeTime) + skipNotice := false + if p.LastStatus().BlockNumber >= pr.blkNo { + heightDiff := p.LastStatus().BlockNumber - pr.blkNo + switch { + case heightDiff >= GapToSkipAll: + skipNotice = true + case heightDiff >= GapToSkipHourly: + skipNotice = p.skipCnt < GapToSkipHourly + default: + skipNotice = p.skipCnt < GapToSkip5Min + } + } + if skipNotice || passedTime < MinNewBlkNotiInterval { + p.skipCnt++ + return nil + } + + if p.skipCnt > 100 { + p.logger.Debug().Str(p2putil.LogPeerName, p.Name()).Str(p2putil.LogProtoID, pr.GetProtocolID().String()).Int32("skip_cnt", p.skipCnt).Str(p2putil.LogMsgID, pr.GetMsgID().String()).Str(p2putil.LogOrgReqID, pr.message.OriginalID().String()).Msg("Send NewBlockNotice after long skip") + } if ok, _ := p.blkHashCache.ContainsOrAdd(blkhash, cachePlaceHolder); ok { // the remote peer already know this block hash. skip it // too many not-insteresting log, @@ -122,6 +144,8 @@ func (pr *pbBlkNoticeOrder) SendTo(pi p2pcommon.RemotePeer) error { p.logger.Warn().Str(p2putil.LogPeerName, p.Name()).Str(p2putil.LogProtoID, pr.GetProtocolID().String()).Str(p2putil.LogMsgID, pr.GetMsgID().String()).Err(err).Msg("fail to SendTo") return err } + p.skipCnt = 0 + p.lastBlkNoticeTime = time.Now() return nil } diff --git a/p2p/protobufHelper_test.go b/p2p/protobufHelper_test.go index b8600294f..949148b41 100644 --- a/p2p/protobufHelper_test.go +++ b/p2p/protobufHelper_test.go @@ -7,7 +7,9 @@ package p2p import ( "fmt" + "math/rand" "testing" + "time" "github.com/aergoio/aergo/p2p/p2pcommon" "github.com/aergoio/aergo/p2p/p2pmock" @@ -135,8 +137,9 @@ func Test_pbBlkNoticeOrder_SendTo(t *testing.T) { mockRW.EXPECT().WriteMsg(gomock.Any()).Return(tt.writeErr).Times(1) } peer := newRemotePeer(sampleMeta, 0, mockPeerManager, mockActorServ, logger, factory, &dummySigner{}, nil, mockRW) + peer.lastStatus = &types.LastBlockStatus{} - target := factory.NewMsgBlkBroadcastOrder(&types.NewBlockNotice{BlockHash: dummyBlockHash}) + target := factory.NewMsgBlkBroadcastOrder(&types.NewBlockNotice{BlockHash: dummyBlockHash, BlockNo:1}) msgID := sampleMsgID // notice broadcast is affected by cache // put dummy request information in cache @@ -157,6 +160,152 @@ func Test_pbBlkNoticeOrder_SendTo(t *testing.T) { } } +func Test_pbBlkNoticeOrder_SendTo_SkipByHeight(t *testing.T) { + allSendCnt := 3 + hashes := make([][]byte,allSendCnt) + for i:=0 ; i>1, 3,4}, + //// skip same or higher peer + //// the first notice is same and skip but seconds will be sent + {"TSamePeer", 0, 3, time.Second>>2, 2,3}, + {"TPartialHigh", 900, 3, time.Second>>2, 0,1}, + {"THighPeer", 10000, 3, time.Second>>2, 0,1}, + {"TVeryHighPeer", 100000, 3, time.Second>>2, 0,1}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mockActorServ := p2pmock.NewMockActorService(ctrl) + mockPeerManager := p2pmock.NewMockPeerManager(ctrl) + mockRW := p2pmock.NewMockMsgReadWriter(ctrl) + + writeCnt := 0 + mockRW.EXPECT().WriteMsg(gomock.Any()).Do(func(arg interface{}) { + writeCnt++ + }).MinTimes(tt.wantSentLow) + + notiNo := uint64(99999) + peerBlkNo := uint64(int64(notiNo)+int64(tt.noDiff)) + peer := newRemotePeer(sampleMeta, 0, mockPeerManager, mockActorServ, logger, factory, &dummySigner{}, nil, mockRW) + peer.lastStatus = &types.LastBlockStatus{BlockNumber:peerBlkNo} + + skipMax := int32(0) + for i:=0; i0 { + // sleep tree times + time.Sleep(time.Second >> 2 ) + } + } + fmt.Printf("%v : Max skipCnt %v \n",tt.name, skipMax) + + }) + } +} + func Test_pbTxNoticeOrder_SendTo(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() diff --git a/p2p/remotepeer.go b/p2p/remotepeer.go index 8d5955725..7dc678cba 100644 --- a/p2p/remotepeer.go +++ b/p2p/remotepeer.go @@ -73,10 +73,12 @@ type remotePeerImpl struct { handlers map[p2pcommon.SubProtocol]p2pcommon.MessageHandler // TODO make automatic disconnect if remote peer cause too many wrong message - blkHashCache *lru.Cache txHashCache *lru.Cache - lastNotice *types.LastBlockStatus + lastStatus *types.LastBlockStatus + // lastBlkNoticeTime is time that local peer sent NewBlockNotice to this remote peer + lastBlkNoticeTime time.Time + skipCnt int32 txQueueLock *sync.Mutex txNoticeQueue *p2putil.PressableQueue @@ -97,7 +99,7 @@ func newRemotePeer(meta p2pcommon.PeerMeta, manageNum uint32, pm p2pcommon.PeerM pingDuration: defaultPingInterval, state: types.STARTING, - lastNotice: &types.LastBlockStatus{}, + lastStatus: &types.LastBlockStatus{}, stopChan: make(chan struct{}, 1), closeWrite: make(chan struct{}), @@ -152,8 +154,8 @@ func (p *remotePeerImpl) State() types.PeerState { return p.state.Get() } -func (p *remotePeerImpl) LastNotice() *types.LastBlockStatus { - return p.lastNotice +func (p *remotePeerImpl) LastStatus() *types.LastBlockStatus { + return p.lastStatus } // runPeer should be called by go routine @@ -259,7 +261,7 @@ func (p *remotePeerImpl) handleMsg(msg p2pcommon.Message) error { subProto := msg.Subprotocol() defer func() { if r := recover(); r != nil { - p.logger.Error().Str(p2putil.LogProtoID,subProto.String()).Str("callstack", string(debug.Stack())).Interface("panic", r).Msg("There were panic in handler.") + p.logger.Error().Str(p2putil.LogProtoID, subProto.String()).Str("callstack", string(debug.Stack())).Interface("panic", r).Msg("There were panic in handler.") err = fmt.Errorf("internal error") } }() @@ -495,7 +497,7 @@ func (p *remotePeerImpl) UpdateTxCache(hashes []types.TxID) []types.TxID { } func (p *remotePeerImpl) UpdateLastNotice(blkHash []byte, blkNumber uint64) { - p.lastNotice = &types.LastBlockStatus{time.Now(), blkHash, blkNumber} + p.lastStatus = &types.LastBlockStatus{time.Now(), blkHash, blkNumber} } func (p *remotePeerImpl) sendGoAway(msg string) { diff --git a/p2p/remotepeer_test.go b/p2p/remotepeer_test.go index caf5281be..d06dbfa47 100644 --- a/p2p/remotepeer_test.go +++ b/p2p/remotepeer_test.go @@ -341,10 +341,10 @@ func TestRemotePeerImpl_UpdateBlkCache(t *testing.T) { for _, hash := range test.inCache { target.blkHashCache.Add(hash, true) } - target.lastNotice = &types.LastBlockStatus{BlockHash: test.prevLastBlk[:], BlockNumber: 0, CheckTime: time.Now()} + target.lastStatus = &types.LastBlockStatus{BlockHash: test.prevLastBlk[:], BlockNumber: 0, CheckTime: time.Now()} actual := target.UpdateBlkCache(test.hash[:], 0) assert.Equal(t, test.expected, actual) - assert.True(t, bytes.Equal(test.hash[:], target.LastNotice().BlockHash)) + assert.True(t, bytes.Equal(test.hash[:], target.LastStatus().BlockHash)) }) } } diff --git a/p2p/v030mofactory.go b/p2p/v030mofactory.go index 042183654..e407dce22 100644 --- a/p2p/v030mofactory.go +++ b/p2p/v030mofactory.go @@ -52,6 +52,7 @@ func (mf *v030MOFactory) NewMsgBlkBroadcastOrder(noticeMsg *types.NewBlockNotice msgID := uuid.Must(uuid.NewV4()) if newV030MsgOrder(&rmo.pbMessageOrder, msgID, uuid.Nil, subproto.NewBlockNotice, noticeMsg) { rmo.blkHash = noticeMsg.BlockHash + rmo.blkNo = noticeMsg.BlockNo return rmo } return nil diff --git a/types/p2pmore.go b/types/p2pmore.go index 03222ca9e..ddd30c081 100644 --- a/types/p2pmore.go +++ b/types/p2pmore.go @@ -21,7 +21,7 @@ type PeerAccessor interface { type PeerBlockInfo interface { ID() peer.ID State() PeerState - LastNotice() *LastBlockStatus + LastStatus() *LastBlockStatus } // LastBlockStatus i From a75e1b5c20a0500a9e4c7afe333df843a3981e4b Mon Sep 17 00:00:00 2001 From: Hayarobi Park Date: Fri, 19 Apr 2019 18:26:57 +0900 Subject: [PATCH 020/148] [P2P] Tune to skip useless block notice - Skip almost all relay block notice to peer with too high block. - Relay block notices are sent at least interval of a quarter of second; notices will be skipped when node is syncing. --- p2p/configs.go | 11 +++ p2p/p2pcommon/others.go | 3 +- p2p/p2pmock/mock_remotepeer.go | 10 +-- p2p/peermanager.go | 2 +- p2p/peermanager_test.go | 6 +- p2p/protobufHelper.go | 24 ++++++ p2p/protobufHelper_test.go | 151 ++++++++++++++++++++++++++++++++- p2p/remotepeer.go | 16 ++-- p2p/remotepeer_test.go | 4 +- p2p/v030mofactory.go | 1 + types/p2pmore.go | 2 +- 11 files changed, 209 insertions(+), 21 deletions(-) diff --git a/p2p/configs.go b/p2p/configs.go index 6b24ca7d1..bb282eb1b 100644 --- a/p2p/configs.go +++ b/p2p/configs.go @@ -64,6 +64,17 @@ const ( cachePlaceHolder = true ) +// constants for block notice tuning +const ( + GapToSkipAll = 86400 + GapToSkipHourly = 3600 + GapToSkip5Min = 300 + + HourlyInterval = time.Hour + TenMiniteInterval = time.Minute * 10 + MinNewBlkNotiInterval = time.Second >> 2 +) + // constants about private key const ( DefaultPkKeyPrefix = "aergo-peer" diff --git a/p2p/p2pcommon/others.go b/p2p/p2pcommon/others.go index 9a8db4ffb..52e1003c3 100644 --- a/p2p/p2pcommon/others.go +++ b/p2p/p2pcommon/others.go @@ -21,7 +21,8 @@ type RemotePeer interface { Name() string State() types.PeerState - LastNotice() *types.LastBlockStatus + // LastStatus returns last observed status of remote peer. this value will be changed by notice, or ping + LastStatus() *types.LastBlockStatus RunPeer() Stop() diff --git a/p2p/p2pmock/mock_remotepeer.go b/p2p/p2pmock/mock_remotepeer.go index bbab189be..820d7156c 100644 --- a/p2p/p2pmock/mock_remotepeer.go +++ b/p2p/p2pmock/mock_remotepeer.go @@ -77,18 +77,18 @@ func (mr *MockRemotePeerMockRecorder) ID() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ID", reflect.TypeOf((*MockRemotePeer)(nil).ID)) } -// LastNotice mocks base method -func (m *MockRemotePeer) LastNotice() *types.LastBlockStatus { +// LastStatus mocks base method +func (m *MockRemotePeer) LastStatus() *types.LastBlockStatus { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "LastNotice") + ret := m.ctrl.Call(m, "LastStatus") ret0, _ := ret[0].(*types.LastBlockStatus) return ret0 } -// LastNotice indicates an expected call of LastNotice +// LastStatus indicates an expected call of LastStatus func (mr *MockRemotePeerMockRecorder) LastNotice() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LastNotice", reflect.TypeOf((*MockRemotePeer)(nil).LastNotice)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LastStatus", reflect.TypeOf((*MockRemotePeer)(nil).LastStatus)) } // MF mocks base method diff --git a/p2p/peermanager.go b/p2p/peermanager.go index e6530a740..5623287b0 100644 --- a/p2p/peermanager.go +++ b/p2p/peermanager.go @@ -560,7 +560,7 @@ func (pm *peerManager) GetPeerAddresses(noHidden bool, showSelf bool) []*message continue } addr := meta.ToPeerAddress() - lastNoti := aPeer.LastNotice() + lastNoti := aPeer.LastStatus() pi := &message.PeerInfo{ &addr, meta.Hidden, lastNoti.CheckTime, lastNoti.BlockHash, lastNoti.BlockNumber, aPeer.State(), false} peers = append(peers, pi) diff --git a/p2p/peermanager_test.go b/p2p/peermanager_test.go index 4920d21c4..48821b78f 100644 --- a/p2p/peermanager_test.go +++ b/p2p/peermanager_test.go @@ -112,9 +112,9 @@ func TestPeerManager_GetPeers(t *testing.T) { func TestPeerManager_GetPeerAddresses(t *testing.T) { peersLen := 3 samplePeers := make([]*remotePeerImpl, peersLen) - samplePeers[0] = &remotePeerImpl{meta: p2pcommon.PeerMeta{ID: dummyPeerID}, lastNotice: &types.LastBlockStatus{}} - samplePeers[1] = &remotePeerImpl{meta: p2pcommon.PeerMeta{ID: dummyPeerID2}, lastNotice: &types.LastBlockStatus{}} - samplePeers[2] = &remotePeerImpl{meta: p2pcommon.PeerMeta{ID: dummyPeerID3}, lastNotice: &types.LastBlockStatus{}} + samplePeers[0] = &remotePeerImpl{meta: p2pcommon.PeerMeta{ID: dummyPeerID}, lastStatus: &types.LastBlockStatus{}} + samplePeers[1] = &remotePeerImpl{meta: p2pcommon.PeerMeta{ID: dummyPeerID2}, lastStatus: &types.LastBlockStatus{}} + samplePeers[2] = &remotePeerImpl{meta: p2pcommon.PeerMeta{ID: dummyPeerID3}, lastStatus: &types.LastBlockStatus{}} tests := []struct { name string }{ diff --git a/p2p/protobufHelper.go b/p2p/protobufHelper.go index 5d0ae9bb6..54b701345 100644 --- a/p2p/protobufHelper.go +++ b/p2p/protobufHelper.go @@ -105,11 +105,33 @@ func (pr *pbResponseOrder) SendTo(pi p2pcommon.RemotePeer) error { type pbBlkNoticeOrder struct { pbMessageOrder blkHash []byte + blkNo uint64 } func (pr *pbBlkNoticeOrder) SendTo(pi p2pcommon.RemotePeer) error { p := pi.(*remotePeerImpl) var blkhash = types.ToBlockID(pr.blkHash) + passedTime := time.Now().Sub(p.lastBlkNoticeTime) + skipNotice := false + if p.LastStatus().BlockNumber >= pr.blkNo { + heightDiff := p.LastStatus().BlockNumber - pr.blkNo + switch { + case heightDiff >= GapToSkipAll: + skipNotice = true + case heightDiff >= GapToSkipHourly: + skipNotice = p.skipCnt < GapToSkipHourly + default: + skipNotice = p.skipCnt < GapToSkip5Min + } + } + if skipNotice || passedTime < MinNewBlkNotiInterval { + p.skipCnt++ + return nil + } + + if p.skipCnt > 100 { + p.logger.Debug().Str(p2putil.LogPeerName, p.Name()).Str(p2putil.LogProtoID, pr.GetProtocolID().String()).Int32("skip_cnt", p.skipCnt).Str(p2putil.LogMsgID, pr.GetMsgID().String()).Str(p2putil.LogOrgReqID, pr.message.OriginalID().String()).Msg("Send NewBlockNotice after long skip") + } if ok, _ := p.blkHashCache.ContainsOrAdd(blkhash, cachePlaceHolder); ok { // the remote peer already know this block hash. skip it // too many not-insteresting log, @@ -122,6 +144,8 @@ func (pr *pbBlkNoticeOrder) SendTo(pi p2pcommon.RemotePeer) error { p.logger.Warn().Str(p2putil.LogPeerName, p.Name()).Str(p2putil.LogProtoID, pr.GetProtocolID().String()).Str(p2putil.LogMsgID, pr.GetMsgID().String()).Err(err).Msg("fail to SendTo") return err } + p.skipCnt = 0 + p.lastBlkNoticeTime = time.Now() return nil } diff --git a/p2p/protobufHelper_test.go b/p2p/protobufHelper_test.go index b8600294f..949148b41 100644 --- a/p2p/protobufHelper_test.go +++ b/p2p/protobufHelper_test.go @@ -7,7 +7,9 @@ package p2p import ( "fmt" + "math/rand" "testing" + "time" "github.com/aergoio/aergo/p2p/p2pcommon" "github.com/aergoio/aergo/p2p/p2pmock" @@ -135,8 +137,9 @@ func Test_pbBlkNoticeOrder_SendTo(t *testing.T) { mockRW.EXPECT().WriteMsg(gomock.Any()).Return(tt.writeErr).Times(1) } peer := newRemotePeer(sampleMeta, 0, mockPeerManager, mockActorServ, logger, factory, &dummySigner{}, nil, mockRW) + peer.lastStatus = &types.LastBlockStatus{} - target := factory.NewMsgBlkBroadcastOrder(&types.NewBlockNotice{BlockHash: dummyBlockHash}) + target := factory.NewMsgBlkBroadcastOrder(&types.NewBlockNotice{BlockHash: dummyBlockHash, BlockNo:1}) msgID := sampleMsgID // notice broadcast is affected by cache // put dummy request information in cache @@ -157,6 +160,152 @@ func Test_pbBlkNoticeOrder_SendTo(t *testing.T) { } } +func Test_pbBlkNoticeOrder_SendTo_SkipByHeight(t *testing.T) { + allSendCnt := 3 + hashes := make([][]byte,allSendCnt) + for i:=0 ; i>1, 3,4}, + //// skip same or higher peer + //// the first notice is same and skip but seconds will be sent + {"TSamePeer", 0, 3, time.Second>>2, 2,3}, + {"TPartialHigh", 900, 3, time.Second>>2, 0,1}, + {"THighPeer", 10000, 3, time.Second>>2, 0,1}, + {"TVeryHighPeer", 100000, 3, time.Second>>2, 0,1}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mockActorServ := p2pmock.NewMockActorService(ctrl) + mockPeerManager := p2pmock.NewMockPeerManager(ctrl) + mockRW := p2pmock.NewMockMsgReadWriter(ctrl) + + writeCnt := 0 + mockRW.EXPECT().WriteMsg(gomock.Any()).Do(func(arg interface{}) { + writeCnt++ + }).MinTimes(tt.wantSentLow) + + notiNo := uint64(99999) + peerBlkNo := uint64(int64(notiNo)+int64(tt.noDiff)) + peer := newRemotePeer(sampleMeta, 0, mockPeerManager, mockActorServ, logger, factory, &dummySigner{}, nil, mockRW) + peer.lastStatus = &types.LastBlockStatus{BlockNumber:peerBlkNo} + + skipMax := int32(0) + for i:=0; i0 { + // sleep tree times + time.Sleep(time.Second >> 2 ) + } + } + fmt.Printf("%v : Max skipCnt %v \n",tt.name, skipMax) + + }) + } +} + func Test_pbTxNoticeOrder_SendTo(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() diff --git a/p2p/remotepeer.go b/p2p/remotepeer.go index 8d5955725..7dc678cba 100644 --- a/p2p/remotepeer.go +++ b/p2p/remotepeer.go @@ -73,10 +73,12 @@ type remotePeerImpl struct { handlers map[p2pcommon.SubProtocol]p2pcommon.MessageHandler // TODO make automatic disconnect if remote peer cause too many wrong message - blkHashCache *lru.Cache txHashCache *lru.Cache - lastNotice *types.LastBlockStatus + lastStatus *types.LastBlockStatus + // lastBlkNoticeTime is time that local peer sent NewBlockNotice to this remote peer + lastBlkNoticeTime time.Time + skipCnt int32 txQueueLock *sync.Mutex txNoticeQueue *p2putil.PressableQueue @@ -97,7 +99,7 @@ func newRemotePeer(meta p2pcommon.PeerMeta, manageNum uint32, pm p2pcommon.PeerM pingDuration: defaultPingInterval, state: types.STARTING, - lastNotice: &types.LastBlockStatus{}, + lastStatus: &types.LastBlockStatus{}, stopChan: make(chan struct{}, 1), closeWrite: make(chan struct{}), @@ -152,8 +154,8 @@ func (p *remotePeerImpl) State() types.PeerState { return p.state.Get() } -func (p *remotePeerImpl) LastNotice() *types.LastBlockStatus { - return p.lastNotice +func (p *remotePeerImpl) LastStatus() *types.LastBlockStatus { + return p.lastStatus } // runPeer should be called by go routine @@ -259,7 +261,7 @@ func (p *remotePeerImpl) handleMsg(msg p2pcommon.Message) error { subProto := msg.Subprotocol() defer func() { if r := recover(); r != nil { - p.logger.Error().Str(p2putil.LogProtoID,subProto.String()).Str("callstack", string(debug.Stack())).Interface("panic", r).Msg("There were panic in handler.") + p.logger.Error().Str(p2putil.LogProtoID, subProto.String()).Str("callstack", string(debug.Stack())).Interface("panic", r).Msg("There were panic in handler.") err = fmt.Errorf("internal error") } }() @@ -495,7 +497,7 @@ func (p *remotePeerImpl) UpdateTxCache(hashes []types.TxID) []types.TxID { } func (p *remotePeerImpl) UpdateLastNotice(blkHash []byte, blkNumber uint64) { - p.lastNotice = &types.LastBlockStatus{time.Now(), blkHash, blkNumber} + p.lastStatus = &types.LastBlockStatus{time.Now(), blkHash, blkNumber} } func (p *remotePeerImpl) sendGoAway(msg string) { diff --git a/p2p/remotepeer_test.go b/p2p/remotepeer_test.go index caf5281be..d06dbfa47 100644 --- a/p2p/remotepeer_test.go +++ b/p2p/remotepeer_test.go @@ -341,10 +341,10 @@ func TestRemotePeerImpl_UpdateBlkCache(t *testing.T) { for _, hash := range test.inCache { target.blkHashCache.Add(hash, true) } - target.lastNotice = &types.LastBlockStatus{BlockHash: test.prevLastBlk[:], BlockNumber: 0, CheckTime: time.Now()} + target.lastStatus = &types.LastBlockStatus{BlockHash: test.prevLastBlk[:], BlockNumber: 0, CheckTime: time.Now()} actual := target.UpdateBlkCache(test.hash[:], 0) assert.Equal(t, test.expected, actual) - assert.True(t, bytes.Equal(test.hash[:], target.LastNotice().BlockHash)) + assert.True(t, bytes.Equal(test.hash[:], target.LastStatus().BlockHash)) }) } } diff --git a/p2p/v030mofactory.go b/p2p/v030mofactory.go index 042183654..e407dce22 100644 --- a/p2p/v030mofactory.go +++ b/p2p/v030mofactory.go @@ -52,6 +52,7 @@ func (mf *v030MOFactory) NewMsgBlkBroadcastOrder(noticeMsg *types.NewBlockNotice msgID := uuid.Must(uuid.NewV4()) if newV030MsgOrder(&rmo.pbMessageOrder, msgID, uuid.Nil, subproto.NewBlockNotice, noticeMsg) { rmo.blkHash = noticeMsg.BlockHash + rmo.blkNo = noticeMsg.BlockNo return rmo } return nil diff --git a/types/p2pmore.go b/types/p2pmore.go index 03222ca9e..ddd30c081 100644 --- a/types/p2pmore.go +++ b/types/p2pmore.go @@ -21,7 +21,7 @@ type PeerAccessor interface { type PeerBlockInfo interface { ID() peer.ID State() PeerState - LastNotice() *LastBlockStatus + LastStatus() *LastBlockStatus } // LastBlockStatus i From 63923148f705ebdc351a8fe48340adf98b3a67cf Mon Sep 17 00:00:00 2001 From: Sung-Jae Woo Date: Mon, 8 Apr 2019 03:04:34 +0900 Subject: [PATCH 021/148] [chain] add data structures for chain statistics - Add general data structures for various chain statistics. - Add reorganization stat. --- chain/stat.go | 142 +++++++++++++++++++++++++++++++++++++++++++++ chain/stat_test.go | 60 +++++++++++++++++++ 2 files changed, 202 insertions(+) create mode 100644 chain/stat.go create mode 100644 chain/stat_test.go diff --git a/chain/stat.go b/chain/stat.go new file mode 100644 index 000000000..0d12423df --- /dev/null +++ b/chain/stat.go @@ -0,0 +1,142 @@ +package chain + +import ( + "sync" +) + +const ( + // TODO: Generate code converting the constants below to the corresponding + // string by using 'go generate' command. + + // StatReorg is a constant representing a stat about reorganization. + statReorg = iota + // StatMax is a constant representing a value less than which all the + // constants corresponding chain stats must be. + statMax +) + +var ( + // To add a new one to chain stats, implements statItem interface and add + // its constructor here. Additionally you need to add a constant + // corresponding to its index like statReorg above. + statItemCtors = map[int]func() statItem{ + statReorg: newStReorg, + } +) + +type stats []*stat + +func newStats() stats { + s := make(stats, statMax) + for i := 0; i < statMax; i++ { + s[i] = newStat(statItemCtors[i]()) + } + return s +} + +func (s stats) get(statIdx int) *stat { + return []*stat(s)[statIdx] +} + +func (s stats) clone(statIdx int) interface{} { + i := s.get(statIdx) + i.RLock() + defer i.RUnlock() + return i.clone() +} + +func (s stats) getCount(statIdx int) int64 { + i := s.get(statIdx) + i.RLock() + defer i.RUnlock() + + return i.getCount() +} + +func (s stats) getLastestEvent(statIdx int) interface{} { + i := s.get(statIdx) + i.RLock() + defer i.RUnlock() + + return i.getLatestEvent() +} + +func (s stats) updateEvent(statIdx int, args ...interface{}) { + i := s.get(statIdx) + i.Lock() + defer i.Unlock() + + i.updateEvent(args...) +} + +type stat struct { + sync.RWMutex + statItem +} + +func newStat(i statItem) *stat { + return &stat{statItem: i} +} + +type statItem interface { + getCount() int64 + getLatestEvent() interface{} + updateEvent(args ...interface{}) + clone() interface{} +} + +type stReorg struct { + Count int64 + Latest *evReorg +} + +func newStReorg() statItem { + return &stReorg{} +} + +type evReorg struct { + OldBest string + NewBest string + Branch string +} + +func (sr *stReorg) getCount() int64 { + return sr.Count +} + +func (sr *stReorg) getLatestEvent() interface{} { + return sr.Latest +} + +func (sr *stReorg) updateEvent(args ...interface{}) { + if len(args) != 3 { + logger.Debug().Int("len", len(args)).Msg("invalid arguments for the reorg stat update") + return + } + + s := make([]string, len(args)) + for i, a := range args { + ok := false + if s[i], ok = a.(string); !ok { + logger.Debug().Int("arg idx", i).Msg("non-string arguemt for the reorg stat update") + return + } + } + + sr.Latest = &evReorg{ + OldBest: s[0], + NewBest: s[1], + Branch: s[2], + } + sr.Count++ +} + +func (sr *stReorg) clone() interface{} { + c := *sr + if sr.Latest != nil { + l := *sr.Latest + c.Latest = &l + } + + return &c +} diff --git a/chain/stat_test.go b/chain/stat_test.go new file mode 100644 index 000000000..ad44cd6d9 --- /dev/null +++ b/chain/stat_test.go @@ -0,0 +1,60 @@ +package chain + +import ( + "encoding/json" + "fmt" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestChainStatBasic(t *testing.T) { + var chk = assert.New(t) + + stats := newStats() + chk.Equal(len(stats), statMax, "# of stat item is inconsistent.") + for i, st := range stats { + chk.Equal(int64(0), st.getCount(), "stat[%d] initial # of events must be 0.", i) + } +} + +func TestChainStatReorgBasic(t *testing.T) { + var chk = assert.New(t) + + stats := newStats() + i := statReorg + chk.Equal(int64(0), stats.getCount(i), "reorg stat's initial # of events must be 0.") + stats.updateEvent(i, "a", "b", "c") + chk.Equal(int64(1), stats.getCount(i)) + stats.updateEvent(i, "a", "b", "c") + stats.updateEvent(i, "a", "b", "c") + stats.updateEvent(i, "a", "b", "c") + chk.Equal(int64(4), stats.getCount(i)) + + b, err := json.Marshal(stats.getLastestEvent(i)) + chk.Nil(err) + fmt.Println(string(b)) +} + +func TestChainStatReorgClone(t *testing.T) { + var chk = assert.New(t) + + stats := newStats() + i := statReorg + + r := stats.clone(i) + chk.NotNil(r) + b, err := json.Marshal(r) + chk.Nil(err) + fmt.Println(string(b)) + + stats.updateEvent(i, "a", "b", "c") + stats.updateEvent(i, "a", "b", "c") + stats.updateEvent(i, "a", "b", "c") + r = stats.clone(i) + chk.NotNil(r) + b, err = json.Marshal(r) + chk.Nil(err) + fmt.Println(string(b)) + +} From 80c6b59a584fa65d0f30e370beeb8c64e3a69c4e Mon Sep 17 00:00:00 2001 From: Sung-Jae Woo Date: Tue, 9 Apr 2019 10:54:40 +0900 Subject: [PATCH 022/148] [chain] add chain stats to chain service --- chain/chainservice.go | 7 +++++-- chain/reorg.go | 3 +++ chain/stat.go | 32 ++++++++++++++++++++++---------- chain/stat_test.go | 17 ++++++++++------- 4 files changed, 40 insertions(+), 19 deletions(-) diff --git a/chain/chainservice.go b/chain/chainservice.go index d517e39cb..a4a858130 100644 --- a/chain/chainservice.go +++ b/chain/chainservice.go @@ -198,13 +198,16 @@ type ChainService struct { chainWorker *ChainWorker chainManager *ChainManager + + stat stats } // NewChainService creates an instance of ChainService. func NewChainService(cfg *cfg.Config) *ChainService { cs := &ChainService{ - cfg: cfg, - op: NewOrphanPool(), + cfg: cfg, + op: NewOrphanPool(), + stat: newStats(), } var err error diff --git a/chain/reorg.go b/chain/reorg.go index 1ac3fad24..ebeb8665e 100644 --- a/chain/reorg.go +++ b/chain/reorg.go @@ -4,6 +4,7 @@ import ( "bytes" "errors" "fmt" + "github.com/aergoio/aergo-lib/db" "github.com/aergoio/aergo/consensus" "github.com/aergoio/aergo/internal/enc" @@ -112,6 +113,8 @@ func (cs *ChainService) reorg(topBlock *types.Block) error { return err } + cs.stat.updateEvent(statReorg, reorg.oldBlocks[0], reorg.newBlocks[0], reorg.brTopBlock) + logger.Info().Msg("reorg end") return nil diff --git a/chain/stat.go b/chain/stat.go index 0d12423df..0c56aeeab 100644 --- a/chain/stat.go +++ b/chain/stat.go @@ -2,6 +2,9 @@ package chain import ( "sync" + "time" + + "github.com/aergoio/aergo/types" ) const ( @@ -95,9 +98,15 @@ func newStReorg() statItem { } type evReorg struct { - OldBest string - NewBest string - Branch string + OldBest *blockInfo + NewBest *blockInfo + Branch *blockInfo + time time.Time +} + +type blockInfo struct { + Hash string + Height types.BlockNo } func (sr *stReorg) getCount() int64 { @@ -110,23 +119,26 @@ func (sr *stReorg) getLatestEvent() interface{} { func (sr *stReorg) updateEvent(args ...interface{}) { if len(args) != 3 { - logger.Debug().Int("len", len(args)).Msg("invalid arguments for the reorg stat update") + logger.Info().Int("len", len(args)).Msg("invalid # of arguments for the reorg stat update") return } - s := make([]string, len(args)) + bi := make([]*blockInfo, len(args)) for i, a := range args { + var block *types.Block ok := false - if s[i], ok = a.(string); !ok { - logger.Debug().Int("arg idx", i).Msg("non-string arguemt for the reorg stat update") + if block, ok = a.(*types.Block); !ok { + logger.Info().Int("arg idx", i).Msg("invalid type of argument") return } + bi[i] = &blockInfo{Hash: block.ID(), Height: block.BlockNo()} } sr.Latest = &evReorg{ - OldBest: s[0], - NewBest: s[1], - Branch: s[2], + OldBest: bi[0], + NewBest: bi[1], + Branch: bi[2], + time: time.Now(), } sr.Count++ } diff --git a/chain/stat_test.go b/chain/stat_test.go index ad44cd6d9..13304e33a 100644 --- a/chain/stat_test.go +++ b/chain/stat_test.go @@ -5,9 +5,12 @@ import ( "fmt" "testing" + "github.com/aergoio/aergo/types" "github.com/stretchr/testify/assert" ) +var block = types.NewBlock(nil, nil, nil, nil, nil, 0) + func TestChainStatBasic(t *testing.T) { var chk = assert.New(t) @@ -24,11 +27,11 @@ func TestChainStatReorgBasic(t *testing.T) { stats := newStats() i := statReorg chk.Equal(int64(0), stats.getCount(i), "reorg stat's initial # of events must be 0.") - stats.updateEvent(i, "a", "b", "c") + stats.updateEvent(i, block, block, block) chk.Equal(int64(1), stats.getCount(i)) - stats.updateEvent(i, "a", "b", "c") - stats.updateEvent(i, "a", "b", "c") - stats.updateEvent(i, "a", "b", "c") + stats.updateEvent(i, block, block, block) + stats.updateEvent(i, block, block, block) + stats.updateEvent(i, block, block, block) chk.Equal(int64(4), stats.getCount(i)) b, err := json.Marshal(stats.getLastestEvent(i)) @@ -48,9 +51,9 @@ func TestChainStatReorgClone(t *testing.T) { chk.Nil(err) fmt.Println(string(b)) - stats.updateEvent(i, "a", "b", "c") - stats.updateEvent(i, "a", "b", "c") - stats.updateEvent(i, "a", "b", "c") + stats.updateEvent(i, block, block, block) + stats.updateEvent(i, block, block, block) + stats.updateEvent(i, block, block, block) r = stats.clone(i) chk.NotNil(r) b, err = json.Marshal(r) From eafe58d9aed42058c76869bc5fbd8a9839e3aa43 Mon Sep 17 00:00:00 2001 From: Sung-Jae Woo Date: Tue, 9 Apr 2019 11:31:28 +0900 Subject: [PATCH 023/148] [chain] add a method generating the stat summary in JSON --- chain/reorg.go | 2 +- chain/stat.go | 58 +++++++++++++++++++++++++-------------- chain/stat_test.go | 19 +++++++++++-- chain/statindex_string.go | 16 +++++++++++ 4 files changed, 71 insertions(+), 24 deletions(-) create mode 100644 chain/statindex_string.go diff --git a/chain/reorg.go b/chain/reorg.go index ebeb8665e..4bf1cedbf 100644 --- a/chain/reorg.go +++ b/chain/reorg.go @@ -113,7 +113,7 @@ func (cs *ChainService) reorg(topBlock *types.Block) error { return err } - cs.stat.updateEvent(statReorg, reorg.oldBlocks[0], reorg.newBlocks[0], reorg.brTopBlock) + cs.stat.updateEvent(ReorgStat, reorg.oldBlocks[0], reorg.newBlocks[0], reorg.brTopBlock) logger.Info().Msg("reorg end") diff --git a/chain/stat.go b/chain/stat.go index 0c56aeeab..e6f665543 100644 --- a/chain/stat.go +++ b/chain/stat.go @@ -1,71 +1,89 @@ package chain import ( + "encoding/json" "sync" "time" "github.com/aergoio/aergo/types" ) +//go:generate stringer -type=statIndex +type statIndex int + const ( - // TODO: Generate code converting the constants below to the corresponding - // string by using 'go generate' command. + // Warning: Each statIndex contant has a String method, which is + // automically generated by 'stringer' with 'go generate' command. For the + // detail, check https://blog.golang.org/generate - // StatReorg is a constant representing a stat about reorganization. - statReorg = iota - // StatMax is a constant representing a value less than which all the + // ReorgStat is a constant representing a stat about reorganization. + ReorgStat statIndex = iota + // MaxStat is a constant representing a value less than which all the // constants corresponding chain stats must be. - statMax + MaxStat ) var ( // To add a new one to chain stats, implements statItem interface and add // its constructor here. Additionally you need to add a constant // corresponding to its index like statReorg above. - statItemCtors = map[int]func() statItem{ - statReorg: newStReorg, + statItemCtors = map[statIndex]func() statItem{ + ReorgStat: newStReorg, } ) type stats []*stat func newStats() stats { - s := make(stats, statMax) - for i := 0; i < statMax; i++ { + s := make(stats, MaxStat) + for i := statIndex(0); i < MaxStat; i++ { s[i] = newStat(statItemCtors[i]()) } return s } -func (s stats) get(statIdx int) *stat { - return []*stat(s)[statIdx] +func (s stats) JSON() string { + r := make(map[string]json.RawMessage) + for i := statIndex(0); i < MaxStat; i++ { + if b, err := json.Marshal(s.clone(i)); err == nil { + r[i.String()] = json.RawMessage(b) + } + } + if m, err := json.Marshal(r); err == nil { + return string(m) + } + return "" +} + +func (s stats) get(idx statIndex) *stat { + return []*stat(s)[idx] } -func (s stats) clone(statIdx int) interface{} { - i := s.get(statIdx) +func (s stats) clone(idx statIndex) interface{} { + i := s.get(idx) i.RLock() defer i.RUnlock() return i.clone() } -func (s stats) getCount(statIdx int) int64 { - i := s.get(statIdx) +func (s stats) getCount(idx statIndex) int64 { + i := s.get(idx) i.RLock() defer i.RUnlock() return i.getCount() } -func (s stats) getLastestEvent(statIdx int) interface{} { - i := s.get(statIdx) +func (s stats) getLastestEvent(idx statIndex) interface{} { + i := s.get(idx) i.RLock() defer i.RUnlock() return i.getLatestEvent() } -func (s stats) updateEvent(statIdx int, args ...interface{}) { - i := s.get(statIdx) +func (s stats) updateEvent(idx statIndex, args ...interface{}) { + i := s.get(idx) i.Lock() defer i.Unlock() diff --git a/chain/stat_test.go b/chain/stat_test.go index 13304e33a..1be3eb933 100644 --- a/chain/stat_test.go +++ b/chain/stat_test.go @@ -15,7 +15,7 @@ func TestChainStatBasic(t *testing.T) { var chk = assert.New(t) stats := newStats() - chk.Equal(len(stats), statMax, "# of stat item is inconsistent.") + chk.Equal(statIndex(len(stats)), MaxStat, "# of stat item is inconsistent.") for i, st := range stats { chk.Equal(int64(0), st.getCount(), "stat[%d] initial # of events must be 0.", i) } @@ -25,7 +25,7 @@ func TestChainStatReorgBasic(t *testing.T) { var chk = assert.New(t) stats := newStats() - i := statReorg + i := ReorgStat chk.Equal(int64(0), stats.getCount(i), "reorg stat's initial # of events must be 0.") stats.updateEvent(i, block, block, block) chk.Equal(int64(1), stats.getCount(i)) @@ -43,7 +43,7 @@ func TestChainStatReorgClone(t *testing.T) { var chk = assert.New(t) stats := newStats() - i := statReorg + i := ReorgStat r := stats.clone(i) chk.NotNil(r) @@ -59,5 +59,18 @@ func TestChainStatReorgClone(t *testing.T) { b, err = json.Marshal(r) chk.Nil(err) fmt.Println(string(b)) +} + +func TestChainStatJSON(t *testing.T) { + var chk = assert.New(t) + + stats := newStats() + i := ReorgStat + stats.updateEvent(i, block, block, block) + stats.updateEvent(i, block, block, block) + stats.updateEvent(i, block, block, block) + s := stats.JSON() + chk.NotZero(len(s)) + fmt.Println(s) } diff --git a/chain/statindex_string.go b/chain/statindex_string.go new file mode 100644 index 000000000..544b45e35 --- /dev/null +++ b/chain/statindex_string.go @@ -0,0 +1,16 @@ +// Code generated by "stringer -type=statIndex"; DO NOT EDIT. + +package chain + +import "strconv" + +const _statIndex_name = "ReorgStatMaxStat" + +var _statIndex_index = [...]uint8{0, 9, 16} + +func (i statIndex) String() string { + if i < 0 || i >= statIndex(len(_statIndex_index)-1) { + return "statIndex(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _statIndex_name[_statIndex_index[i]:_statIndex_index[i+1]] +} From 6e4c127708caf299eba864171ee92f8913c206b7 Mon Sep 17 00:00:00 2001 From: Sung-Jae Woo Date: Tue, 9 Apr 2019 17:03:28 +0900 Subject: [PATCH 024/148] [types] add GetChainStats to ChainAccessor interface --- chain/chainservice.go | 4 ++++ chain/stubchain.go | 4 ++++ p2p/p2pmock/mock_chainaccessor.go | 14 ++++++++++++++ types/blockchain.go | 1 + 4 files changed, 23 insertions(+) diff --git a/chain/chainservice.go b/chain/chainservice.go index a4a858130..c1832d216 100644 --- a/chain/chainservice.go +++ b/chain/chainservice.go @@ -285,6 +285,10 @@ func (cs *ChainService) GetConsensusInfo() string { return cs.Info() } +func (cs *ChainService) GetChainStats() string { + return cs.stat.JSON() +} + // SetChainConsensus sets cs.cc to cc. func (cs *ChainService) SetChainConsensus(cc consensus.ChainConsensus) { cs.ChainConsensus = cc diff --git a/chain/stubchain.go b/chain/stubchain.go index b6bdfa179..7a3ba3bad 100644 --- a/chain/stubchain.go +++ b/chain/stubchain.go @@ -118,6 +118,10 @@ func (tchain *StubBlockChain) GetConsensusInfo() string { return "" } +func (tchain *StubBlockChain) GetChainStats() string { + return "" +} + func (tchain *StubBlockChain) GetBestBlock() (*types.Block, error) { return tchain.BestBlock, nil } diff --git a/p2p/p2pmock/mock_chainaccessor.go b/p2p/p2pmock/mock_chainaccessor.go index b8f652ca9..d33e1357e 100644 --- a/p2p/p2pmock/mock_chainaccessor.go +++ b/p2p/p2pmock/mock_chainaccessor.go @@ -62,6 +62,20 @@ func (mr *MockChainAccessorMockRecorder) GetConsensusInfo() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetConsensusInfo", reflect.TypeOf((*MockChainAccessor)(nil).GetConsensusInfo)) } +// GetChainStats mocks base method +func (m *MockChainAccessor) GetChainStats() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetChainStats") + ret0, _ := ret[0].(string) + return ret0 +} + +// GetConsensusInfo indicates an expected call of GetConsensusInfo +func (mr *MockChainAccessorMockRecorder) GetChainStats() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChainStats", reflect.TypeOf((*MockChainAccessor)(nil).GetChainStats)) +} + // GetBestBlock mocks base method func (m *MockChainAccessor) GetBestBlock() (*types.Block, error) { m.ctrl.T.Helper() diff --git a/types/blockchain.go b/types/blockchain.go index 5b269762b..67936ab85 100644 --- a/types/blockchain.go +++ b/types/blockchain.go @@ -127,6 +127,7 @@ type ChainAccessor interface { GetBlock(blockHash []byte) (*Block, error) // GetHashByNo returns hash of block. It return nil and error if not found block of that number or there is a problem in db store GetHashByNo(blockNo BlockNo) ([]byte, error) + GetChainStats() string } type SyncContext struct { From b2b7448cf7d83d4fa4043ce8490a0fd8e92dc7ea Mon Sep 17 00:00:00 2001 From: Sung-Jae Woo Date: Tue, 9 Apr 2019 20:55:17 +0900 Subject: [PATCH 025/148] [aergocli] display chain statistics in the blockchain status --- chain/reorg.go | 2 +- chain/stat.go | 10 +++++----- cmd/aergocli/util/base58addr.go | 16 ++++++++++++---- cmd/aergocli/util/base64ToHex.go | 1 + rpc/grpcserver.go | 1 + 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/chain/reorg.go b/chain/reorg.go index 4bf1cedbf..91f92f306 100644 --- a/chain/reorg.go +++ b/chain/reorg.go @@ -113,7 +113,7 @@ func (cs *ChainService) reorg(topBlock *types.Block) error { return err } - cs.stat.updateEvent(ReorgStat, reorg.oldBlocks[0], reorg.newBlocks[0], reorg.brTopBlock) + cs.stat.updateEvent(ReorgStat, reorg.oldBlocks[0], reorg.newBlocks[0], reorg.brStartBlock) logger.Info().Msg("reorg end") diff --git a/chain/stat.go b/chain/stat.go index e6f665543..bd5cd6a04 100644 --- a/chain/stat.go +++ b/chain/stat.go @@ -108,7 +108,7 @@ type statItem interface { type stReorg struct { Count int64 - Latest *evReorg + Latest *evReorg `json:",omitempty"` } func newStReorg() statItem { @@ -118,8 +118,8 @@ func newStReorg() statItem { type evReorg struct { OldBest *blockInfo NewBest *blockInfo - Branch *blockInfo - time time.Time + Fork *blockInfo + Time time.Time } type blockInfo struct { @@ -155,8 +155,8 @@ func (sr *stReorg) updateEvent(args ...interface{}) { sr.Latest = &evReorg{ OldBest: bi[0], NewBest: bi[1], - Branch: bi[2], - time: time.Now(), + Fork: bi[2], + Time: time.Now(), } sr.Count++ } diff --git a/cmd/aergocli/util/base58addr.go b/cmd/aergocli/util/base58addr.go index fd6bf9b96..e409bffe7 100644 --- a/cmd/aergocli/util/base58addr.go +++ b/cmd/aergocli/util/base58addr.go @@ -261,11 +261,19 @@ func ConvBlockchainStatus(in *types.BlockchainStatus) string { } out.Hash = base58.Encode(in.BestBlockHash) out.Height = in.BestHeight - if len(in.ConsensusInfo) > 0 { - ci := json.RawMessage(in.ConsensusInfo) - out.ConsensusInfo = &ci - } + out.ChainIdHash = base58.Encode(in.BestChainIdHash) + + toJRM := func(s string) *json.RawMessage { + if len(s) > 0 { + m := json.RawMessage(s) + return &m + } + return nil + } + out.ConsensusInfo = toJRM(in.ConsensusInfo) + out.ChainStat = toJRM(in.ChainStat) + jsonout, err := json.Marshal(out) if err != nil { return "" diff --git a/cmd/aergocli/util/base64ToHex.go b/cmd/aergocli/util/base64ToHex.go index 66cb56b09..0df44e04f 100644 --- a/cmd/aergocli/util/base64ToHex.go +++ b/cmd/aergocli/util/base64ToHex.go @@ -12,6 +12,7 @@ type InOutBlockchainStatus struct { Height uint64 ConsensusInfo *json.RawMessage `json:",omitempty"` ChainIdHash string + ChainStat *json.RawMessage `json:",omitempty"` } func ConvHexBlockchainStatus(in *types.BlockchainStatus) string { diff --git a/rpc/grpcserver.go b/rpc/grpcserver.go index 3dce27412..b45d69be8 100644 --- a/rpc/grpcserver.go +++ b/rpc/grpcserver.go @@ -131,6 +131,7 @@ func (rpc *AergoRPCService) Blockchain(ctx context.Context, in *types.Empty) (*t BestHeight: last.GetHeader().GetBlockNo(), ConsensusInfo: ca.GetConsensusInfo(), BestChainIdHash: bestChainIdHash, + ChainStat: ca.GetChainStats(), }, nil } From 8b686b7db3b851b0eeaa6087a85ba466db0937c6 Mon Sep 17 00:00:00 2001 From: Sung-Jae Woo Date: Fri, 12 Apr 2019 19:33:04 +0900 Subject: [PATCH 026/148] [PB] add chain stat to BlockchainStatus --- aergo-protobuf | 2 +- types/rpc.pb.go | 395 +++++++++++++++++++++++++----------------------- 2 files changed, 203 insertions(+), 194 deletions(-) diff --git a/aergo-protobuf b/aergo-protobuf index 9e86ed578..63059e092 160000 --- a/aergo-protobuf +++ b/aergo-protobuf @@ -1 +1 @@ -Subproject commit 9e86ed57878f691d4a5ab70c50d3410013cccd8b +Subproject commit 63059e092d2610192bf63c3d2e97a50d10c5f6a6 diff --git a/types/rpc.pb.go b/types/rpc.pb.go index bbc1168e8..baf859f29 100644 --- a/types/rpc.pb.go +++ b/types/rpc.pb.go @@ -64,7 +64,7 @@ func (x CommitStatus) String() string { return proto.EnumName(CommitStatus_name, int32(x)) } func (CommitStatus) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{0} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{0} } type VerifyStatus int32 @@ -90,7 +90,7 @@ func (x VerifyStatus) String() string { return proto.EnumName(VerifyStatus_name, int32(x)) } func (VerifyStatus) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{1} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{1} } // BlockchainStatus is current status of blockchain @@ -99,6 +99,7 @@ type BlockchainStatus struct { BestHeight uint64 `protobuf:"varint,2,opt,name=best_height,json=bestHeight,proto3" json:"best_height,omitempty"` ConsensusInfo string `protobuf:"bytes,3,opt,name=consensus_info,json=consensusInfo,proto3" json:"consensus_info,omitempty"` BestChainIdHash []byte `protobuf:"bytes,4,opt,name=best_chain_id_hash,json=bestChainIdHash,proto3" json:"best_chain_id_hash,omitempty"` + ChainStat string `protobuf:"bytes,5,opt,name=chain_stat,json=chainStat,proto3" json:"chain_stat,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -108,7 +109,7 @@ func (m *BlockchainStatus) Reset() { *m = BlockchainStatus{} } func (m *BlockchainStatus) String() string { return proto.CompactTextString(m) } func (*BlockchainStatus) ProtoMessage() {} func (*BlockchainStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{0} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{0} } func (m *BlockchainStatus) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BlockchainStatus.Unmarshal(m, b) @@ -156,6 +157,13 @@ func (m *BlockchainStatus) GetBestChainIdHash() []byte { return nil } +func (m *BlockchainStatus) GetChainStat() string { + if m != nil { + return m.ChainStat + } + return "" +} + type ChainId struct { Magic string `protobuf:"bytes,1,opt,name=magic,proto3" json:"magic,omitempty"` Public bool `protobuf:"varint,2,opt,name=public,proto3" json:"public,omitempty"` @@ -170,7 +178,7 @@ func (m *ChainId) Reset() { *m = ChainId{} } func (m *ChainId) String() string { return proto.CompactTextString(m) } func (*ChainId) ProtoMessage() {} func (*ChainId) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{1} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{1} } func (m *ChainId) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ChainId.Unmarshal(m, b) @@ -237,7 +245,7 @@ func (m *ChainInfo) Reset() { *m = ChainInfo{} } func (m *ChainInfo) String() string { return proto.CompactTextString(m) } func (*ChainInfo) ProtoMessage() {} func (*ChainInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{2} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{2} } func (m *ChainInfo) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ChainInfo.Unmarshal(m, b) @@ -327,7 +335,7 @@ func (m *Input) Reset() { *m = Input{} } func (m *Input) String() string { return proto.CompactTextString(m) } func (*Input) ProtoMessage() {} func (*Input) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{3} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{3} } func (m *Input) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Input.Unmarshal(m, b) @@ -389,7 +397,7 @@ func (m *Output) Reset() { *m = Output{} } func (m *Output) String() string { return proto.CompactTextString(m) } func (*Output) ProtoMessage() {} func (*Output) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{4} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{4} } func (m *Output) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Output.Unmarshal(m, b) @@ -447,7 +455,7 @@ func (m *Empty) Reset() { *m = Empty{} } func (m *Empty) String() string { return proto.CompactTextString(m) } func (*Empty) ProtoMessage() {} func (*Empty) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{5} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{5} } func (m *Empty) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Empty.Unmarshal(m, b) @@ -478,7 +486,7 @@ func (m *SingleBytes) Reset() { *m = SingleBytes{} } func (m *SingleBytes) String() string { return proto.CompactTextString(m) } func (*SingleBytes) ProtoMessage() {} func (*SingleBytes) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{6} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{6} } func (m *SingleBytes) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SingleBytes.Unmarshal(m, b) @@ -516,7 +524,7 @@ func (m *AccountAddress) Reset() { *m = AccountAddress{} } func (m *AccountAddress) String() string { return proto.CompactTextString(m) } func (*AccountAddress) ProtoMessage() {} func (*AccountAddress) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{7} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{7} } func (m *AccountAddress) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_AccountAddress.Unmarshal(m, b) @@ -544,9 +552,9 @@ func (m *AccountAddress) GetValue() []byte { } type AccountAndRoot struct { - Account []byte `protobuf:"bytes,1,opt,name=Account,proto3" json:"Account,omitempty"` - Root []byte `protobuf:"bytes,2,opt,name=Root,proto3" json:"Root,omitempty"` - Compressed bool `protobuf:"varint,3,opt,name=Compressed,proto3" json:"Compressed,omitempty"` + Account []byte `protobuf:"bytes,1,opt,name=Account,json=account,proto3" json:"Account,omitempty"` + Root []byte `protobuf:"bytes,2,opt,name=Root,json=root,proto3" json:"Root,omitempty"` + Compressed bool `protobuf:"varint,3,opt,name=Compressed,json=compressed,proto3" json:"Compressed,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -556,7 +564,7 @@ func (m *AccountAndRoot) Reset() { *m = AccountAndRoot{} } func (m *AccountAndRoot) String() string { return proto.CompactTextString(m) } func (*AccountAndRoot) ProtoMessage() {} func (*AccountAndRoot) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{8} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{8} } func (m *AccountAndRoot) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_AccountAndRoot.Unmarshal(m, b) @@ -613,7 +621,7 @@ func (m *Peer) Reset() { *m = Peer{} } func (m *Peer) String() string { return proto.CompactTextString(m) } func (*Peer) ProtoMessage() {} func (*Peer) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{9} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{9} } func (m *Peer) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Peer.Unmarshal(m, b) @@ -686,7 +694,7 @@ func (m *PeerList) Reset() { *m = PeerList{} } func (m *PeerList) String() string { return proto.CompactTextString(m) } func (*PeerList) ProtoMessage() {} func (*PeerList) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{10} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{10} } func (m *PeerList) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PeerList.Unmarshal(m, b) @@ -728,7 +736,7 @@ func (m *ListParams) Reset() { *m = ListParams{} } func (m *ListParams) String() string { return proto.CompactTextString(m) } func (*ListParams) ProtoMessage() {} func (*ListParams) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{11} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{11} } func (m *ListParams) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ListParams.Unmarshal(m, b) @@ -795,7 +803,7 @@ func (m *PageParams) Reset() { *m = PageParams{} } func (m *PageParams) String() string { return proto.CompactTextString(m) } func (*PageParams) ProtoMessage() {} func (*PageParams) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{12} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{12} } func (m *PageParams) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PageParams.Unmarshal(m, b) @@ -843,7 +851,7 @@ func (m *BlockBodyPaged) Reset() { *m = BlockBodyPaged{} } func (m *BlockBodyPaged) String() string { return proto.CompactTextString(m) } func (*BlockBodyPaged) ProtoMessage() {} func (*BlockBodyPaged) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{13} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{13} } func (m *BlockBodyPaged) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BlockBodyPaged.Unmarshal(m, b) @@ -903,7 +911,7 @@ func (m *BlockBodyParams) Reset() { *m = BlockBodyParams{} } func (m *BlockBodyParams) String() string { return proto.CompactTextString(m) } func (*BlockBodyParams) ProtoMessage() {} func (*BlockBodyParams) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{14} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{14} } func (m *BlockBodyParams) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BlockBodyParams.Unmarshal(m, b) @@ -948,7 +956,7 @@ func (m *BlockHeaderList) Reset() { *m = BlockHeaderList{} } func (m *BlockHeaderList) String() string { return proto.CompactTextString(m) } func (*BlockHeaderList) ProtoMessage() {} func (*BlockHeaderList) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{15} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{15} } func (m *BlockHeaderList) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BlockHeaderList.Unmarshal(m, b) @@ -988,7 +996,7 @@ func (m *BlockMetadata) Reset() { *m = BlockMetadata{} } func (m *BlockMetadata) String() string { return proto.CompactTextString(m) } func (*BlockMetadata) ProtoMessage() {} func (*BlockMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{16} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{16} } func (m *BlockMetadata) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BlockMetadata.Unmarshal(m, b) @@ -1040,7 +1048,7 @@ func (m *BlockMetadataList) Reset() { *m = BlockMetadataList{} } func (m *BlockMetadataList) String() string { return proto.CompactTextString(m) } func (*BlockMetadataList) ProtoMessage() {} func (*BlockMetadataList) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{17} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{17} } func (m *BlockMetadataList) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BlockMetadataList.Unmarshal(m, b) @@ -1080,7 +1088,7 @@ func (m *CommitResult) Reset() { *m = CommitResult{} } func (m *CommitResult) String() string { return proto.CompactTextString(m) } func (*CommitResult) ProtoMessage() {} func (*CommitResult) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{18} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{18} } func (m *CommitResult) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CommitResult.Unmarshal(m, b) @@ -1132,7 +1140,7 @@ func (m *CommitResultList) Reset() { *m = CommitResultList{} } func (m *CommitResultList) String() string { return proto.CompactTextString(m) } func (*CommitResultList) ProtoMessage() {} func (*CommitResultList) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{19} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{19} } func (m *CommitResultList) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CommitResultList.Unmarshal(m, b) @@ -1171,7 +1179,7 @@ func (m *VerifyResult) Reset() { *m = VerifyResult{} } func (m *VerifyResult) String() string { return proto.CompactTextString(m) } func (*VerifyResult) ProtoMessage() {} func (*VerifyResult) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{20} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{20} } func (m *VerifyResult) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VerifyResult.Unmarshal(m, b) @@ -1217,7 +1225,7 @@ func (m *Personal) Reset() { *m = Personal{} } func (m *Personal) String() string { return proto.CompactTextString(m) } func (*Personal) ProtoMessage() {} func (*Personal) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{21} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{21} } func (m *Personal) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Personal.Unmarshal(m, b) @@ -1264,7 +1272,7 @@ func (m *ImportFormat) Reset() { *m = ImportFormat{} } func (m *ImportFormat) String() string { return proto.CompactTextString(m) } func (*ImportFormat) ProtoMessage() {} func (*ImportFormat) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{22} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{22} } func (m *ImportFormat) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ImportFormat.Unmarshal(m, b) @@ -1317,7 +1325,7 @@ func (m *Staking) Reset() { *m = Staking{} } func (m *Staking) String() string { return proto.CompactTextString(m) } func (*Staking) ProtoMessage() {} func (*Staking) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{23} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{23} } func (m *Staking) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Staking.Unmarshal(m, b) @@ -1363,7 +1371,7 @@ func (m *Vote) Reset() { *m = Vote{} } func (m *Vote) String() string { return proto.CompactTextString(m) } func (*Vote) ProtoMessage() {} func (*Vote) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{24} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{24} } func (m *Vote) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Vote.Unmarshal(m, b) @@ -1409,7 +1417,7 @@ func (m *VoteParams) Reset() { *m = VoteParams{} } func (m *VoteParams) String() string { return proto.CompactTextString(m) } func (*VoteParams) ProtoMessage() {} func (*VoteParams) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{25} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{25} } func (m *VoteParams) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VoteParams.Unmarshal(m, b) @@ -1455,7 +1463,7 @@ func (m *AccountVoteInfo) Reset() { *m = AccountVoteInfo{} } func (m *AccountVoteInfo) String() string { return proto.CompactTextString(m) } func (*AccountVoteInfo) ProtoMessage() {} func (*AccountVoteInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{26} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{26} } func (m *AccountVoteInfo) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_AccountVoteInfo.Unmarshal(m, b) @@ -1501,7 +1509,7 @@ func (m *VoteInfo) Reset() { *m = VoteInfo{} } func (m *VoteInfo) String() string { return proto.CompactTextString(m) } func (*VoteInfo) ProtoMessage() {} func (*VoteInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{27} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{27} } func (m *VoteInfo) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VoteInfo.Unmarshal(m, b) @@ -1547,7 +1555,7 @@ func (m *VoteList) Reset() { *m = VoteList{} } func (m *VoteList) String() string { return proto.CompactTextString(m) } func (*VoteList) ProtoMessage() {} func (*VoteList) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{28} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{28} } func (m *VoteList) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VoteList.Unmarshal(m, b) @@ -1593,7 +1601,7 @@ func (m *NodeReq) Reset() { *m = NodeReq{} } func (m *NodeReq) String() string { return proto.CompactTextString(m) } func (*NodeReq) ProtoMessage() {} func (*NodeReq) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{29} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{29} } func (m *NodeReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_NodeReq.Unmarshal(m, b) @@ -1638,7 +1646,7 @@ func (m *Name) Reset() { *m = Name{} } func (m *Name) String() string { return proto.CompactTextString(m) } func (*Name) ProtoMessage() {} func (*Name) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{30} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{30} } func (m *Name) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Name.Unmarshal(m, b) @@ -1678,7 +1686,7 @@ func (m *NameInfo) Reset() { *m = NameInfo{} } func (m *NameInfo) String() string { return proto.CompactTextString(m) } func (*NameInfo) ProtoMessage() {} func (*NameInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{31} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{31} } func (m *NameInfo) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_NameInfo.Unmarshal(m, b) @@ -1731,7 +1739,7 @@ func (m *PeersParams) Reset() { *m = PeersParams{} } func (m *PeersParams) String() string { return proto.CompactTextString(m) } func (*PeersParams) ProtoMessage() {} func (*PeersParams) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{32} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{32} } func (m *PeersParams) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PeersParams.Unmarshal(m, b) @@ -1776,7 +1784,7 @@ func (m *KeyParams) Reset() { *m = KeyParams{} } func (m *KeyParams) String() string { return proto.CompactTextString(m) } func (*KeyParams) ProtoMessage() {} func (*KeyParams) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{33} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{33} } func (m *KeyParams) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_KeyParams.Unmarshal(m, b) @@ -1815,7 +1823,7 @@ func (m *ServerInfo) Reset() { *m = ServerInfo{} } func (m *ServerInfo) String() string { return proto.CompactTextString(m) } func (*ServerInfo) ProtoMessage() {} func (*ServerInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{34} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{34} } func (m *ServerInfo) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ServerInfo.Unmarshal(m, b) @@ -1860,7 +1868,7 @@ func (m *ConfigItem) Reset() { *m = ConfigItem{} } func (m *ConfigItem) String() string { return proto.CompactTextString(m) } func (*ConfigItem) ProtoMessage() {} func (*ConfigItem) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{35} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{35} } func (m *ConfigItem) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ConfigItem.Unmarshal(m, b) @@ -1898,7 +1906,7 @@ func (m *EventList) Reset() { *m = EventList{} } func (m *EventList) String() string { return proto.CompactTextString(m) } func (*EventList) ProtoMessage() {} func (*EventList) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{36} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{36} } func (m *EventList) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_EventList.Unmarshal(m, b) @@ -1939,7 +1947,7 @@ func (m *ConsensusInfo) Reset() { *m = ConsensusInfo{} } func (m *ConsensusInfo) String() string { return proto.CompactTextString(m) } func (*ConsensusInfo) ProtoMessage() {} func (*ConsensusInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_d4110ef4f672b82e, []int{37} + return fileDescriptor_rpc_0c5cc25d52d67e33, []int{37} } func (m *ConsensusInfo) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ConsensusInfo.Unmarshal(m, b) @@ -3477,154 +3485,155 @@ var _AergoRPCService_serviceDesc = grpc.ServiceDesc{ Metadata: "rpc.proto", } -func init() { proto.RegisterFile("rpc.proto", fileDescriptor_rpc_d4110ef4f672b82e) } - -var fileDescriptor_rpc_d4110ef4f672b82e = []byte{ - // 2325 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x58, 0xdd, 0x76, 0xdb, 0xc6, - 0xf1, 0x27, 0x29, 0x91, 0x22, 0x87, 0xa4, 0x04, 0x6d, 0x64, 0x5b, 0x7f, 0xfe, 0x1d, 0x47, 0xdd, - 0xa6, 0x8e, 0xe2, 0xda, 0x8a, 0x2d, 0xd7, 0xa9, 0x9b, 0xd3, 0x36, 0x85, 0x18, 0xca, 0xe2, 0x89, - 0x4c, 0xa9, 0x4b, 0xda, 0x55, 0x7a, 0x51, 0x16, 0x22, 0x96, 0x22, 0x8e, 0x08, 0x2c, 0x02, 0x2c, - 0xf5, 0x91, 0xdb, 0x3e, 0x40, 0x2f, 0xfa, 0x20, 0x7d, 0x96, 0xf6, 0x89, 0x7a, 0xf6, 0x0b, 0x1f, - 0x14, 0xdc, 0x73, 0xdc, 0x2b, 0x62, 0x66, 0xe7, 0x6b, 0x67, 0x66, 0x67, 0x7f, 0x4b, 0x68, 0x44, - 0xe1, 0x64, 0x2f, 0x8c, 0x18, 0x67, 0xa8, 0xca, 0x6f, 0x43, 0x1a, 0x77, 0xac, 0xf3, 0x39, 0x9b, - 0x5c, 0x4e, 0x66, 0x8e, 0x17, 0xa8, 0x85, 0x4e, 0xdb, 0x99, 0x4c, 0xd8, 0x22, 0xe0, 0x9a, 0x84, - 0x80, 0xb9, 0x54, 0x7f, 0x37, 0xc2, 0xfd, 0x50, 0x7f, 0xb6, 0x7c, 0xca, 0x23, 0x4f, 0x1b, 0xc3, - 0xff, 0x2c, 0x83, 0x75, 0x90, 0x18, 0x1a, 0x72, 0x87, 0x2f, 0x62, 0xf4, 0x18, 0x36, 0xce, 0x69, - 0xcc, 0xc7, 0xd2, 0xc3, 0x78, 0xe6, 0xc4, 0xb3, 0xed, 0xf2, 0x4e, 0x79, 0xb7, 0x45, 0xda, 0x82, - 0x2d, 0xc5, 0x8f, 0x9c, 0x78, 0x86, 0x3e, 0x83, 0xa6, 0x94, 0x9b, 0x51, 0xef, 0x62, 0xc6, 0xb7, - 0x2b, 0x3b, 0xe5, 0xdd, 0x55, 0x02, 0x82, 0x75, 0x24, 0x39, 0xe8, 0x17, 0xb0, 0x3e, 0x61, 0x41, - 0x4c, 0x83, 0x78, 0x11, 0x8f, 0xbd, 0x60, 0xca, 0xb6, 0x57, 0x76, 0xca, 0xbb, 0x0d, 0xd2, 0x4e, - 0xb8, 0xfd, 0x60, 0xca, 0xd0, 0x2f, 0x01, 0x49, 0x3b, 0x32, 0x86, 0xb1, 0xe7, 0x2a, 0x97, 0xab, - 0xd2, 0xa5, 0x8c, 0xa4, 0x2b, 0x16, 0xfa, 0xae, 0x70, 0x8a, 0x19, 0xac, 0x69, 0x12, 0x6d, 0x41, - 0xd5, 0x77, 0x2e, 0xbc, 0x89, 0x8c, 0xae, 0x41, 0x14, 0x81, 0xee, 0x43, 0x2d, 0x5c, 0x9c, 0xcf, - 0xbd, 0x89, 0x0c, 0xa8, 0x4e, 0x34, 0x85, 0xb6, 0x61, 0xcd, 0x77, 0xbc, 0x20, 0xa0, 0x5c, 0x46, - 0x51, 0x27, 0x86, 0x44, 0x0f, 0xa1, 0x91, 0x04, 0x24, 0xdd, 0x36, 0x48, 0xca, 0xc0, 0x7f, 0xaf, - 0x40, 0x43, 0x79, 0x14, 0xb1, 0x3e, 0x82, 0x8a, 0xe7, 0x4a, 0x87, 0xcd, 0xfd, 0xf5, 0x3d, 0x59, - 0x8a, 0x3d, 0x1d, 0x0f, 0xa9, 0x78, 0x2e, 0xea, 0x40, 0xfd, 0x3c, 0x1c, 0x2c, 0xfc, 0x73, 0x1a, - 0x49, 0xff, 0x6d, 0x92, 0xd0, 0x08, 0x43, 0xcb, 0x77, 0x6e, 0x64, 0x56, 0x63, 0xef, 0x27, 0x2a, - 0xc3, 0x58, 0x25, 0x39, 0x9e, 0x88, 0xc5, 0x77, 0x6e, 0x38, 0xbb, 0xa4, 0x41, 0xac, 0x53, 0x90, - 0x32, 0xd0, 0x63, 0x58, 0x8f, 0xb9, 0x73, 0xe9, 0x05, 0x17, 0xbe, 0x17, 0x78, 0xfe, 0xc2, 0xdf, - 0xae, 0x4a, 0x91, 0x25, 0xae, 0xf0, 0xc4, 0x19, 0x77, 0xe6, 0x9a, 0xbd, 0x5d, 0x93, 0x52, 0x39, - 0x9e, 0x88, 0xf4, 0xc2, 0x89, 0xc3, 0xc8, 0x9b, 0xd0, 0xed, 0x35, 0xb9, 0x9e, 0xd0, 0x22, 0x8a, - 0xc0, 0xf1, 0xa9, 0x5a, 0xac, 0xab, 0x28, 0x12, 0x06, 0x9e, 0x40, 0xb5, 0x1f, 0x84, 0x0b, 0x8e, - 0x10, 0xac, 0x66, 0xba, 0x43, 0x7e, 0x8b, 0x34, 0x3b, 0xae, 0x1b, 0xd1, 0x38, 0xde, 0xae, 0xec, - 0xac, 0xec, 0xb6, 0x88, 0x21, 0x45, 0xb9, 0xae, 0x9c, 0xf9, 0x42, 0xed, 0xbb, 0x45, 0x14, 0x21, - 0xca, 0x15, 0x4f, 0x22, 0x2f, 0xe4, 0x7a, 0xb7, 0x9a, 0xc2, 0x53, 0xa8, 0x9d, 0x2c, 0xb8, 0xf0, - 0xb2, 0x05, 0x55, 0x2f, 0x70, 0xe9, 0x8d, 0x74, 0xd3, 0x26, 0x8a, 0xc8, 0xfb, 0x29, 0xff, 0xef, - 0x7e, 0xd6, 0xa0, 0xda, 0xf3, 0x43, 0x7e, 0x8b, 0x7f, 0x0e, 0xcd, 0xa1, 0x17, 0x5c, 0xcc, 0xe9, - 0xc1, 0x2d, 0xa7, 0x19, 0x2b, 0xe5, 0x8c, 0x15, 0xfc, 0x18, 0xd6, 0x6d, 0x75, 0xca, 0xec, 0x65, - 0x6f, 0x39, 0xb9, 0xbf, 0xa4, 0x72, 0x81, 0x4b, 0x18, 0xe3, 0x22, 0x5e, 0xcd, 0xd1, 0x92, 0x86, - 0x14, 0x59, 0x14, 0x12, 0x7a, 0x1b, 0xf2, 0x1b, 0x3d, 0x02, 0xe8, 0x32, 0x3f, 0x14, 0x1e, 0xa8, - 0xab, 0xfb, 0x35, 0xc3, 0xc1, 0xff, 0x2a, 0xc3, 0xea, 0x29, 0xa5, 0x11, 0x7a, 0x9a, 0xa6, 0x41, - 0x35, 0x25, 0xd2, 0x4d, 0x29, 0x56, 0x75, 0x8c, 0x69, 0x6a, 0x5e, 0x42, 0x43, 0x9c, 0x27, 0xd9, - 0x6e, 0xd2, 0x5f, 0x73, 0xff, 0x9e, 0x96, 0x1f, 0xd0, 0x6b, 0x79, 0xb2, 0x07, 0x8c, 0x7b, 0x13, - 0x4a, 0x52, 0x39, 0xb1, 0xc3, 0x98, 0x3b, 0x5c, 0xe5, 0xb3, 0x4a, 0x14, 0x21, 0xf2, 0x39, 0xf3, - 0x5c, 0x97, 0x06, 0x32, 0x9f, 0x75, 0xa2, 0x29, 0xd1, 0x3a, 0x73, 0x27, 0x9e, 0x75, 0x67, 0x74, - 0x72, 0x29, 0xbb, 0x73, 0x85, 0xa4, 0x0c, 0xd1, 0x74, 0x31, 0x9d, 0x4f, 0x43, 0x4a, 0x23, 0xd9, - 0x94, 0x75, 0x92, 0xd0, 0xf8, 0x19, 0xd4, 0x45, 0xd0, 0xc7, 0x5e, 0xcc, 0xd1, 0xcf, 0xa0, 0x2a, - 0x78, 0x62, 0x53, 0x2b, 0xbb, 0xcd, 0xfd, 0x66, 0x66, 0x53, 0x44, 0xad, 0xe0, 0x2b, 0x00, 0x21, - 0x7a, 0xea, 0x44, 0x8e, 0x1f, 0x17, 0xb6, 0xa2, 0x08, 0x31, 0x3b, 0x9a, 0x34, 0x25, 0x64, 0x93, - 0xf3, 0xd7, 0x26, 0xf2, 0x5b, 0xc8, 0xb2, 0xe9, 0x34, 0xa6, 0xaa, 0x3d, 0xda, 0x44, 0x53, 0xc8, - 0x82, 0x15, 0x27, 0x9e, 0xc8, 0x8d, 0xd4, 0x89, 0xf8, 0xc4, 0xaf, 0x01, 0x4e, 0x9d, 0x0b, 0xaa, - 0xfd, 0xa6, 0x7a, 0xe5, 0x9c, 0x9e, 0xf1, 0x51, 0x49, 0x7d, 0xe0, 0x1b, 0x58, 0x97, 0x29, 0x3e, - 0x60, 0xee, 0xad, 0x30, 0x21, 0x27, 0x98, 0x3c, 0x93, 0xa6, 0xb5, 0x25, 0x91, 0xb1, 0x59, 0x29, - 0xb4, 0x99, 0x8d, 0xfb, 0x73, 0x58, 0x3d, 0x67, 0xee, 0xad, 0x8c, 0xba, 0xb9, 0x6f, 0xe9, 0x3c, - 0x25, 0x6e, 0x88, 0x5c, 0xc5, 0x7f, 0x85, 0x8d, 0x8c, 0x67, 0x19, 0x38, 0x86, 0x96, 0x48, 0x12, - 0x8b, 0x02, 0x35, 0xac, 0x54, 0xe2, 0x72, 0x3c, 0xf4, 0x25, 0xd4, 0x42, 0xe7, 0x42, 0x0c, 0x10, - 0xd5, 0x2b, 0x9b, 0xa6, 0x0c, 0xc9, 0xfe, 0x89, 0x16, 0xc0, 0xbf, 0xd6, 0x1e, 0x8e, 0xa8, 0xe3, - 0xea, 0x1a, 0x7e, 0x0e, 0x35, 0x35, 0xd7, 0x74, 0x11, 0x5b, 0xd9, 0xe0, 0x88, 0x5e, 0xc3, 0x1e, - 0xb4, 0x25, 0xe3, 0x2d, 0xe5, 0x8e, 0xeb, 0x70, 0xa7, 0xb0, 0x92, 0x4f, 0x44, 0x25, 0x85, 0x61, - 0x1d, 0x08, 0xca, 0x9a, 0x52, 0x2e, 0x89, 0x96, 0x10, 0x07, 0x8d, 0xdf, 0xa8, 0x83, 0xa6, 0x1a, - 0xd6, 0x90, 0xd8, 0x86, 0xcd, 0x9c, 0x2b, 0x19, 0xe5, 0xd3, 0xa5, 0x28, 0xb7, 0xb2, 0xa6, 0x8d, - 0x64, 0x12, 0x2d, 0x85, 0x56, 0x97, 0xf9, 0xbe, 0xc7, 0x09, 0x8d, 0x17, 0xf3, 0xe2, 0x09, 0xf8, - 0x25, 0x54, 0x69, 0x14, 0x31, 0x15, 0xeb, 0xfa, 0xfe, 0x27, 0xe6, 0x96, 0x90, 0x7a, 0xea, 0x8a, - 0x25, 0x4a, 0x42, 0x54, 0xda, 0xa5, 0xdc, 0xf1, 0xe6, 0xfa, 0x62, 0xd4, 0x14, 0xb6, 0xc1, 0xca, - 0xba, 0x91, 0x81, 0x3e, 0x83, 0xb5, 0x48, 0x52, 0x26, 0xd2, 0xbc, 0x61, 0x25, 0x49, 0x8c, 0x0c, - 0x1e, 0x41, 0xeb, 0x3d, 0x8d, 0xbc, 0xe9, 0xad, 0x8e, 0xf4, 0xff, 0xa0, 0xc2, 0x6f, 0xf4, 0x8c, - 0x68, 0x68, 0xcd, 0xd1, 0x0d, 0xa9, 0xf0, 0x9b, 0x0f, 0x05, 0xac, 0xd4, 0x73, 0x01, 0xe3, 0x91, - 0x38, 0xa3, 0x51, 0xcc, 0x02, 0x67, 0x2e, 0x66, 0x54, 0xe8, 0xc4, 0x71, 0x38, 0x8b, 0x9c, 0x98, - 0xea, 0x3b, 0x38, 0xc3, 0x41, 0xbb, 0xb0, 0xa6, 0x11, 0x89, 0xae, 0x9a, 0xb9, 0x2f, 0xf5, 0xe0, - 0x23, 0x66, 0x19, 0xcf, 0xa0, 0xd5, 0xf7, 0x43, 0x16, 0xf1, 0x43, 0x16, 0xf9, 0x8e, 0xe8, 0x9c, - 0x95, 0x6b, 0x6f, 0xba, 0x34, 0xd0, 0x32, 0xc3, 0x99, 0x88, 0x65, 0x51, 0x68, 0x36, 0x77, 0x85, - 0x43, 0x69, 0xbf, 0x41, 0x0c, 0x29, 0x56, 0x02, 0x7a, 0x2d, 0x57, 0x54, 0x5e, 0x0d, 0x89, 0x5f, - 0xc1, 0xda, 0x50, 0xdf, 0x7f, 0xf7, 0xa1, 0xe6, 0xf8, 0x99, 0x79, 0xac, 0x29, 0x51, 0xd2, 0xeb, - 0x19, 0x0d, 0xf4, 0xcc, 0x90, 0xdf, 0xf8, 0xb7, 0xb0, 0xfa, 0x9e, 0x71, 0x79, 0x2f, 0x4e, 0x9c, - 0xc0, 0xf5, 0x5c, 0x31, 0x0e, 0x95, 0x5a, 0xca, 0xc8, 0x58, 0xac, 0x64, 0x2d, 0xe2, 0x7d, 0x00, - 0xa1, 0xad, 0x0f, 0xde, 0x7a, 0x82, 0x20, 0x1a, 0x12, 0x31, 0x6c, 0x41, 0x35, 0x4d, 0x52, 0x9b, - 0x28, 0x02, 0xbb, 0xb0, 0xa1, 0xd3, 0x24, 0x54, 0x25, 0xf4, 0xd8, 0x85, 0x35, 0x73, 0x9f, 0xe7, - 0xf1, 0x87, 0xde, 0x11, 0x31, 0xcb, 0xe8, 0x0b, 0xa8, 0x5d, 0x31, 0xae, 0xce, 0xad, 0xe8, 0x94, - 0x0d, 0x53, 0x51, 0x6d, 0x8a, 0xe8, 0x65, 0xfc, 0x0d, 0xd4, 0x13, 0xf3, 0x2a, 0xae, 0x4a, 0x12, - 0xd7, 0x23, 0x80, 0x64, 0x6b, 0x22, 0x8f, 0x2b, 0xa2, 0xbc, 0x29, 0x07, 0xff, 0x4e, 0xe9, 0x9a, - 0x71, 0x7d, 0xc5, 0x84, 0x58, 0x7e, 0x5c, 0x8b, 0x75, 0xa2, 0x56, 0x96, 0xcd, 0x63, 0x1b, 0xd6, - 0x06, 0xcc, 0xa5, 0x84, 0xfe, 0x28, 0x4f, 0xac, 0xe7, 0x53, 0xb6, 0x48, 0xae, 0x46, 0x4d, 0x2a, - 0x64, 0xe6, 0x87, 0x2c, 0xa0, 0x49, 0x52, 0x53, 0x06, 0xee, 0xc0, 0xea, 0xc0, 0xf1, 0xa9, 0xa8, - 0x98, 0x00, 0x27, 0x3a, 0xa7, 0xf2, 0x1b, 0x4f, 0xa0, 0x2e, 0xd6, 0xe4, 0xce, 0x3e, 0xcb, 0xac, - 0xa7, 0xc1, 0x89, 0x65, 0x25, 0x2c, 0x4a, 0xc0, 0xae, 0x03, 0x3d, 0x5d, 0x5a, 0x44, 0x11, 0x68, - 0x07, 0x9a, 0x2e, 0x8d, 0xb9, 0x17, 0x38, 0xdc, 0x63, 0x81, 0x46, 0x13, 0x59, 0x16, 0xee, 0x41, - 0x53, 0xdc, 0x48, 0xb1, 0xae, 0x6c, 0x07, 0xea, 0x01, 0x3b, 0x52, 0x97, 0x62, 0x59, 0x5d, 0x6e, - 0x86, 0x96, 0x17, 0xdf, 0x8c, 0x5d, 0x0f, 0xe9, 0x7c, 0xaa, 0x71, 0x69, 0x42, 0xe3, 0x4f, 0xa1, - 0xf1, 0x3d, 0x35, 0x73, 0xd9, 0x82, 0x95, 0x4b, 0x7a, 0x2b, 0x13, 0xd9, 0x20, 0xe2, 0x13, 0xff, - 0xad, 0x02, 0x30, 0xa4, 0xd1, 0x15, 0x8d, 0xe4, 0x6e, 0x5e, 0x41, 0x2d, 0x96, 0x67, 0x52, 0x27, - 0xfb, 0x53, 0xd3, 0x05, 0x89, 0xc8, 0x9e, 0x3a, 0xb3, 0xbd, 0x80, 0x47, 0xb7, 0x44, 0x0b, 0x0b, - 0xb5, 0x09, 0x0b, 0xa6, 0x9e, 0xe9, 0x89, 0x02, 0xb5, 0xae, 0x5c, 0xd7, 0x6a, 0x4a, 0xb8, 0xf3, - 0x1b, 0x68, 0x66, 0xac, 0xa5, 0xd1, 0x95, 0x75, 0x74, 0x29, 0xfe, 0x51, 0xa5, 0x55, 0xc4, 0x37, - 0x95, 0xd7, 0xe5, 0xce, 0x31, 0x34, 0x33, 0x16, 0x0b, 0x54, 0xbf, 0xc8, 0xaa, 0xa6, 0xb7, 0x8b, - 0x52, 0xea, 0x73, 0xea, 0x67, 0xac, 0xe1, 0x9f, 0x04, 0x22, 0x32, 0x0b, 0x68, 0x1f, 0xaa, 0x61, - 0xc4, 0xc2, 0x58, 0x6f, 0xe6, 0xe1, 0x1d, 0xd5, 0xbd, 0x53, 0xb1, 0xac, 0xf6, 0xa2, 0x44, 0x3b, - 0xe2, 0xe2, 0x4e, 0x98, 0x1f, 0xb3, 0x13, 0xfc, 0x02, 0x1a, 0xbd, 0x2b, 0x1a, 0x70, 0x73, 0xad, - 0x51, 0x41, 0x2c, 0x5f, 0x6b, 0x52, 0x82, 0xe8, 0x35, 0xdc, 0x87, 0x76, 0x37, 0xf7, 0xc8, 0x41, - 0xb0, 0x2a, 0xe4, 0x4c, 0x93, 0x8a, 0x6f, 0xc1, 0x93, 0xaf, 0x22, 0xe5, 0x50, 0x7e, 0x8b, 0xb8, - 0xce, 0x43, 0x73, 0xde, 0xc4, 0xe7, 0x93, 0x7f, 0x97, 0xcd, 0xa5, 0xa3, 0xdf, 0x67, 0x0d, 0xa8, - 0x8e, 0xce, 0xc6, 0x27, 0xdf, 0x5b, 0x25, 0xb4, 0x05, 0xd6, 0xe8, 0x6c, 0x3c, 0x38, 0x19, 0x74, - 0x7b, 0xe3, 0xd1, 0xc9, 0xc9, 0xf8, 0xf8, 0xe4, 0x4f, 0x56, 0x19, 0xdd, 0x83, 0xcd, 0xd1, 0xd9, - 0xd8, 0x3e, 0x26, 0x3d, 0xfb, 0xbb, 0x1f, 0xc6, 0xbd, 0xb3, 0xfe, 0x70, 0x34, 0xb4, 0x2a, 0xe8, - 0x13, 0xd8, 0x18, 0x9d, 0x8d, 0xfb, 0x83, 0xf7, 0xf6, 0x71, 0xff, 0xbb, 0xf1, 0x91, 0x3d, 0x3c, - 0xb2, 0x56, 0x96, 0x98, 0xc3, 0xfe, 0x9b, 0x81, 0xb5, 0xaa, 0x0d, 0x18, 0xe6, 0xe1, 0x09, 0x79, - 0x6b, 0x8f, 0xac, 0x2a, 0xfa, 0x7f, 0x78, 0x20, 0xd9, 0xc3, 0x77, 0x87, 0x87, 0xfd, 0x6e, 0xbf, - 0x37, 0x18, 0x8d, 0x0f, 0xec, 0x63, 0x7b, 0xd0, 0xed, 0x59, 0x35, 0xad, 0x73, 0x64, 0x0f, 0xc7, - 0x43, 0xfb, 0x6d, 0x4f, 0xc5, 0x64, 0xad, 0x25, 0xa6, 0x46, 0x3d, 0x32, 0xb0, 0x8f, 0xc7, 0x3d, - 0x42, 0x4e, 0x88, 0xd5, 0x78, 0x32, 0x35, 0xd7, 0x93, 0xde, 0xd3, 0x16, 0x58, 0xef, 0x7b, 0xa4, - 0x7f, 0xf8, 0xc3, 0x78, 0x38, 0xb2, 0x47, 0xef, 0x86, 0x6a, 0x7b, 0x3b, 0xf0, 0x30, 0xcf, 0x15, - 0xf1, 0x8d, 0x07, 0x27, 0xa3, 0xf1, 0x5b, 0x7b, 0xd4, 0x3d, 0xb2, 0xca, 0xe8, 0x11, 0x74, 0xf2, - 0x12, 0xb9, 0xed, 0x55, 0xf6, 0xff, 0x61, 0xc1, 0x86, 0x4d, 0xa3, 0x0b, 0x46, 0x4e, 0xbb, 0xa2, - 0xd5, 0xc5, 0xeb, 0xe6, 0x05, 0x34, 0xc4, 0xe8, 0x19, 0x4a, 0x1c, 0x6b, 0x86, 0xa8, 0x1e, 0x46, - 0x9d, 0x82, 0xeb, 0x06, 0x97, 0xd0, 0x0b, 0xa8, 0xbd, 0x95, 0xef, 0x66, 0x64, 0xf0, 0xb2, 0x22, - 0x63, 0x42, 0x7f, 0x5c, 0xd0, 0x98, 0x77, 0xd6, 0xf3, 0x6c, 0x5c, 0x42, 0xaf, 0x00, 0xd2, 0x97, - 0x35, 0x4a, 0xba, 0x44, 0xbc, 0x35, 0x3a, 0x0f, 0xb2, 0x20, 0x23, 0xf3, 0xf4, 0xc6, 0x25, 0xf4, - 0x1c, 0x5a, 0x6f, 0x28, 0x4f, 0x1f, 0x9c, 0x79, 0x45, 0x2b, 0xf7, 0xe4, 0x0c, 0xa6, 0x0c, 0x97, - 0xd0, 0xb7, 0x60, 0x89, 0xc6, 0xcc, 0x60, 0xa1, 0x18, 0x99, 0xb3, 0x94, 0x22, 0xe4, 0xce, 0xfd, - 0xbb, 0x98, 0x49, 0xac, 0xe2, 0x12, 0x3a, 0x80, 0xcd, 0xc4, 0x40, 0x02, 0xc3, 0x0a, 0x2c, 0x6c, - 0x17, 0x41, 0x23, 0x6d, 0xe3, 0x05, 0x6c, 0x24, 0x36, 0x86, 0x3c, 0xa2, 0x8e, 0xbf, 0x14, 0x79, - 0x0e, 0xfd, 0xe1, 0xd2, 0xf3, 0x32, 0xb2, 0xe1, 0xc1, 0x1d, 0xb7, 0x85, 0xaa, 0x85, 0x90, 0x4c, - 0x9a, 0xd8, 0x83, 0xfa, 0x1b, 0xaa, 0x2c, 0xa0, 0x82, 0xc2, 0x2d, 0x3b, 0x45, 0xbf, 0x07, 0xcb, - 0xc8, 0xa7, 0x78, 0xb3, 0x40, 0xef, 0x03, 0x1e, 0xd1, 0xb7, 0xb2, 0x38, 0x09, 0x94, 0x46, 0xf7, - 0x97, 0xf1, 0xb6, 0xce, 0xd4, 0xbd, 0xbb, 0xfc, 0x0b, 0xea, 0xe2, 0x12, 0xda, 0x85, 0xea, 0x1b, - 0xca, 0x47, 0x67, 0x85, 0x5e, 0x53, 0x58, 0x86, 0x4b, 0xe8, 0x57, 0x00, 0xc6, 0xd5, 0x07, 0xc4, - 0xad, 0x44, 0xbc, 0x1f, 0x98, 0x0d, 0xee, 0x4b, 0x2d, 0x42, 0x27, 0xd4, 0x0b, 0x79, 0xa1, 0x96, - 0x69, 0x54, 0x2d, 0x83, 0x4b, 0x02, 0x5c, 0xbf, 0xa1, 0xdc, 0x3e, 0xe8, 0x17, 0xca, 0x83, 0x01, - 0x6d, 0x07, 0x7d, 0x25, 0x3b, 0xa4, 0x81, 0x3b, 0x3a, 0x43, 0x69, 0xb0, 0x9d, 0x22, 0x20, 0x8a, - 0xc5, 0xe1, 0xad, 0x0d, 0xbd, 0x8b, 0x20, 0x2f, 0x9b, 0xdb, 0xe3, 0x53, 0xa8, 0xab, 0x21, 0x50, - 0x6c, 0x2f, 0x8b, 0x5f, 0x65, 0x46, 0xea, 0xca, 0xc3, 0xe8, 0x0c, 0xb5, 0x13, 0x69, 0xd1, 0x42, - 0xc9, 0x79, 0x5a, 0x06, 0xcd, 0xb8, 0xa4, 0x5b, 0x44, 0x9d, 0xf5, 0xff, 0xd6, 0x22, 0x52, 0x02, - 0x97, 0xd0, 0x1f, 0x64, 0x8b, 0x48, 0xca, 0x0e, 0xdc, 0xd3, 0x88, 0xb1, 0x69, 0x72, 0xe6, 0xf3, - 0x4f, 0xfa, 0x24, 0x4e, 0xcd, 0x96, 0xb2, 0xb2, 0x06, 0xed, 0x6e, 0x44, 0x85, 0xbe, 0x7e, 0xe0, - 0x6f, 0x24, 0xaf, 0x57, 0x85, 0x9c, 0x3b, 0x4b, 0x40, 0x58, 0x1e, 0x9f, 0xa6, 0xa8, 0x81, 0xa2, - 0xe3, 0xa5, 0xfe, 0x47, 0x79, 0x71, 0xbd, 0xb1, 0xe7, 0xd0, 0x3c, 0x66, 0x93, 0xcb, 0x8f, 0x70, - 0xb2, 0x0f, 0xed, 0x77, 0xc1, 0xfc, 0xe3, 0x74, 0xbe, 0x86, 0xb6, 0x82, 0xe6, 0x46, 0xc7, 0x6c, - 0x3a, 0x0b, 0xd8, 0x8b, 0xf5, 0x7a, 0x37, 0x59, 0xbd, 0x3b, 0xbe, 0x8a, 0x07, 0xed, 0x4b, 0x68, - 0xff, 0x71, 0x41, 0xa3, 0xdb, 0x2e, 0x0b, 0x78, 0xe4, 0x4c, 0x78, 0x92, 0x0a, 0xc9, 0xfd, 0x80, - 0x92, 0x0d, 0x28, 0xa7, 0xa4, 0xaa, 0xbd, 0x99, 0xad, 0xac, 0x52, 0xbf, 0x7f, 0x87, 0x65, 0x8a, - 0xf6, 0x42, 0xb6, 0x89, 0x44, 0x73, 0x28, 0xfb, 0x17, 0x8a, 0xc6, 0x76, 0x9d, 0x8d, 0x0c, 0x2f, - 0x29, 0x80, 0x50, 0x79, 0x2f, 0xd1, 0xed, 0x66, 0x06, 0xf1, 0x2e, 0x69, 0x18, 0x90, 0x2c, 0x07, - 0xed, 0x46, 0x5a, 0x65, 0xa5, 0xb8, 0xdc, 0x5a, 0xea, 0x8f, 0x9a, 0x24, 0xd0, 0xa5, 0x37, 0x80, - 0xba, 0x56, 0x54, 0x7f, 0x4a, 0xa4, 0xff, 0x01, 0xf5, 0xa5, 0x97, 0x01, 0x2e, 0xa1, 0x67, 0xb2, - 0xc1, 0x12, 0x48, 0x9c, 0x05, 0xc1, 0x49, 0xa4, 0x66, 0x55, 0x96, 0x4f, 0x8e, 0x73, 0x89, 0x69, - 0xf4, 0x4c, 0x36, 0x5b, 0x3c, 0xf4, 0xe6, 0x5c, 0x01, 0xc6, 0x4e, 0x0e, 0xfa, 0xc8, 0x81, 0xfc, - 0x52, 0xfd, 0x29, 0x23, 0x19, 0x71, 0x91, 0x8a, 0x95, 0x55, 0xd1, 0x69, 0xf9, 0x1a, 0xda, 0x62, - 0x4b, 0x29, 0xc4, 0x35, 0x42, 0x09, 0x2a, 0xee, 0x6c, 0xde, 0x41, 0xab, 0xb8, 0x84, 0x5e, 0xcb, - 0xa3, 0x9a, 0x87, 0x59, 0xc5, 0x37, 0x47, 0x4e, 0x06, 0x97, 0x0e, 0x76, 0xfe, 0xfc, 0xe8, 0xc2, - 0xe3, 0xb3, 0xc5, 0xf9, 0xde, 0x84, 0xf9, 0x5f, 0x39, 0x02, 0x1f, 0x78, 0x4c, 0xfd, 0x7e, 0x25, - 0x35, 0xce, 0x6b, 0xf2, 0xff, 0xf1, 0x97, 0xff, 0x09, 0x00, 0x00, 0xff, 0xff, 0x4e, 0x7c, 0xba, - 0xc9, 0x79, 0x17, 0x00, 0x00, +func init() { proto.RegisterFile("rpc.proto", fileDescriptor_rpc_0c5cc25d52d67e33) } + +var fileDescriptor_rpc_0c5cc25d52d67e33 = []byte{ + // 2342 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x58, 0x6d, 0x73, 0x1b, 0xb7, + 0xf1, 0x27, 0x29, 0x91, 0x22, 0x97, 0xa4, 0x74, 0x42, 0x14, 0x5b, 0x7f, 0xfe, 0x6d, 0x47, 0x45, + 0x53, 0x47, 0x71, 0x6d, 0xc5, 0x96, 0xeb, 0xd4, 0xcd, 0xb4, 0x4d, 0x29, 0x86, 0xb2, 0x38, 0x91, + 0x29, 0x15, 0xa4, 0x5d, 0xa5, 0x2f, 0xca, 0x9e, 0x78, 0xa0, 0x78, 0x23, 0xde, 0x1d, 0x73, 0x07, + 0xea, 0x21, 0x6f, 0xfb, 0x01, 0xfa, 0xa2, 0xdf, 0xab, 0x33, 0xed, 0x27, 0xea, 0x60, 0x01, 0xdc, + 0x03, 0x75, 0xee, 0x8c, 0xfb, 0x8a, 0xb7, 0x8b, 0x7d, 0xc2, 0xee, 0x62, 0xf1, 0x03, 0xa1, 0x16, + 0xce, 0xc7, 0x7b, 0xf3, 0x30, 0x10, 0x01, 0x29, 0x8b, 0xdb, 0x39, 0x8f, 0x5a, 0xd6, 0xf9, 0x2c, + 0x18, 0x5f, 0x8e, 0xa7, 0xb6, 0xeb, 0xab, 0x85, 0x56, 0xd3, 0x1e, 0x8f, 0x83, 0x85, 0x2f, 0x34, + 0x09, 0x7e, 0xe0, 0x70, 0xfd, 0x5d, 0x9b, 0xef, 0xcf, 0xf5, 0x67, 0xc3, 0xe3, 0x22, 0x74, 0xb5, + 0x31, 0xfa, 0xcf, 0x22, 0x58, 0x07, 0xb1, 0xa1, 0x81, 0xb0, 0xc5, 0x22, 0x22, 0x8f, 0x61, 0xe3, + 0x9c, 0x47, 0x62, 0x84, 0x1e, 0x46, 0x53, 0x3b, 0x9a, 0x6e, 0x17, 0x77, 0x8a, 0xbb, 0x0d, 0xd6, + 0x94, 0x6c, 0x14, 0x3f, 0xb2, 0xa3, 0x29, 0xf9, 0x0c, 0xea, 0x28, 0x37, 0xe5, 0xee, 0xc5, 0x54, + 0x6c, 0x97, 0x76, 0x8a, 0xbb, 0xab, 0x0c, 0x24, 0xeb, 0x08, 0x39, 0xe4, 0x17, 0xb0, 0x3e, 0x0e, + 0xfc, 0x88, 0xfb, 0xd1, 0x22, 0x1a, 0xb9, 0xfe, 0x24, 0xd8, 0x5e, 0xd9, 0x29, 0xee, 0xd6, 0x58, + 0x33, 0xe6, 0xf6, 0xfc, 0x49, 0x40, 0x7e, 0x09, 0x04, 0xed, 0x60, 0x0c, 0x23, 0xd7, 0x51, 0x2e, + 0x57, 0xd1, 0x25, 0x46, 0xd2, 0x91, 0x0b, 0x3d, 0x07, 0x9d, 0x3e, 0x04, 0x50, 0x72, 0x91, 0xb0, + 0xc5, 0x76, 0x19, 0xed, 0xd5, 0xe2, 0xe8, 0x69, 0x00, 0x6b, 0x5a, 0x9a, 0x6c, 0x41, 0xd9, 0xb3, + 0x2f, 0xdc, 0x31, 0x06, 0x5f, 0x63, 0x8a, 0x20, 0xf7, 0xa0, 0x32, 0x5f, 0x9c, 0xcf, 0xdc, 0x31, + 0xc6, 0x5b, 0x65, 0x9a, 0x22, 0xdb, 0xb0, 0xe6, 0xd9, 0xae, 0xef, 0x73, 0x81, 0x41, 0x56, 0x99, + 0x21, 0xc9, 0x03, 0xa8, 0xc5, 0xf1, 0x62, 0x54, 0xd2, 0xa1, 0x61, 0xd0, 0xbf, 0x97, 0xa0, 0xa6, + 0x3c, 0xca, 0xad, 0x3c, 0x82, 0x92, 0xeb, 0xa0, 0xc3, 0xfa, 0xfe, 0xfa, 0x1e, 0x56, 0x6a, 0x4f, + 0xc7, 0xc3, 0x4a, 0xae, 0x43, 0x5a, 0x50, 0x3d, 0x9f, 0xf7, 0x17, 0xde, 0x39, 0x0f, 0xd1, 0x7f, + 0x93, 0xc5, 0x34, 0xa1, 0xd0, 0xf0, 0xec, 0x1b, 0x4c, 0x7a, 0xe4, 0xfe, 0xc4, 0x31, 0x8c, 0x55, + 0x96, 0xe1, 0xc9, 0x58, 0x3c, 0xfb, 0x46, 0x04, 0x97, 0xdc, 0x8f, 0x74, 0x86, 0x12, 0x06, 0x79, + 0x0c, 0xeb, 0x91, 0xb0, 0x2f, 0x5d, 0xff, 0xc2, 0x73, 0x7d, 0xd7, 0x5b, 0x78, 0x98, 0x9f, 0x06, + 0x5b, 0xe2, 0x4a, 0x4f, 0x22, 0x10, 0xf6, 0x4c, 0xb3, 0xb7, 0x2b, 0x28, 0x95, 0xe1, 0xc9, 0x48, + 0x2f, 0xec, 0x68, 0x1e, 0xba, 0x63, 0xbe, 0xbd, 0x86, 0xeb, 0x31, 0x2d, 0xa3, 0xf0, 0x6d, 0x8f, + 0xab, 0xc5, 0xaa, 0x8a, 0x22, 0x66, 0xd0, 0x31, 0x94, 0x7b, 0xfe, 0x7c, 0x21, 0x08, 0x81, 0xd5, + 0x54, 0xf3, 0xe0, 0xb7, 0x4c, 0xb3, 0xed, 0x38, 0x21, 0x8f, 0xa2, 0xed, 0xd2, 0xce, 0xca, 0x6e, + 0x83, 0x19, 0x52, 0x96, 0xeb, 0xca, 0x9e, 0x2d, 0xd4, 0xbe, 0x1b, 0x4c, 0x11, 0xb2, 0x5c, 0xd1, + 0x38, 0x74, 0xe7, 0x42, 0xef, 0x56, 0x53, 0x74, 0x02, 0x95, 0x93, 0x85, 0x90, 0x5e, 0xb6, 0xa0, + 0xec, 0xfa, 0x0e, 0xbf, 0x41, 0x37, 0x4d, 0xa6, 0x88, 0xac, 0x9f, 0xe2, 0xff, 0xee, 0x67, 0x0d, + 0xca, 0x5d, 0x6f, 0x2e, 0x6e, 0xe9, 0xcf, 0xa1, 0x3e, 0x70, 0xfd, 0x8b, 0x19, 0x3f, 0xb8, 0x15, + 0x3c, 0x65, 0xa5, 0x98, 0xb2, 0x42, 0x1f, 0xc3, 0x7a, 0x5b, 0x1d, 0xc2, 0xf6, 0xb2, 0xb7, 0x8c, + 0xdc, 0x5f, 0x12, 0x39, 0xdf, 0x61, 0x41, 0x20, 0x64, 0xbc, 0x9a, 0xa3, 0x25, 0xd7, 0xf4, 0x69, + 0x96, 0x59, 0x94, 0x12, 0x7a, 0x1b, 0xab, 0xa1, 0x94, 0x7e, 0x04, 0xd0, 0x09, 0xbc, 0xb9, 0xf4, + 0xc0, 0x1d, 0xdd, 0xaf, 0x30, 0x8e, 0x39, 0xf4, 0x5f, 0x45, 0x58, 0x3d, 0xe5, 0x3c, 0x24, 0x4f, + 0x93, 0x34, 0xa8, 0xa6, 0x24, 0xba, 0x29, 0xe5, 0xaa, 0x8e, 0x31, 0x49, 0xcd, 0x4b, 0xa8, 0xc9, + 0xe3, 0x86, 0xed, 0x86, 0xfe, 0xea, 0xfb, 0x9f, 0x6a, 0xf9, 0x3e, 0xbf, 0xc6, 0x83, 0xdf, 0x0f, + 0x84, 0x3b, 0xe6, 0x2c, 0x91, 0x93, 0x3b, 0x94, 0x47, 0x51, 0xe5, 0xb3, 0xcc, 0x14, 0x21, 0xf3, + 0x39, 0x75, 0x1d, 0x87, 0xfb, 0x98, 0xcf, 0x2a, 0xd3, 0x94, 0x6c, 0x9d, 0x99, 0x1d, 0x4d, 0x3b, + 0x53, 0x3e, 0xbe, 0xc4, 0xee, 0x5c, 0x61, 0x09, 0x43, 0x36, 0x5d, 0xc4, 0x67, 0x93, 0x39, 0xe7, + 0x21, 0x36, 0x65, 0x95, 0xc5, 0x34, 0x7d, 0x06, 0x55, 0x19, 0xf4, 0xb1, 0x1b, 0x09, 0xf2, 0x33, + 0x28, 0x4b, 0x9e, 0xdc, 0xd4, 0xca, 0x6e, 0x7d, 0xbf, 0x9e, 0xda, 0x14, 0x53, 0x2b, 0xf4, 0x0a, + 0x40, 0x8a, 0x9e, 0xda, 0xa1, 0xed, 0x45, 0xb9, 0xad, 0x28, 0x43, 0x4c, 0x4f, 0x2e, 0x4d, 0x49, + 0xd9, 0xf8, 0xfc, 0x35, 0x19, 0x7e, 0x4b, 0xd9, 0x60, 0x32, 0x89, 0xb8, 0x6a, 0x8f, 0x26, 0xd3, + 0x14, 0xb1, 0x60, 0xc5, 0x8e, 0xc6, 0xb8, 0x91, 0x2a, 0x93, 0x9f, 0xf4, 0x35, 0xc0, 0xa9, 0x7d, + 0xc1, 0xb5, 0xdf, 0x44, 0xaf, 0x98, 0xd1, 0x33, 0x3e, 0x4a, 0x89, 0x0f, 0x7a, 0x03, 0xeb, 0x98, + 0xe2, 0x83, 0xc0, 0xb9, 0x95, 0x26, 0x70, 0x82, 0xe1, 0x99, 0x34, 0xad, 0x8d, 0x44, 0xca, 0x66, + 0x29, 0xd7, 0x66, 0x3a, 0xee, 0xcf, 0x61, 0xf5, 0x3c, 0x70, 0x6e, 0x31, 0xea, 0xfa, 0xbe, 0xa5, + 0xf3, 0x14, 0xbb, 0x61, 0xb8, 0x4a, 0xff, 0x0a, 0x1b, 0x29, 0xcf, 0x18, 0x38, 0x85, 0x86, 0x4c, + 0x52, 0x10, 0xfa, 0x6a, 0x58, 0xa9, 0xc4, 0x65, 0x78, 0xe4, 0x4b, 0xa8, 0xcc, 0xed, 0x0b, 0x39, + 0x40, 0x54, 0xaf, 0x6c, 0x9a, 0x32, 0xc4, 0xfb, 0x67, 0x5a, 0x80, 0xfe, 0x5a, 0x7b, 0x38, 0xe2, + 0xb6, 0xa3, 0x6b, 0xf8, 0x39, 0x54, 0xd4, 0x5c, 0xd3, 0x45, 0x6c, 0xa4, 0x83, 0x63, 0x7a, 0x8d, + 0xba, 0xd0, 0x44, 0xc6, 0x5b, 0x2e, 0x6c, 0xc7, 0x16, 0x76, 0x6e, 0x25, 0x9f, 0xc8, 0x4a, 0x4a, + 0xc3, 0x3a, 0x10, 0x92, 0x36, 0xa5, 0x5c, 0x32, 0x2d, 0x21, 0x0f, 0x9a, 0xb8, 0x51, 0x07, 0x4d, + 0x35, 0xac, 0x21, 0x69, 0x1b, 0x36, 0x33, 0xae, 0x30, 0xca, 0xa7, 0x4b, 0x51, 0x6e, 0xa5, 0x4d, + 0x1b, 0xc9, 0x38, 0x5a, 0x0e, 0x8d, 0x4e, 0xe0, 0x79, 0xae, 0x60, 0x3c, 0x5a, 0xcc, 0xf2, 0x27, + 0xe0, 0x97, 0x50, 0xe6, 0x61, 0x18, 0xa8, 0x58, 0xd7, 0xf7, 0x3f, 0x31, 0xb7, 0x04, 0xea, 0xa9, + 0x1b, 0x98, 0x29, 0x09, 0x59, 0x69, 0x87, 0x0b, 0xdb, 0x9d, 0xe9, 0x7b, 0x53, 0x53, 0xb4, 0x0d, + 0x56, 0xda, 0x0d, 0x06, 0xfa, 0x0c, 0xd6, 0x42, 0xa4, 0x4c, 0xa4, 0x59, 0xc3, 0x4a, 0x92, 0x19, + 0x19, 0x3a, 0x84, 0xc6, 0x7b, 0x1e, 0xba, 0x93, 0x5b, 0x1d, 0xe9, 0xff, 0x41, 0x49, 0xdc, 0xe8, + 0x19, 0x51, 0xd3, 0x9a, 0xc3, 0x1b, 0x56, 0x12, 0x37, 0x1f, 0x0a, 0x58, 0xa9, 0x67, 0x02, 0xa6, + 0x43, 0x79, 0x46, 0xc3, 0x28, 0xf0, 0xed, 0x99, 0x9c, 0x51, 0x73, 0x3b, 0x8a, 0xe6, 0xd3, 0xd0, + 0x8e, 0xb8, 0xbe, 0x83, 0x53, 0x1c, 0xb2, 0x0b, 0x66, 0xc4, 0xe9, 0xaa, 0x99, 0xfb, 0x52, 0xcf, + 0xc1, 0x78, 0x02, 0xd2, 0x29, 0x34, 0x7a, 0xde, 0x3c, 0x08, 0xc5, 0x61, 0x10, 0x7a, 0xb6, 0xec, + 0x9c, 0x95, 0x6b, 0x77, 0xb2, 0x34, 0xd0, 0x52, 0xc3, 0x99, 0xc9, 0x65, 0x59, 0xe8, 0x60, 0xe6, + 0x48, 0x87, 0x68, 0xbf, 0xc6, 0x0c, 0x29, 0x57, 0x7c, 0x7e, 0x8d, 0x2b, 0x2a, 0xaf, 0x86, 0xa4, + 0xaf, 0x60, 0x6d, 0xa0, 0xef, 0xbf, 0x7b, 0x50, 0xb1, 0xbd, 0xd4, 0x3c, 0xd6, 0x94, 0x2c, 0xe9, + 0xf5, 0x94, 0xfb, 0x7a, 0x66, 0xe0, 0x37, 0xfd, 0x2d, 0xac, 0xbe, 0x0f, 0x04, 0xde, 0x8b, 0x63, + 0xdb, 0x77, 0x5c, 0x47, 0x8e, 0x43, 0xa5, 0x96, 0x30, 0x52, 0x16, 0x4b, 0x69, 0x8b, 0x74, 0x1f, + 0x40, 0x6a, 0xeb, 0x83, 0xb7, 0x1e, 0x23, 0x88, 0x1a, 0x22, 0x86, 0x2d, 0x28, 0x27, 0x49, 0x6a, + 0x32, 0x45, 0x50, 0x07, 0x36, 0x74, 0x9a, 0xa4, 0x2a, 0x42, 0x8f, 0x5d, 0x58, 0x33, 0xf7, 0x79, + 0x16, 0x7f, 0xe8, 0x1d, 0x31, 0xb3, 0x4c, 0xbe, 0x80, 0xca, 0x55, 0x20, 0xd4, 0xb9, 0x95, 0x9d, + 0xb2, 0x61, 0x2a, 0xaa, 0x4d, 0x31, 0xbd, 0x4c, 0xbf, 0x81, 0x6a, 0x6c, 0x5e, 0xc5, 0x55, 0x8a, + 0xe3, 0x7a, 0x04, 0x10, 0x6f, 0x4d, 0xe6, 0x71, 0x45, 0x96, 0x37, 0xe1, 0xd0, 0xdf, 0x29, 0x5d, + 0x33, 0xae, 0xaf, 0x02, 0x29, 0x96, 0x1d, 0xd7, 0x72, 0x9d, 0xa9, 0x95, 0x65, 0xf3, 0xb4, 0x0d, + 0x6b, 0xfd, 0xc0, 0xe1, 0x8c, 0xff, 0x88, 0x27, 0xd6, 0xf5, 0x78, 0xb0, 0x88, 0xaf, 0x46, 0x4d, + 0x2a, 0x64, 0xe6, 0xcd, 0x03, 0x9f, 0xc7, 0x49, 0x4d, 0x18, 0xb4, 0x05, 0xab, 0x7d, 0xdb, 0xe3, + 0xb2, 0x62, 0x12, 0x9c, 0xe8, 0x9c, 0xe2, 0x37, 0x1d, 0x43, 0x55, 0xae, 0xe1, 0xce, 0x3e, 0x4b, + 0xad, 0x27, 0xc1, 0xc9, 0x65, 0x25, 0x2c, 0x4b, 0x10, 0x5c, 0xfb, 0x7a, 0xba, 0x34, 0x98, 0x22, + 0xc8, 0x0e, 0xd4, 0x1d, 0x1e, 0x09, 0xd7, 0xb7, 0x85, 0x1b, 0xf8, 0x1a, 0x4d, 0xa4, 0x59, 0xb4, + 0x0b, 0x75, 0x79, 0x23, 0x45, 0xba, 0xb2, 0x2d, 0xa8, 0xfa, 0xc1, 0x91, 0xba, 0x14, 0x8b, 0xea, + 0x72, 0x33, 0x34, 0x5e, 0x7c, 0xd3, 0xe0, 0x7a, 0xc0, 0x67, 0x13, 0x8d, 0x4b, 0x63, 0x9a, 0x3e, + 0x84, 0xda, 0xf7, 0xdc, 0xcc, 0x65, 0x0b, 0x56, 0x2e, 0xf9, 0x2d, 0x26, 0xb2, 0xc6, 0xe4, 0x27, + 0xfd, 0x5b, 0x09, 0x60, 0xc0, 0xc3, 0x2b, 0x1e, 0xe2, 0x6e, 0x5e, 0x41, 0x25, 0xc2, 0x33, 0xa9, + 0x93, 0xfd, 0xd0, 0x74, 0x41, 0x2c, 0xb2, 0xa7, 0xce, 0x6c, 0xd7, 0x17, 0xe1, 0x2d, 0xd3, 0xc2, + 0x52, 0x6d, 0x1c, 0xf8, 0x13, 0xd7, 0xf4, 0x44, 0x8e, 0x5a, 0x07, 0xd7, 0xb5, 0x9a, 0x12, 0x6e, + 0xfd, 0x06, 0xea, 0x29, 0x6b, 0x49, 0x74, 0x45, 0x1d, 0x5d, 0x82, 0x7f, 0x54, 0x69, 0x15, 0xf1, + 0x4d, 0xe9, 0x75, 0xb1, 0x75, 0x0c, 0xf5, 0x94, 0xc5, 0x1c, 0xd5, 0x2f, 0xd2, 0xaa, 0xc9, 0xed, + 0xa2, 0x94, 0x7a, 0x82, 0x7b, 0x29, 0x6b, 0xf4, 0x27, 0x89, 0x88, 0xcc, 0x02, 0xd9, 0x87, 0xf2, + 0x3c, 0x0c, 0xe6, 0x91, 0xde, 0xcc, 0x83, 0x3b, 0xaa, 0x7b, 0xa7, 0x72, 0x59, 0xed, 0x45, 0x89, + 0xb6, 0xe4, 0xc5, 0x1d, 0x33, 0x3f, 0x66, 0x27, 0xf4, 0x05, 0xd4, 0xba, 0x57, 0xdc, 0x17, 0xe6, + 0x5a, 0xe3, 0x92, 0x58, 0xbe, 0xd6, 0x50, 0x82, 0xe9, 0x35, 0xda, 0x83, 0x66, 0x27, 0xf3, 0x06, + 0x22, 0xb0, 0x2a, 0xe5, 0x4c, 0x93, 0xca, 0x6f, 0xc9, 0xc3, 0x47, 0x93, 0x72, 0x88, 0xdf, 0x32, + 0xae, 0xf3, 0xb9, 0x39, 0x6f, 0xf2, 0xf3, 0xc9, 0xbf, 0x8b, 0xe6, 0xd2, 0xd1, 0xcf, 0xb7, 0x1a, + 0x94, 0x87, 0x67, 0xa3, 0x93, 0xef, 0xad, 0x02, 0xd9, 0x02, 0x6b, 0x78, 0x36, 0xea, 0x9f, 0xf4, + 0x3b, 0xdd, 0xd1, 0xf0, 0xe4, 0x64, 0x74, 0x7c, 0xf2, 0x27, 0xab, 0x48, 0x3e, 0x85, 0xcd, 0xe1, + 0xd9, 0xa8, 0x7d, 0xcc, 0xba, 0xed, 0xef, 0x7e, 0x18, 0x75, 0xcf, 0x7a, 0x83, 0xe1, 0xc0, 0x2a, + 0x91, 0x4f, 0x60, 0x63, 0x78, 0x36, 0xea, 0xf5, 0xdf, 0xb7, 0x8f, 0x7b, 0xdf, 0x8d, 0x8e, 0xda, + 0x83, 0x23, 0x6b, 0x65, 0x89, 0x39, 0xe8, 0xbd, 0xe9, 0x5b, 0xab, 0xda, 0x80, 0x61, 0x1e, 0x9e, + 0xb0, 0xb7, 0xed, 0xa1, 0x55, 0x26, 0xff, 0x0f, 0xf7, 0x91, 0x3d, 0x78, 0x77, 0x78, 0xd8, 0xeb, + 0xf4, 0xba, 0xfd, 0xe1, 0xe8, 0xa0, 0x7d, 0xdc, 0xee, 0x77, 0xba, 0x56, 0x45, 0xeb, 0x1c, 0xb5, + 0x07, 0xa3, 0x41, 0xfb, 0x6d, 0x57, 0xc5, 0x64, 0xad, 0xc5, 0xa6, 0x86, 0x5d, 0xd6, 0x6f, 0x1f, + 0x8f, 0xba, 0x8c, 0x9d, 0x30, 0xab, 0xf6, 0x64, 0x62, 0xae, 0x27, 0xbd, 0xa7, 0x2d, 0xb0, 0xde, + 0x77, 0x59, 0xef, 0xf0, 0x87, 0xd1, 0x60, 0xd8, 0x1e, 0xbe, 0x1b, 0xa8, 0xed, 0xed, 0xc0, 0x83, + 0x2c, 0x57, 0xc6, 0x37, 0xea, 0x9f, 0x0c, 0x47, 0x6f, 0xdb, 0xc3, 0xce, 0x91, 0x55, 0x24, 0x8f, + 0xa0, 0x95, 0x95, 0xc8, 0x6c, 0xaf, 0xb4, 0xff, 0x0f, 0x0b, 0x36, 0xda, 0x3c, 0xbc, 0x08, 0xd8, + 0x69, 0x47, 0xb6, 0xba, 0x7c, 0xdd, 0xbc, 0x80, 0x9a, 0x1c, 0x3d, 0x03, 0xc4, 0xb1, 0x66, 0x88, + 0xea, 0x61, 0xd4, 0xca, 0xb9, 0x6e, 0x68, 0x81, 0xbc, 0x80, 0xca, 0x5b, 0x7c, 0x56, 0x13, 0x83, + 0x97, 0x15, 0x19, 0x31, 0xfe, 0xe3, 0x82, 0x47, 0xa2, 0xb5, 0x9e, 0x65, 0xd3, 0x02, 0x79, 0x05, + 0x90, 0x3c, 0xbc, 0x49, 0xdc, 0x25, 0xf2, 0xad, 0xd1, 0xba, 0x9f, 0x06, 0x19, 0xa9, 0x97, 0x39, + 0x2d, 0x90, 0xe7, 0xd0, 0x78, 0xc3, 0x45, 0xf2, 0xe0, 0xcc, 0x2a, 0x5a, 0x99, 0x27, 0xa7, 0x3f, + 0x09, 0x68, 0x81, 0x7c, 0x0b, 0x96, 0x6c, 0xcc, 0x14, 0x16, 0x8a, 0x88, 0x39, 0x4b, 0x09, 0x42, + 0x6e, 0xdd, 0xbb, 0x8b, 0x99, 0xe4, 0x2a, 0x2d, 0x90, 0x03, 0xd8, 0x8c, 0x0d, 0xc4, 0x30, 0x2c, + 0xc7, 0xc2, 0x76, 0x1e, 0x34, 0xd2, 0x36, 0x5e, 0xc0, 0x46, 0x6c, 0x63, 0x20, 0x42, 0x6e, 0x7b, + 0x4b, 0x91, 0x67, 0xd0, 0x1f, 0x2d, 0x3c, 0x2f, 0x92, 0x36, 0xdc, 0xbf, 0xe3, 0x36, 0x57, 0x35, + 0x17, 0x92, 0xa1, 0x89, 0x3d, 0xa8, 0xbe, 0xe1, 0xca, 0x02, 0xc9, 0x29, 0xdc, 0xb2, 0x53, 0xf2, + 0x7b, 0xb0, 0x8c, 0x7c, 0x82, 0x37, 0x73, 0xf4, 0x3e, 0xe0, 0x91, 0x7c, 0x8b, 0xc5, 0x89, 0xa1, + 0x34, 0xb9, 0xb7, 0x8c, 0xb7, 0x75, 0xa6, 0x3e, 0xbd, 0xcb, 0xbf, 0xe0, 0x0e, 0x2d, 0x90, 0x5d, + 0x28, 0xbf, 0xe1, 0x62, 0x78, 0x96, 0xeb, 0x35, 0x81, 0x65, 0xb4, 0x40, 0x7e, 0x05, 0x60, 0x5c, + 0x7d, 0x40, 0xdc, 0x8a, 0xc5, 0x7b, 0xbe, 0xd9, 0xe0, 0x3e, 0x6a, 0x31, 0x3e, 0xe6, 0xee, 0x5c, + 0xe4, 0x6a, 0x99, 0x46, 0xd5, 0x32, 0xb4, 0x20, 0xc1, 0xf5, 0x1b, 0x2e, 0xda, 0x07, 0xbd, 0x5c, + 0x79, 0x30, 0xa0, 0xed, 0xa0, 0xa7, 0x64, 0x07, 0xdc, 0x77, 0x86, 0x67, 0x24, 0x09, 0xb6, 0x95, + 0x07, 0x44, 0xa9, 0x3c, 0xbc, 0x95, 0x81, 0x7b, 0xe1, 0x67, 0x65, 0x33, 0x7b, 0x7c, 0x0a, 0x55, + 0x35, 0x04, 0xf2, 0xed, 0xa5, 0xf1, 0x2b, 0x66, 0xa4, 0xaa, 0x3c, 0x0c, 0xcf, 0x48, 0x33, 0x96, + 0x96, 0x2d, 0x14, 0x9f, 0xa7, 0x65, 0xd0, 0x4c, 0x0b, 0xba, 0x45, 0xd4, 0x59, 0xff, 0x6f, 0x2d, + 0x82, 0x12, 0xb4, 0x40, 0xfe, 0x80, 0x2d, 0x82, 0x54, 0xdb, 0x77, 0x4e, 0xc3, 0x20, 0x98, 0xc4, + 0x67, 0x3e, 0xfb, 0xa4, 0x8f, 0xe3, 0xd4, 0x6c, 0x94, 0xc5, 0x1a, 0x34, 0x3b, 0x21, 0x97, 0xfa, + 0xfa, 0x81, 0xbf, 0x11, 0xbf, 0x5e, 0x15, 0x72, 0x6e, 0x2d, 0x01, 0x61, 0x3c, 0x3e, 0x75, 0x59, + 0x03, 0x45, 0x47, 0x4b, 0xfd, 0x4f, 0xb2, 0xe2, 0x7a, 0x63, 0xcf, 0xa1, 0x7e, 0x1c, 0x8c, 0x2f, + 0x3f, 0xc2, 0xc9, 0x3e, 0x34, 0xdf, 0xf9, 0xb3, 0x8f, 0xd3, 0xf9, 0x1a, 0x9a, 0x0a, 0x9a, 0x1b, + 0x1d, 0xb3, 0xe9, 0x34, 0x60, 0xcf, 0xd7, 0xeb, 0xde, 0xa4, 0xf5, 0xee, 0xf8, 0xca, 0x1f, 0xb4, + 0x2f, 0xa1, 0xf9, 0xc7, 0x05, 0x0f, 0x6f, 0x3b, 0x81, 0x2f, 0x42, 0x7b, 0x2c, 0xe2, 0x54, 0x20, + 0xf7, 0x03, 0x4a, 0x6d, 0x20, 0x19, 0x25, 0x55, 0xed, 0xcd, 0x74, 0x65, 0x95, 0xfa, 0xbd, 0x3b, + 0x2c, 0x53, 0xb4, 0x17, 0xd8, 0x26, 0x88, 0xe6, 0x48, 0xfa, 0x2f, 0x14, 0x8d, 0xed, 0x5a, 0x1b, + 0x29, 0x5e, 0x5c, 0x00, 0xa9, 0xf2, 0x1e, 0xd1, 0xed, 0x66, 0x0a, 0xf1, 0x2e, 0x69, 0x18, 0x90, + 0x8c, 0x83, 0x76, 0x23, 0xa9, 0xb2, 0x52, 0x5c, 0x6e, 0x2d, 0xf5, 0x47, 0x4d, 0x1c, 0xe8, 0xd2, + 0x1b, 0x40, 0x5d, 0x2b, 0xaa, 0x3f, 0x11, 0xe9, 0x7f, 0x40, 0x7d, 0xe9, 0x65, 0x40, 0x0b, 0xe4, + 0x19, 0x36, 0x58, 0x0c, 0x89, 0xd3, 0x20, 0x38, 0x8e, 0xd4, 0xac, 0x62, 0xf9, 0x70, 0x9c, 0x23, + 0xa6, 0xd1, 0x33, 0xd9, 0x6c, 0xf1, 0xd0, 0x9d, 0x09, 0x05, 0x18, 0x5b, 0x19, 0xe8, 0x83, 0x03, + 0xf9, 0xa5, 0xfa, 0x53, 0x06, 0x19, 0x51, 0x9e, 0x8a, 0x95, 0x56, 0xd1, 0x69, 0xf9, 0x1a, 0x9a, + 0x72, 0x4b, 0x09, 0xc4, 0x35, 0x42, 0x31, 0x2a, 0x6e, 0x6d, 0xde, 0x41, 0xab, 0xb4, 0x40, 0x5e, + 0xe3, 0x51, 0xcd, 0xc2, 0xac, 0xfc, 0x9b, 0x23, 0x23, 0x43, 0x0b, 0x07, 0x3b, 0x7f, 0x7e, 0x74, + 0xe1, 0x8a, 0xe9, 0xe2, 0x7c, 0x6f, 0x1c, 0x78, 0x5f, 0xd9, 0x12, 0x1f, 0xb8, 0x81, 0xfa, 0xfd, + 0x0a, 0x35, 0xce, 0x2b, 0xf8, 0xf7, 0xf9, 0xcb, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x97, 0xff, + 0x17, 0x0a, 0x98, 0x17, 0x00, 0x00, } From 1ae8dcaa48e27ce96675eb636f833944f9d412e4 Mon Sep 17 00:00:00 2001 From: Sung-Jae Woo Date: Mon, 15 Apr 2019 17:35:18 +0900 Subject: [PATCH 027/148] [rpc] add skeleton code for ChainStat RPC command - Update for the ChainStat RPC command & fix build failure related to it. - Remove chain stat field from the blockchain RPC command result. --- aergo-protobuf | 2 +- cmd/aergocli/cmd/mock_types/mock_types.go | 21 +- cmd/aergocli/util/base58addr.go | 1 - rpc/grpcserver.go | 8 +- types/rpc.pb.go | 466 +++++++++++++--------- 5 files changed, 294 insertions(+), 204 deletions(-) diff --git a/aergo-protobuf b/aergo-protobuf index 63059e092..cf06c4811 160000 --- a/aergo-protobuf +++ b/aergo-protobuf @@ -1 +1 @@ -Subproject commit 63059e092d2610192bf63c3d2e97a50d10c5f6a6 +Subproject commit cf06c4811a678504a58d12627b2f295f55acac2b diff --git a/cmd/aergocli/cmd/mock_types/mock_types.go b/cmd/aergocli/cmd/mock_types/mock_types.go index 4eeb9c25d..351a5fdfe 100644 --- a/cmd/aergocli/cmd/mock_types/mock_types.go +++ b/cmd/aergocli/cmd/mock_types/mock_types.go @@ -6,10 +6,11 @@ package mock_types import ( context "context" + reflect "reflect" + types "github.com/aergoio/aergo/types" gomock "github.com/golang/mock/gomock" grpc "google.golang.org/grpc" - reflect "reflect" ) // MockAergoRPCServiceClient is a mock of AergoRPCServiceClient interface @@ -251,6 +252,24 @@ func (mr *MockAergoRPCServiceClientMockRecorder) GetChainInfo(arg0, arg1 interfa return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChainInfo", reflect.TypeOf((*MockAergoRPCServiceClient)(nil).GetChainInfo), varargs...) } +// ChainStat mocks base method +func (m *MockAergoRPCServiceClient) ChainStat(arg0 context.Context, arg1 *types.Empty, arg2 ...grpc.CallOption) (*types.ChainStats, error) { + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetChainInfo", varargs...) + ret0, _ := ret[0].(*types.ChainStats) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainStat indicates an expected call of ChainStat +func (mr *MockAergoRPCServiceClientMockRecorder) ChainStat(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChainInfo", reflect.TypeOf((*MockAergoRPCServiceClient)(nil).GetChainInfo), varargs...) +} + // GetConsensusInfo mocks base method func (m *MockAergoRPCServiceClient) GetConsensusInfo(arg0 context.Context, arg1 *types.Empty, arg2 ...grpc.CallOption) (*types.ConsensusInfo, error) { varargs := []interface{}{arg0, arg1} diff --git a/cmd/aergocli/util/base58addr.go b/cmd/aergocli/util/base58addr.go index e409bffe7..96999ea40 100644 --- a/cmd/aergocli/util/base58addr.go +++ b/cmd/aergocli/util/base58addr.go @@ -272,7 +272,6 @@ func ConvBlockchainStatus(in *types.BlockchainStatus) string { return nil } out.ConsensusInfo = toJRM(in.ConsensusInfo) - out.ChainStat = toJRM(in.ChainStat) jsonout, err := json.Marshal(out) if err != nil { diff --git a/rpc/grpcserver.go b/rpc/grpcserver.go index b45d69be8..6638f934a 100644 --- a/rpc/grpcserver.go +++ b/rpc/grpcserver.go @@ -131,7 +131,6 @@ func (rpc *AergoRPCService) Blockchain(ctx context.Context, in *types.Empty) (*t BestHeight: last.GetHeader().GetBlockNo(), ConsensusInfo: ca.GetConsensusInfo(), BestChainIdHash: bestChainIdHash, - ChainStat: ca.GetChainStats(), }, nil } @@ -1041,7 +1040,7 @@ func (rpc *AergoRPCService) GetServerInfo(ctx context.Context, in *types.KeyPara return rsp, nil } -// Blockchain handle rpc request blockchain. It has no additional input parameter +// GetConsensusInfo handle rpc request blockchain. It has no additional input parameter func (rpc *AergoRPCService) GetConsensusInfo(ctx context.Context, in *types.Empty) (*types.ConsensusInfo, error) { if rpc.consensusAccessor == nil { return nil, ErrUninitAccessor @@ -1049,3 +1048,8 @@ func (rpc *AergoRPCService) GetConsensusInfo(ctx context.Context, in *types.Empt return rpc.consensusAccessor.ConsensusInfo(), nil } + +// Chainstat handles rpc request chainstat. +func (rpc *AergoRPCService) ChainStat(ctx context.Context, in *types.Empty) (*types.ChainStats, error) { + return nil, nil +} diff --git a/types/rpc.pb.go b/types/rpc.pb.go index baf859f29..8a7d5f961 100644 --- a/types/rpc.pb.go +++ b/types/rpc.pb.go @@ -64,7 +64,7 @@ func (x CommitStatus) String() string { return proto.EnumName(CommitStatus_name, int32(x)) } func (CommitStatus) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{0} + return fileDescriptor_rpc_ae4e7533275017ec, []int{0} } type VerifyStatus int32 @@ -90,7 +90,7 @@ func (x VerifyStatus) String() string { return proto.EnumName(VerifyStatus_name, int32(x)) } func (VerifyStatus) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{1} + return fileDescriptor_rpc_ae4e7533275017ec, []int{1} } // BlockchainStatus is current status of blockchain @@ -99,7 +99,6 @@ type BlockchainStatus struct { BestHeight uint64 `protobuf:"varint,2,opt,name=best_height,json=bestHeight,proto3" json:"best_height,omitempty"` ConsensusInfo string `protobuf:"bytes,3,opt,name=consensus_info,json=consensusInfo,proto3" json:"consensus_info,omitempty"` BestChainIdHash []byte `protobuf:"bytes,4,opt,name=best_chain_id_hash,json=bestChainIdHash,proto3" json:"best_chain_id_hash,omitempty"` - ChainStat string `protobuf:"bytes,5,opt,name=chain_stat,json=chainStat,proto3" json:"chain_stat,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -109,7 +108,7 @@ func (m *BlockchainStatus) Reset() { *m = BlockchainStatus{} } func (m *BlockchainStatus) String() string { return proto.CompactTextString(m) } func (*BlockchainStatus) ProtoMessage() {} func (*BlockchainStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{0} + return fileDescriptor_rpc_ae4e7533275017ec, []int{0} } func (m *BlockchainStatus) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BlockchainStatus.Unmarshal(m, b) @@ -157,13 +156,6 @@ func (m *BlockchainStatus) GetBestChainIdHash() []byte { return nil } -func (m *BlockchainStatus) GetChainStat() string { - if m != nil { - return m.ChainStat - } - return "" -} - type ChainId struct { Magic string `protobuf:"bytes,1,opt,name=magic,proto3" json:"magic,omitempty"` Public bool `protobuf:"varint,2,opt,name=public,proto3" json:"public,omitempty"` @@ -178,7 +170,7 @@ func (m *ChainId) Reset() { *m = ChainId{} } func (m *ChainId) String() string { return proto.CompactTextString(m) } func (*ChainId) ProtoMessage() {} func (*ChainId) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{1} + return fileDescriptor_rpc_ae4e7533275017ec, []int{1} } func (m *ChainId) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ChainId.Unmarshal(m, b) @@ -245,7 +237,7 @@ func (m *ChainInfo) Reset() { *m = ChainInfo{} } func (m *ChainInfo) String() string { return proto.CompactTextString(m) } func (*ChainInfo) ProtoMessage() {} func (*ChainInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{2} + return fileDescriptor_rpc_ae4e7533275017ec, []int{2} } func (m *ChainInfo) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ChainInfo.Unmarshal(m, b) @@ -321,6 +313,45 @@ func (m *ChainInfo) GetNameprice() []byte { return nil } +// ChainStats corresponds to a chain statistics report. +type ChainStats struct { + Report string `protobuf:"bytes,1,opt,name=report,proto3" json:"report,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ChainStats) Reset() { *m = ChainStats{} } +func (m *ChainStats) String() string { return proto.CompactTextString(m) } +func (*ChainStats) ProtoMessage() {} +func (*ChainStats) Descriptor() ([]byte, []int) { + return fileDescriptor_rpc_ae4e7533275017ec, []int{3} +} +func (m *ChainStats) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ChainStats.Unmarshal(m, b) +} +func (m *ChainStats) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ChainStats.Marshal(b, m, deterministic) +} +func (dst *ChainStats) XXX_Merge(src proto.Message) { + xxx_messageInfo_ChainStats.Merge(dst, src) +} +func (m *ChainStats) XXX_Size() int { + return xxx_messageInfo_ChainStats.Size(m) +} +func (m *ChainStats) XXX_DiscardUnknown() { + xxx_messageInfo_ChainStats.DiscardUnknown(m) +} + +var xxx_messageInfo_ChainStats proto.InternalMessageInfo + +func (m *ChainStats) GetReport() string { + if m != nil { + return m.Report + } + return "" +} + type Input struct { Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` Address [][]byte `protobuf:"bytes,2,rep,name=address,proto3" json:"address,omitempty"` @@ -335,7 +366,7 @@ func (m *Input) Reset() { *m = Input{} } func (m *Input) String() string { return proto.CompactTextString(m) } func (*Input) ProtoMessage() {} func (*Input) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{3} + return fileDescriptor_rpc_ae4e7533275017ec, []int{4} } func (m *Input) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Input.Unmarshal(m, b) @@ -397,7 +428,7 @@ func (m *Output) Reset() { *m = Output{} } func (m *Output) String() string { return proto.CompactTextString(m) } func (*Output) ProtoMessage() {} func (*Output) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{4} + return fileDescriptor_rpc_ae4e7533275017ec, []int{5} } func (m *Output) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Output.Unmarshal(m, b) @@ -455,7 +486,7 @@ func (m *Empty) Reset() { *m = Empty{} } func (m *Empty) String() string { return proto.CompactTextString(m) } func (*Empty) ProtoMessage() {} func (*Empty) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{5} + return fileDescriptor_rpc_ae4e7533275017ec, []int{6} } func (m *Empty) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Empty.Unmarshal(m, b) @@ -486,7 +517,7 @@ func (m *SingleBytes) Reset() { *m = SingleBytes{} } func (m *SingleBytes) String() string { return proto.CompactTextString(m) } func (*SingleBytes) ProtoMessage() {} func (*SingleBytes) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{6} + return fileDescriptor_rpc_ae4e7533275017ec, []int{7} } func (m *SingleBytes) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SingleBytes.Unmarshal(m, b) @@ -524,7 +555,7 @@ func (m *AccountAddress) Reset() { *m = AccountAddress{} } func (m *AccountAddress) String() string { return proto.CompactTextString(m) } func (*AccountAddress) ProtoMessage() {} func (*AccountAddress) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{7} + return fileDescriptor_rpc_ae4e7533275017ec, []int{8} } func (m *AccountAddress) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_AccountAddress.Unmarshal(m, b) @@ -564,7 +595,7 @@ func (m *AccountAndRoot) Reset() { *m = AccountAndRoot{} } func (m *AccountAndRoot) String() string { return proto.CompactTextString(m) } func (*AccountAndRoot) ProtoMessage() {} func (*AccountAndRoot) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{8} + return fileDescriptor_rpc_ae4e7533275017ec, []int{9} } func (m *AccountAndRoot) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_AccountAndRoot.Unmarshal(m, b) @@ -621,7 +652,7 @@ func (m *Peer) Reset() { *m = Peer{} } func (m *Peer) String() string { return proto.CompactTextString(m) } func (*Peer) ProtoMessage() {} func (*Peer) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{9} + return fileDescriptor_rpc_ae4e7533275017ec, []int{10} } func (m *Peer) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Peer.Unmarshal(m, b) @@ -694,7 +725,7 @@ func (m *PeerList) Reset() { *m = PeerList{} } func (m *PeerList) String() string { return proto.CompactTextString(m) } func (*PeerList) ProtoMessage() {} func (*PeerList) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{10} + return fileDescriptor_rpc_ae4e7533275017ec, []int{11} } func (m *PeerList) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PeerList.Unmarshal(m, b) @@ -736,7 +767,7 @@ func (m *ListParams) Reset() { *m = ListParams{} } func (m *ListParams) String() string { return proto.CompactTextString(m) } func (*ListParams) ProtoMessage() {} func (*ListParams) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{11} + return fileDescriptor_rpc_ae4e7533275017ec, []int{12} } func (m *ListParams) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ListParams.Unmarshal(m, b) @@ -803,7 +834,7 @@ func (m *PageParams) Reset() { *m = PageParams{} } func (m *PageParams) String() string { return proto.CompactTextString(m) } func (*PageParams) ProtoMessage() {} func (*PageParams) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{12} + return fileDescriptor_rpc_ae4e7533275017ec, []int{13} } func (m *PageParams) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PageParams.Unmarshal(m, b) @@ -851,7 +882,7 @@ func (m *BlockBodyPaged) Reset() { *m = BlockBodyPaged{} } func (m *BlockBodyPaged) String() string { return proto.CompactTextString(m) } func (*BlockBodyPaged) ProtoMessage() {} func (*BlockBodyPaged) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{13} + return fileDescriptor_rpc_ae4e7533275017ec, []int{14} } func (m *BlockBodyPaged) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BlockBodyPaged.Unmarshal(m, b) @@ -911,7 +942,7 @@ func (m *BlockBodyParams) Reset() { *m = BlockBodyParams{} } func (m *BlockBodyParams) String() string { return proto.CompactTextString(m) } func (*BlockBodyParams) ProtoMessage() {} func (*BlockBodyParams) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{14} + return fileDescriptor_rpc_ae4e7533275017ec, []int{15} } func (m *BlockBodyParams) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BlockBodyParams.Unmarshal(m, b) @@ -956,7 +987,7 @@ func (m *BlockHeaderList) Reset() { *m = BlockHeaderList{} } func (m *BlockHeaderList) String() string { return proto.CompactTextString(m) } func (*BlockHeaderList) ProtoMessage() {} func (*BlockHeaderList) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{15} + return fileDescriptor_rpc_ae4e7533275017ec, []int{16} } func (m *BlockHeaderList) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BlockHeaderList.Unmarshal(m, b) @@ -996,7 +1027,7 @@ func (m *BlockMetadata) Reset() { *m = BlockMetadata{} } func (m *BlockMetadata) String() string { return proto.CompactTextString(m) } func (*BlockMetadata) ProtoMessage() {} func (*BlockMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{16} + return fileDescriptor_rpc_ae4e7533275017ec, []int{17} } func (m *BlockMetadata) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BlockMetadata.Unmarshal(m, b) @@ -1048,7 +1079,7 @@ func (m *BlockMetadataList) Reset() { *m = BlockMetadataList{} } func (m *BlockMetadataList) String() string { return proto.CompactTextString(m) } func (*BlockMetadataList) ProtoMessage() {} func (*BlockMetadataList) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{17} + return fileDescriptor_rpc_ae4e7533275017ec, []int{18} } func (m *BlockMetadataList) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BlockMetadataList.Unmarshal(m, b) @@ -1088,7 +1119,7 @@ func (m *CommitResult) Reset() { *m = CommitResult{} } func (m *CommitResult) String() string { return proto.CompactTextString(m) } func (*CommitResult) ProtoMessage() {} func (*CommitResult) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{18} + return fileDescriptor_rpc_ae4e7533275017ec, []int{19} } func (m *CommitResult) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CommitResult.Unmarshal(m, b) @@ -1140,7 +1171,7 @@ func (m *CommitResultList) Reset() { *m = CommitResultList{} } func (m *CommitResultList) String() string { return proto.CompactTextString(m) } func (*CommitResultList) ProtoMessage() {} func (*CommitResultList) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{19} + return fileDescriptor_rpc_ae4e7533275017ec, []int{20} } func (m *CommitResultList) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CommitResultList.Unmarshal(m, b) @@ -1179,7 +1210,7 @@ func (m *VerifyResult) Reset() { *m = VerifyResult{} } func (m *VerifyResult) String() string { return proto.CompactTextString(m) } func (*VerifyResult) ProtoMessage() {} func (*VerifyResult) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{20} + return fileDescriptor_rpc_ae4e7533275017ec, []int{21} } func (m *VerifyResult) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VerifyResult.Unmarshal(m, b) @@ -1225,7 +1256,7 @@ func (m *Personal) Reset() { *m = Personal{} } func (m *Personal) String() string { return proto.CompactTextString(m) } func (*Personal) ProtoMessage() {} func (*Personal) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{21} + return fileDescriptor_rpc_ae4e7533275017ec, []int{22} } func (m *Personal) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Personal.Unmarshal(m, b) @@ -1272,7 +1303,7 @@ func (m *ImportFormat) Reset() { *m = ImportFormat{} } func (m *ImportFormat) String() string { return proto.CompactTextString(m) } func (*ImportFormat) ProtoMessage() {} func (*ImportFormat) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{22} + return fileDescriptor_rpc_ae4e7533275017ec, []int{23} } func (m *ImportFormat) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ImportFormat.Unmarshal(m, b) @@ -1325,7 +1356,7 @@ func (m *Staking) Reset() { *m = Staking{} } func (m *Staking) String() string { return proto.CompactTextString(m) } func (*Staking) ProtoMessage() {} func (*Staking) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{23} + return fileDescriptor_rpc_ae4e7533275017ec, []int{24} } func (m *Staking) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Staking.Unmarshal(m, b) @@ -1371,7 +1402,7 @@ func (m *Vote) Reset() { *m = Vote{} } func (m *Vote) String() string { return proto.CompactTextString(m) } func (*Vote) ProtoMessage() {} func (*Vote) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{24} + return fileDescriptor_rpc_ae4e7533275017ec, []int{25} } func (m *Vote) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Vote.Unmarshal(m, b) @@ -1417,7 +1448,7 @@ func (m *VoteParams) Reset() { *m = VoteParams{} } func (m *VoteParams) String() string { return proto.CompactTextString(m) } func (*VoteParams) ProtoMessage() {} func (*VoteParams) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{25} + return fileDescriptor_rpc_ae4e7533275017ec, []int{26} } func (m *VoteParams) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VoteParams.Unmarshal(m, b) @@ -1463,7 +1494,7 @@ func (m *AccountVoteInfo) Reset() { *m = AccountVoteInfo{} } func (m *AccountVoteInfo) String() string { return proto.CompactTextString(m) } func (*AccountVoteInfo) ProtoMessage() {} func (*AccountVoteInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{26} + return fileDescriptor_rpc_ae4e7533275017ec, []int{27} } func (m *AccountVoteInfo) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_AccountVoteInfo.Unmarshal(m, b) @@ -1509,7 +1540,7 @@ func (m *VoteInfo) Reset() { *m = VoteInfo{} } func (m *VoteInfo) String() string { return proto.CompactTextString(m) } func (*VoteInfo) ProtoMessage() {} func (*VoteInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{27} + return fileDescriptor_rpc_ae4e7533275017ec, []int{28} } func (m *VoteInfo) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VoteInfo.Unmarshal(m, b) @@ -1555,7 +1586,7 @@ func (m *VoteList) Reset() { *m = VoteList{} } func (m *VoteList) String() string { return proto.CompactTextString(m) } func (*VoteList) ProtoMessage() {} func (*VoteList) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{28} + return fileDescriptor_rpc_ae4e7533275017ec, []int{29} } func (m *VoteList) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VoteList.Unmarshal(m, b) @@ -1601,7 +1632,7 @@ func (m *NodeReq) Reset() { *m = NodeReq{} } func (m *NodeReq) String() string { return proto.CompactTextString(m) } func (*NodeReq) ProtoMessage() {} func (*NodeReq) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{29} + return fileDescriptor_rpc_ae4e7533275017ec, []int{30} } func (m *NodeReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_NodeReq.Unmarshal(m, b) @@ -1646,7 +1677,7 @@ func (m *Name) Reset() { *m = Name{} } func (m *Name) String() string { return proto.CompactTextString(m) } func (*Name) ProtoMessage() {} func (*Name) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{30} + return fileDescriptor_rpc_ae4e7533275017ec, []int{31} } func (m *Name) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Name.Unmarshal(m, b) @@ -1686,7 +1717,7 @@ func (m *NameInfo) Reset() { *m = NameInfo{} } func (m *NameInfo) String() string { return proto.CompactTextString(m) } func (*NameInfo) ProtoMessage() {} func (*NameInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{31} + return fileDescriptor_rpc_ae4e7533275017ec, []int{32} } func (m *NameInfo) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_NameInfo.Unmarshal(m, b) @@ -1739,7 +1770,7 @@ func (m *PeersParams) Reset() { *m = PeersParams{} } func (m *PeersParams) String() string { return proto.CompactTextString(m) } func (*PeersParams) ProtoMessage() {} func (*PeersParams) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{32} + return fileDescriptor_rpc_ae4e7533275017ec, []int{33} } func (m *PeersParams) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PeersParams.Unmarshal(m, b) @@ -1784,7 +1815,7 @@ func (m *KeyParams) Reset() { *m = KeyParams{} } func (m *KeyParams) String() string { return proto.CompactTextString(m) } func (*KeyParams) ProtoMessage() {} func (*KeyParams) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{33} + return fileDescriptor_rpc_ae4e7533275017ec, []int{34} } func (m *KeyParams) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_KeyParams.Unmarshal(m, b) @@ -1823,7 +1854,7 @@ func (m *ServerInfo) Reset() { *m = ServerInfo{} } func (m *ServerInfo) String() string { return proto.CompactTextString(m) } func (*ServerInfo) ProtoMessage() {} func (*ServerInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{34} + return fileDescriptor_rpc_ae4e7533275017ec, []int{35} } func (m *ServerInfo) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ServerInfo.Unmarshal(m, b) @@ -1868,7 +1899,7 @@ func (m *ConfigItem) Reset() { *m = ConfigItem{} } func (m *ConfigItem) String() string { return proto.CompactTextString(m) } func (*ConfigItem) ProtoMessage() {} func (*ConfigItem) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{35} + return fileDescriptor_rpc_ae4e7533275017ec, []int{36} } func (m *ConfigItem) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ConfigItem.Unmarshal(m, b) @@ -1906,7 +1937,7 @@ func (m *EventList) Reset() { *m = EventList{} } func (m *EventList) String() string { return proto.CompactTextString(m) } func (*EventList) ProtoMessage() {} func (*EventList) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{36} + return fileDescriptor_rpc_ae4e7533275017ec, []int{37} } func (m *EventList) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_EventList.Unmarshal(m, b) @@ -1947,7 +1978,7 @@ func (m *ConsensusInfo) Reset() { *m = ConsensusInfo{} } func (m *ConsensusInfo) String() string { return proto.CompactTextString(m) } func (*ConsensusInfo) ProtoMessage() {} func (*ConsensusInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_rpc_0c5cc25d52d67e33, []int{37} + return fileDescriptor_rpc_ae4e7533275017ec, []int{38} } func (m *ConsensusInfo) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ConsensusInfo.Unmarshal(m, b) @@ -1992,6 +2023,7 @@ func init() { proto.RegisterType((*BlockchainStatus)(nil), "types.BlockchainStatus") proto.RegisterType((*ChainId)(nil), "types.ChainId") proto.RegisterType((*ChainInfo)(nil), "types.ChainInfo") + proto.RegisterType((*ChainStats)(nil), "types.ChainStats") proto.RegisterType((*Input)(nil), "types.Input") proto.RegisterType((*Output)(nil), "types.Output") proto.RegisterType((*Empty)(nil), "types.Empty") @@ -2054,6 +2086,8 @@ type AergoRPCServiceClient interface { Blockchain(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*BlockchainStatus, error) // Returns current blockchain's basic information GetChainInfo(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ChainInfo, error) + // Returns current chain statistics + ChainStat(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ChainStats, error) // Returns list of Blocks without body according to request ListBlockHeaders(ctx context.Context, in *ListParams, opts ...grpc.CallOption) (*BlockHeaderList, error) // Returns list of block metadata (hash, header, and number of transactions) according to request @@ -2168,6 +2202,15 @@ func (c *aergoRPCServiceClient) GetChainInfo(ctx context.Context, in *Empty, opt return out, nil } +func (c *aergoRPCServiceClient) ChainStat(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ChainStats, error) { + out := new(ChainStats) + err := c.cc.Invoke(ctx, "/types.AergoRPCService/ChainStat", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *aergoRPCServiceClient) ListBlockHeaders(ctx context.Context, in *ListParams, opts ...grpc.CallOption) (*BlockHeaderList, error) { out := new(BlockHeaderList) err := c.cc.Invoke(ctx, "/types.AergoRPCService/ListBlockHeaders", in, out, opts...) @@ -2553,6 +2596,8 @@ type AergoRPCServiceServer interface { Blockchain(context.Context, *Empty) (*BlockchainStatus, error) // Returns current blockchain's basic information GetChainInfo(context.Context, *Empty) (*ChainInfo, error) + // Returns current chain statistics + ChainStat(context.Context, *Empty) (*ChainStats, error) // Returns list of Blocks without body according to request ListBlockHeaders(context.Context, *ListParams) (*BlockHeaderList, error) // Returns list of block metadata (hash, header, and number of transactions) according to request @@ -2699,6 +2744,24 @@ func _AergoRPCService_GetChainInfo_Handler(srv interface{}, ctx context.Context, return interceptor(ctx, in, info, handler) } +func _AergoRPCService_ChainStat_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AergoRPCServiceServer).ChainStat(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/types.AergoRPCService/ChainStat", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AergoRPCServiceServer).ChainStat(ctx, req.(*Empty)) + } + return interceptor(ctx, in, info, handler) +} + func _AergoRPCService_ListBlockHeaders_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListParams) if err := dec(in); err != nil { @@ -3340,6 +3403,10 @@ var _AergoRPCService_serviceDesc = grpc.ServiceDesc{ MethodName: "GetChainInfo", Handler: _AergoRPCService_GetChainInfo_Handler, }, + { + MethodName: "ChainStat", + Handler: _AergoRPCService_ChainStat_Handler, + }, { MethodName: "ListBlockHeaders", Handler: _AergoRPCService_ListBlockHeaders_Handler, @@ -3485,155 +3552,156 @@ var _AergoRPCService_serviceDesc = grpc.ServiceDesc{ Metadata: "rpc.proto", } -func init() { proto.RegisterFile("rpc.proto", fileDescriptor_rpc_0c5cc25d52d67e33) } - -var fileDescriptor_rpc_0c5cc25d52d67e33 = []byte{ - // 2342 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x58, 0x6d, 0x73, 0x1b, 0xb7, - 0xf1, 0x27, 0x29, 0x91, 0x22, 0x97, 0xa4, 0x74, 0x42, 0x14, 0x5b, 0x7f, 0xfe, 0x6d, 0x47, 0x45, - 0x53, 0x47, 0x71, 0x6d, 0xc5, 0x96, 0xeb, 0xd4, 0xcd, 0xb4, 0x4d, 0x29, 0x86, 0xb2, 0x38, 0x91, - 0x29, 0x15, 0xa4, 0x5d, 0xa5, 0x2f, 0xca, 0x9e, 0x78, 0xa0, 0x78, 0x23, 0xde, 0x1d, 0x73, 0x07, - 0xea, 0x21, 0x6f, 0xfb, 0x01, 0xfa, 0xa2, 0xdf, 0xab, 0x33, 0xed, 0x27, 0xea, 0x60, 0x01, 0xdc, - 0x03, 0x75, 0xee, 0x8c, 0xfb, 0x8a, 0xb7, 0x8b, 0x7d, 0xc2, 0xee, 0x62, 0xf1, 0x03, 0xa1, 0x16, - 0xce, 0xc7, 0x7b, 0xf3, 0x30, 0x10, 0x01, 0x29, 0x8b, 0xdb, 0x39, 0x8f, 0x5a, 0xd6, 0xf9, 0x2c, - 0x18, 0x5f, 0x8e, 0xa7, 0xb6, 0xeb, 0xab, 0x85, 0x56, 0xd3, 0x1e, 0x8f, 0x83, 0x85, 0x2f, 0x34, - 0x09, 0x7e, 0xe0, 0x70, 0xfd, 0x5d, 0x9b, 0xef, 0xcf, 0xf5, 0x67, 0xc3, 0xe3, 0x22, 0x74, 0xb5, - 0x31, 0xfa, 0xcf, 0x22, 0x58, 0x07, 0xb1, 0xa1, 0x81, 0xb0, 0xc5, 0x22, 0x22, 0x8f, 0x61, 0xe3, - 0x9c, 0x47, 0x62, 0x84, 0x1e, 0x46, 0x53, 0x3b, 0x9a, 0x6e, 0x17, 0x77, 0x8a, 0xbb, 0x0d, 0xd6, - 0x94, 0x6c, 0x14, 0x3f, 0xb2, 0xa3, 0x29, 0xf9, 0x0c, 0xea, 0x28, 0x37, 0xe5, 0xee, 0xc5, 0x54, - 0x6c, 0x97, 0x76, 0x8a, 0xbb, 0xab, 0x0c, 0x24, 0xeb, 0x08, 0x39, 0xe4, 0x17, 0xb0, 0x3e, 0x0e, - 0xfc, 0x88, 0xfb, 0xd1, 0x22, 0x1a, 0xb9, 0xfe, 0x24, 0xd8, 0x5e, 0xd9, 0x29, 0xee, 0xd6, 0x58, - 0x33, 0xe6, 0xf6, 0xfc, 0x49, 0x40, 0x7e, 0x09, 0x04, 0xed, 0x60, 0x0c, 0x23, 0xd7, 0x51, 0x2e, - 0x57, 0xd1, 0x25, 0x46, 0xd2, 0x91, 0x0b, 0x3d, 0x07, 0x9d, 0x3e, 0x04, 0x50, 0x72, 0x91, 0xb0, - 0xc5, 0x76, 0x19, 0xed, 0xd5, 0xe2, 0xe8, 0x69, 0x00, 0x6b, 0x5a, 0x9a, 0x6c, 0x41, 0xd9, 0xb3, - 0x2f, 0xdc, 0x31, 0x06, 0x5f, 0x63, 0x8a, 0x20, 0xf7, 0xa0, 0x32, 0x5f, 0x9c, 0xcf, 0xdc, 0x31, - 0xc6, 0x5b, 0x65, 0x9a, 0x22, 0xdb, 0xb0, 0xe6, 0xd9, 0xae, 0xef, 0x73, 0x81, 0x41, 0x56, 0x99, - 0x21, 0xc9, 0x03, 0xa8, 0xc5, 0xf1, 0x62, 0x54, 0xd2, 0xa1, 0x61, 0xd0, 0xbf, 0x97, 0xa0, 0xa6, - 0x3c, 0xca, 0xad, 0x3c, 0x82, 0x92, 0xeb, 0xa0, 0xc3, 0xfa, 0xfe, 0xfa, 0x1e, 0x56, 0x6a, 0x4f, - 0xc7, 0xc3, 0x4a, 0xae, 0x43, 0x5a, 0x50, 0x3d, 0x9f, 0xf7, 0x17, 0xde, 0x39, 0x0f, 0xd1, 0x7f, - 0x93, 0xc5, 0x34, 0xa1, 0xd0, 0xf0, 0xec, 0x1b, 0x4c, 0x7a, 0xe4, 0xfe, 0xc4, 0x31, 0x8c, 0x55, - 0x96, 0xe1, 0xc9, 0x58, 0x3c, 0xfb, 0x46, 0x04, 0x97, 0xdc, 0x8f, 0x74, 0x86, 0x12, 0x06, 0x79, - 0x0c, 0xeb, 0x91, 0xb0, 0x2f, 0x5d, 0xff, 0xc2, 0x73, 0x7d, 0xd7, 0x5b, 0x78, 0x98, 0x9f, 0x06, - 0x5b, 0xe2, 0x4a, 0x4f, 0x22, 0x10, 0xf6, 0x4c, 0xb3, 0xb7, 0x2b, 0x28, 0x95, 0xe1, 0xc9, 0x48, - 0x2f, 0xec, 0x68, 0x1e, 0xba, 0x63, 0xbe, 0xbd, 0x86, 0xeb, 0x31, 0x2d, 0xa3, 0xf0, 0x6d, 0x8f, - 0xab, 0xc5, 0xaa, 0x8a, 0x22, 0x66, 0xd0, 0x31, 0x94, 0x7b, 0xfe, 0x7c, 0x21, 0x08, 0x81, 0xd5, - 0x54, 0xf3, 0xe0, 0xb7, 0x4c, 0xb3, 0xed, 0x38, 0x21, 0x8f, 0xa2, 0xed, 0xd2, 0xce, 0xca, 0x6e, - 0x83, 0x19, 0x52, 0x96, 0xeb, 0xca, 0x9e, 0x2d, 0xd4, 0xbe, 0x1b, 0x4c, 0x11, 0xb2, 0x5c, 0xd1, - 0x38, 0x74, 0xe7, 0x42, 0xef, 0x56, 0x53, 0x74, 0x02, 0x95, 0x93, 0x85, 0x90, 0x5e, 0xb6, 0xa0, - 0xec, 0xfa, 0x0e, 0xbf, 0x41, 0x37, 0x4d, 0xa6, 0x88, 0xac, 0x9f, 0xe2, 0xff, 0xee, 0x67, 0x0d, - 0xca, 0x5d, 0x6f, 0x2e, 0x6e, 0xe9, 0xcf, 0xa1, 0x3e, 0x70, 0xfd, 0x8b, 0x19, 0x3f, 0xb8, 0x15, - 0x3c, 0x65, 0xa5, 0x98, 0xb2, 0x42, 0x1f, 0xc3, 0x7a, 0x5b, 0x1d, 0xc2, 0xf6, 0xb2, 0xb7, 0x8c, - 0xdc, 0x5f, 0x12, 0x39, 0xdf, 0x61, 0x41, 0x20, 0x64, 0xbc, 0x9a, 0xa3, 0x25, 0xd7, 0xf4, 0x69, - 0x96, 0x59, 0x94, 0x12, 0x7a, 0x1b, 0xab, 0xa1, 0x94, 0x7e, 0x04, 0xd0, 0x09, 0xbc, 0xb9, 0xf4, - 0xc0, 0x1d, 0xdd, 0xaf, 0x30, 0x8e, 0x39, 0xf4, 0x5f, 0x45, 0x58, 0x3d, 0xe5, 0x3c, 0x24, 0x4f, - 0x93, 0x34, 0xa8, 0xa6, 0x24, 0xba, 0x29, 0xe5, 0xaa, 0x8e, 0x31, 0x49, 0xcd, 0x4b, 0xa8, 0xc9, - 0xe3, 0x86, 0xed, 0x86, 0xfe, 0xea, 0xfb, 0x9f, 0x6a, 0xf9, 0x3e, 0xbf, 0xc6, 0x83, 0xdf, 0x0f, - 0x84, 0x3b, 0xe6, 0x2c, 0x91, 0x93, 0x3b, 0x94, 0x47, 0x51, 0xe5, 0xb3, 0xcc, 0x14, 0x21, 0xf3, - 0x39, 0x75, 0x1d, 0x87, 0xfb, 0x98, 0xcf, 0x2a, 0xd3, 0x94, 0x6c, 0x9d, 0x99, 0x1d, 0x4d, 0x3b, - 0x53, 0x3e, 0xbe, 0xc4, 0xee, 0x5c, 0x61, 0x09, 0x43, 0x36, 0x5d, 0xc4, 0x67, 0x93, 0x39, 0xe7, - 0x21, 0x36, 0x65, 0x95, 0xc5, 0x34, 0x7d, 0x06, 0x55, 0x19, 0xf4, 0xb1, 0x1b, 0x09, 0xf2, 0x33, - 0x28, 0x4b, 0x9e, 0xdc, 0xd4, 0xca, 0x6e, 0x7d, 0xbf, 0x9e, 0xda, 0x14, 0x53, 0x2b, 0xf4, 0x0a, - 0x40, 0x8a, 0x9e, 0xda, 0xa1, 0xed, 0x45, 0xb9, 0xad, 0x28, 0x43, 0x4c, 0x4f, 0x2e, 0x4d, 0x49, - 0xd9, 0xf8, 0xfc, 0x35, 0x19, 0x7e, 0x4b, 0xd9, 0x60, 0x32, 0x89, 0xb8, 0x6a, 0x8f, 0x26, 0xd3, - 0x14, 0xb1, 0x60, 0xc5, 0x8e, 0xc6, 0xb8, 0x91, 0x2a, 0x93, 0x9f, 0xf4, 0x35, 0xc0, 0xa9, 0x7d, - 0xc1, 0xb5, 0xdf, 0x44, 0xaf, 0x98, 0xd1, 0x33, 0x3e, 0x4a, 0x89, 0x0f, 0x7a, 0x03, 0xeb, 0x98, - 0xe2, 0x83, 0xc0, 0xb9, 0x95, 0x26, 0x70, 0x82, 0xe1, 0x99, 0x34, 0xad, 0x8d, 0x44, 0xca, 0x66, - 0x29, 0xd7, 0x66, 0x3a, 0xee, 0xcf, 0x61, 0xf5, 0x3c, 0x70, 0x6e, 0x31, 0xea, 0xfa, 0xbe, 0xa5, - 0xf3, 0x14, 0xbb, 0x61, 0xb8, 0x4a, 0xff, 0x0a, 0x1b, 0x29, 0xcf, 0x18, 0x38, 0x85, 0x86, 0x4c, - 0x52, 0x10, 0xfa, 0x6a, 0x58, 0xa9, 0xc4, 0x65, 0x78, 0xe4, 0x4b, 0xa8, 0xcc, 0xed, 0x0b, 0x39, - 0x40, 0x54, 0xaf, 0x6c, 0x9a, 0x32, 0xc4, 0xfb, 0x67, 0x5a, 0x80, 0xfe, 0x5a, 0x7b, 0x38, 0xe2, - 0xb6, 0xa3, 0x6b, 0xf8, 0x39, 0x54, 0xd4, 0x5c, 0xd3, 0x45, 0x6c, 0xa4, 0x83, 0x63, 0x7a, 0x8d, - 0xba, 0xd0, 0x44, 0xc6, 0x5b, 0x2e, 0x6c, 0xc7, 0x16, 0x76, 0x6e, 0x25, 0x9f, 0xc8, 0x4a, 0x4a, - 0xc3, 0x3a, 0x10, 0x92, 0x36, 0xa5, 0x5c, 0x32, 0x2d, 0x21, 0x0f, 0x9a, 0xb8, 0x51, 0x07, 0x4d, - 0x35, 0xac, 0x21, 0x69, 0x1b, 0x36, 0x33, 0xae, 0x30, 0xca, 0xa7, 0x4b, 0x51, 0x6e, 0xa5, 0x4d, - 0x1b, 0xc9, 0x38, 0x5a, 0x0e, 0x8d, 0x4e, 0xe0, 0x79, 0xae, 0x60, 0x3c, 0x5a, 0xcc, 0xf2, 0x27, - 0xe0, 0x97, 0x50, 0xe6, 0x61, 0x18, 0xa8, 0x58, 0xd7, 0xf7, 0x3f, 0x31, 0xb7, 0x04, 0xea, 0xa9, - 0x1b, 0x98, 0x29, 0x09, 0x59, 0x69, 0x87, 0x0b, 0xdb, 0x9d, 0xe9, 0x7b, 0x53, 0x53, 0xb4, 0x0d, - 0x56, 0xda, 0x0d, 0x06, 0xfa, 0x0c, 0xd6, 0x42, 0xa4, 0x4c, 0xa4, 0x59, 0xc3, 0x4a, 0x92, 0x19, - 0x19, 0x3a, 0x84, 0xc6, 0x7b, 0x1e, 0xba, 0x93, 0x5b, 0x1d, 0xe9, 0xff, 0x41, 0x49, 0xdc, 0xe8, - 0x19, 0x51, 0xd3, 0x9a, 0xc3, 0x1b, 0x56, 0x12, 0x37, 0x1f, 0x0a, 0x58, 0xa9, 0x67, 0x02, 0xa6, - 0x43, 0x79, 0x46, 0xc3, 0x28, 0xf0, 0xed, 0x99, 0x9c, 0x51, 0x73, 0x3b, 0x8a, 0xe6, 0xd3, 0xd0, - 0x8e, 0xb8, 0xbe, 0x83, 0x53, 0x1c, 0xb2, 0x0b, 0x66, 0xc4, 0xe9, 0xaa, 0x99, 0xfb, 0x52, 0xcf, - 0xc1, 0x78, 0x02, 0xd2, 0x29, 0x34, 0x7a, 0xde, 0x3c, 0x08, 0xc5, 0x61, 0x10, 0x7a, 0xb6, 0xec, - 0x9c, 0x95, 0x6b, 0x77, 0xb2, 0x34, 0xd0, 0x52, 0xc3, 0x99, 0xc9, 0x65, 0x59, 0xe8, 0x60, 0xe6, - 0x48, 0x87, 0x68, 0xbf, 0xc6, 0x0c, 0x29, 0x57, 0x7c, 0x7e, 0x8d, 0x2b, 0x2a, 0xaf, 0x86, 0xa4, - 0xaf, 0x60, 0x6d, 0xa0, 0xef, 0xbf, 0x7b, 0x50, 0xb1, 0xbd, 0xd4, 0x3c, 0xd6, 0x94, 0x2c, 0xe9, - 0xf5, 0x94, 0xfb, 0x7a, 0x66, 0xe0, 0x37, 0xfd, 0x2d, 0xac, 0xbe, 0x0f, 0x04, 0xde, 0x8b, 0x63, - 0xdb, 0x77, 0x5c, 0x47, 0x8e, 0x43, 0xa5, 0x96, 0x30, 0x52, 0x16, 0x4b, 0x69, 0x8b, 0x74, 0x1f, - 0x40, 0x6a, 0xeb, 0x83, 0xb7, 0x1e, 0x23, 0x88, 0x1a, 0x22, 0x86, 0x2d, 0x28, 0x27, 0x49, 0x6a, - 0x32, 0x45, 0x50, 0x07, 0x36, 0x74, 0x9a, 0xa4, 0x2a, 0x42, 0x8f, 0x5d, 0x58, 0x33, 0xf7, 0x79, - 0x16, 0x7f, 0xe8, 0x1d, 0x31, 0xb3, 0x4c, 0xbe, 0x80, 0xca, 0x55, 0x20, 0xd4, 0xb9, 0x95, 0x9d, - 0xb2, 0x61, 0x2a, 0xaa, 0x4d, 0x31, 0xbd, 0x4c, 0xbf, 0x81, 0x6a, 0x6c, 0x5e, 0xc5, 0x55, 0x8a, - 0xe3, 0x7a, 0x04, 0x10, 0x6f, 0x4d, 0xe6, 0x71, 0x45, 0x96, 0x37, 0xe1, 0xd0, 0xdf, 0x29, 0x5d, - 0x33, 0xae, 0xaf, 0x02, 0x29, 0x96, 0x1d, 0xd7, 0x72, 0x9d, 0xa9, 0x95, 0x65, 0xf3, 0xb4, 0x0d, - 0x6b, 0xfd, 0xc0, 0xe1, 0x8c, 0xff, 0x88, 0x27, 0xd6, 0xf5, 0x78, 0xb0, 0x88, 0xaf, 0x46, 0x4d, - 0x2a, 0x64, 0xe6, 0xcd, 0x03, 0x9f, 0xc7, 0x49, 0x4d, 0x18, 0xb4, 0x05, 0xab, 0x7d, 0xdb, 0xe3, - 0xb2, 0x62, 0x12, 0x9c, 0xe8, 0x9c, 0xe2, 0x37, 0x1d, 0x43, 0x55, 0xae, 0xe1, 0xce, 0x3e, 0x4b, - 0xad, 0x27, 0xc1, 0xc9, 0x65, 0x25, 0x2c, 0x4b, 0x10, 0x5c, 0xfb, 0x7a, 0xba, 0x34, 0x98, 0x22, - 0xc8, 0x0e, 0xd4, 0x1d, 0x1e, 0x09, 0xd7, 0xb7, 0x85, 0x1b, 0xf8, 0x1a, 0x4d, 0xa4, 0x59, 0xb4, - 0x0b, 0x75, 0x79, 0x23, 0x45, 0xba, 0xb2, 0x2d, 0xa8, 0xfa, 0xc1, 0x91, 0xba, 0x14, 0x8b, 0xea, - 0x72, 0x33, 0x34, 0x5e, 0x7c, 0xd3, 0xe0, 0x7a, 0xc0, 0x67, 0x13, 0x8d, 0x4b, 0x63, 0x9a, 0x3e, - 0x84, 0xda, 0xf7, 0xdc, 0xcc, 0x65, 0x0b, 0x56, 0x2e, 0xf9, 0x2d, 0x26, 0xb2, 0xc6, 0xe4, 0x27, - 0xfd, 0x5b, 0x09, 0x60, 0xc0, 0xc3, 0x2b, 0x1e, 0xe2, 0x6e, 0x5e, 0x41, 0x25, 0xc2, 0x33, 0xa9, - 0x93, 0xfd, 0xd0, 0x74, 0x41, 0x2c, 0xb2, 0xa7, 0xce, 0x6c, 0xd7, 0x17, 0xe1, 0x2d, 0xd3, 0xc2, - 0x52, 0x6d, 0x1c, 0xf8, 0x13, 0xd7, 0xf4, 0x44, 0x8e, 0x5a, 0x07, 0xd7, 0xb5, 0x9a, 0x12, 0x6e, - 0xfd, 0x06, 0xea, 0x29, 0x6b, 0x49, 0x74, 0x45, 0x1d, 0x5d, 0x82, 0x7f, 0x54, 0x69, 0x15, 0xf1, - 0x4d, 0xe9, 0x75, 0xb1, 0x75, 0x0c, 0xf5, 0x94, 0xc5, 0x1c, 0xd5, 0x2f, 0xd2, 0xaa, 0xc9, 0xed, - 0xa2, 0x94, 0x7a, 0x82, 0x7b, 0x29, 0x6b, 0xf4, 0x27, 0x89, 0x88, 0xcc, 0x02, 0xd9, 0x87, 0xf2, - 0x3c, 0x0c, 0xe6, 0x91, 0xde, 0xcc, 0x83, 0x3b, 0xaa, 0x7b, 0xa7, 0x72, 0x59, 0xed, 0x45, 0x89, - 0xb6, 0xe4, 0xc5, 0x1d, 0x33, 0x3f, 0x66, 0x27, 0xf4, 0x05, 0xd4, 0xba, 0x57, 0xdc, 0x17, 0xe6, - 0x5a, 0xe3, 0x92, 0x58, 0xbe, 0xd6, 0x50, 0x82, 0xe9, 0x35, 0xda, 0x83, 0x66, 0x27, 0xf3, 0x06, - 0x22, 0xb0, 0x2a, 0xe5, 0x4c, 0x93, 0xca, 0x6f, 0xc9, 0xc3, 0x47, 0x93, 0x72, 0x88, 0xdf, 0x32, - 0xae, 0xf3, 0xb9, 0x39, 0x6f, 0xf2, 0xf3, 0xc9, 0xbf, 0x8b, 0xe6, 0xd2, 0xd1, 0xcf, 0xb7, 0x1a, - 0x94, 0x87, 0x67, 0xa3, 0x93, 0xef, 0xad, 0x02, 0xd9, 0x02, 0x6b, 0x78, 0x36, 0xea, 0x9f, 0xf4, - 0x3b, 0xdd, 0xd1, 0xf0, 0xe4, 0x64, 0x74, 0x7c, 0xf2, 0x27, 0xab, 0x48, 0x3e, 0x85, 0xcd, 0xe1, - 0xd9, 0xa8, 0x7d, 0xcc, 0xba, 0xed, 0xef, 0x7e, 0x18, 0x75, 0xcf, 0x7a, 0x83, 0xe1, 0xc0, 0x2a, - 0x91, 0x4f, 0x60, 0x63, 0x78, 0x36, 0xea, 0xf5, 0xdf, 0xb7, 0x8f, 0x7b, 0xdf, 0x8d, 0x8e, 0xda, - 0x83, 0x23, 0x6b, 0x65, 0x89, 0x39, 0xe8, 0xbd, 0xe9, 0x5b, 0xab, 0xda, 0x80, 0x61, 0x1e, 0x9e, - 0xb0, 0xb7, 0xed, 0xa1, 0x55, 0x26, 0xff, 0x0f, 0xf7, 0x91, 0x3d, 0x78, 0x77, 0x78, 0xd8, 0xeb, - 0xf4, 0xba, 0xfd, 0xe1, 0xe8, 0xa0, 0x7d, 0xdc, 0xee, 0x77, 0xba, 0x56, 0x45, 0xeb, 0x1c, 0xb5, - 0x07, 0xa3, 0x41, 0xfb, 0x6d, 0x57, 0xc5, 0x64, 0xad, 0xc5, 0xa6, 0x86, 0x5d, 0xd6, 0x6f, 0x1f, - 0x8f, 0xba, 0x8c, 0x9d, 0x30, 0xab, 0xf6, 0x64, 0x62, 0xae, 0x27, 0xbd, 0xa7, 0x2d, 0xb0, 0xde, - 0x77, 0x59, 0xef, 0xf0, 0x87, 0xd1, 0x60, 0xd8, 0x1e, 0xbe, 0x1b, 0xa8, 0xed, 0xed, 0xc0, 0x83, - 0x2c, 0x57, 0xc6, 0x37, 0xea, 0x9f, 0x0c, 0x47, 0x6f, 0xdb, 0xc3, 0xce, 0x91, 0x55, 0x24, 0x8f, - 0xa0, 0x95, 0x95, 0xc8, 0x6c, 0xaf, 0xb4, 0xff, 0x0f, 0x0b, 0x36, 0xda, 0x3c, 0xbc, 0x08, 0xd8, - 0x69, 0x47, 0xb6, 0xba, 0x7c, 0xdd, 0xbc, 0x80, 0x9a, 0x1c, 0x3d, 0x03, 0xc4, 0xb1, 0x66, 0x88, - 0xea, 0x61, 0xd4, 0xca, 0xb9, 0x6e, 0x68, 0x81, 0xbc, 0x80, 0xca, 0x5b, 0x7c, 0x56, 0x13, 0x83, - 0x97, 0x15, 0x19, 0x31, 0xfe, 0xe3, 0x82, 0x47, 0xa2, 0xb5, 0x9e, 0x65, 0xd3, 0x02, 0x79, 0x05, - 0x90, 0x3c, 0xbc, 0x49, 0xdc, 0x25, 0xf2, 0xad, 0xd1, 0xba, 0x9f, 0x06, 0x19, 0xa9, 0x97, 0x39, - 0x2d, 0x90, 0xe7, 0xd0, 0x78, 0xc3, 0x45, 0xf2, 0xe0, 0xcc, 0x2a, 0x5a, 0x99, 0x27, 0xa7, 0x3f, - 0x09, 0x68, 0x81, 0x7c, 0x0b, 0x96, 0x6c, 0xcc, 0x14, 0x16, 0x8a, 0x88, 0x39, 0x4b, 0x09, 0x42, - 0x6e, 0xdd, 0xbb, 0x8b, 0x99, 0xe4, 0x2a, 0x2d, 0x90, 0x03, 0xd8, 0x8c, 0x0d, 0xc4, 0x30, 0x2c, - 0xc7, 0xc2, 0x76, 0x1e, 0x34, 0xd2, 0x36, 0x5e, 0xc0, 0x46, 0x6c, 0x63, 0x20, 0x42, 0x6e, 0x7b, - 0x4b, 0x91, 0x67, 0xd0, 0x1f, 0x2d, 0x3c, 0x2f, 0x92, 0x36, 0xdc, 0xbf, 0xe3, 0x36, 0x57, 0x35, - 0x17, 0x92, 0xa1, 0x89, 0x3d, 0xa8, 0xbe, 0xe1, 0xca, 0x02, 0xc9, 0x29, 0xdc, 0xb2, 0x53, 0xf2, - 0x7b, 0xb0, 0x8c, 0x7c, 0x82, 0x37, 0x73, 0xf4, 0x3e, 0xe0, 0x91, 0x7c, 0x8b, 0xc5, 0x89, 0xa1, - 0x34, 0xb9, 0xb7, 0x8c, 0xb7, 0x75, 0xa6, 0x3e, 0xbd, 0xcb, 0xbf, 0xe0, 0x0e, 0x2d, 0x90, 0x5d, - 0x28, 0xbf, 0xe1, 0x62, 0x78, 0x96, 0xeb, 0x35, 0x81, 0x65, 0xb4, 0x40, 0x7e, 0x05, 0x60, 0x5c, - 0x7d, 0x40, 0xdc, 0x8a, 0xc5, 0x7b, 0xbe, 0xd9, 0xe0, 0x3e, 0x6a, 0x31, 0x3e, 0xe6, 0xee, 0x5c, - 0xe4, 0x6a, 0x99, 0x46, 0xd5, 0x32, 0xb4, 0x20, 0xc1, 0xf5, 0x1b, 0x2e, 0xda, 0x07, 0xbd, 0x5c, - 0x79, 0x30, 0xa0, 0xed, 0xa0, 0xa7, 0x64, 0x07, 0xdc, 0x77, 0x86, 0x67, 0x24, 0x09, 0xb6, 0x95, - 0x07, 0x44, 0xa9, 0x3c, 0xbc, 0x95, 0x81, 0x7b, 0xe1, 0x67, 0x65, 0x33, 0x7b, 0x7c, 0x0a, 0x55, - 0x35, 0x04, 0xf2, 0xed, 0xa5, 0xf1, 0x2b, 0x66, 0xa4, 0xaa, 0x3c, 0x0c, 0xcf, 0x48, 0x33, 0x96, - 0x96, 0x2d, 0x14, 0x9f, 0xa7, 0x65, 0xd0, 0x4c, 0x0b, 0xba, 0x45, 0xd4, 0x59, 0xff, 0x6f, 0x2d, - 0x82, 0x12, 0xb4, 0x40, 0xfe, 0x80, 0x2d, 0x82, 0x54, 0xdb, 0x77, 0x4e, 0xc3, 0x20, 0x98, 0xc4, - 0x67, 0x3e, 0xfb, 0xa4, 0x8f, 0xe3, 0xd4, 0x6c, 0x94, 0xc5, 0x1a, 0x34, 0x3b, 0x21, 0x97, 0xfa, - 0xfa, 0x81, 0xbf, 0x11, 0xbf, 0x5e, 0x15, 0x72, 0x6e, 0x2d, 0x01, 0x61, 0x3c, 0x3e, 0x75, 0x59, - 0x03, 0x45, 0x47, 0x4b, 0xfd, 0x4f, 0xb2, 0xe2, 0x7a, 0x63, 0xcf, 0xa1, 0x7e, 0x1c, 0x8c, 0x2f, - 0x3f, 0xc2, 0xc9, 0x3e, 0x34, 0xdf, 0xf9, 0xb3, 0x8f, 0xd3, 0xf9, 0x1a, 0x9a, 0x0a, 0x9a, 0x1b, - 0x1d, 0xb3, 0xe9, 0x34, 0x60, 0xcf, 0xd7, 0xeb, 0xde, 0xa4, 0xf5, 0xee, 0xf8, 0xca, 0x1f, 0xb4, - 0x2f, 0xa1, 0xf9, 0xc7, 0x05, 0x0f, 0x6f, 0x3b, 0x81, 0x2f, 0x42, 0x7b, 0x2c, 0xe2, 0x54, 0x20, - 0xf7, 0x03, 0x4a, 0x6d, 0x20, 0x19, 0x25, 0x55, 0xed, 0xcd, 0x74, 0x65, 0x95, 0xfa, 0xbd, 0x3b, - 0x2c, 0x53, 0xb4, 0x17, 0xd8, 0x26, 0x88, 0xe6, 0x48, 0xfa, 0x2f, 0x14, 0x8d, 0xed, 0x5a, 0x1b, - 0x29, 0x5e, 0x5c, 0x00, 0xa9, 0xf2, 0x1e, 0xd1, 0xed, 0x66, 0x0a, 0xf1, 0x2e, 0x69, 0x18, 0x90, - 0x8c, 0x83, 0x76, 0x23, 0xa9, 0xb2, 0x52, 0x5c, 0x6e, 0x2d, 0xf5, 0x47, 0x4d, 0x1c, 0xe8, 0xd2, - 0x1b, 0x40, 0x5d, 0x2b, 0xaa, 0x3f, 0x11, 0xe9, 0x7f, 0x40, 0x7d, 0xe9, 0x65, 0x40, 0x0b, 0xe4, - 0x19, 0x36, 0x58, 0x0c, 0x89, 0xd3, 0x20, 0x38, 0x8e, 0xd4, 0xac, 0x62, 0xf9, 0x70, 0x9c, 0x23, - 0xa6, 0xd1, 0x33, 0xd9, 0x6c, 0xf1, 0xd0, 0x9d, 0x09, 0x05, 0x18, 0x5b, 0x19, 0xe8, 0x83, 0x03, - 0xf9, 0xa5, 0xfa, 0x53, 0x06, 0x19, 0x51, 0x9e, 0x8a, 0x95, 0x56, 0xd1, 0x69, 0xf9, 0x1a, 0x9a, - 0x72, 0x4b, 0x09, 0xc4, 0x35, 0x42, 0x31, 0x2a, 0x6e, 0x6d, 0xde, 0x41, 0xab, 0xb4, 0x40, 0x5e, - 0xe3, 0x51, 0xcd, 0xc2, 0xac, 0xfc, 0x9b, 0x23, 0x23, 0x43, 0x0b, 0x07, 0x3b, 0x7f, 0x7e, 0x74, - 0xe1, 0x8a, 0xe9, 0xe2, 0x7c, 0x6f, 0x1c, 0x78, 0x5f, 0xd9, 0x12, 0x1f, 0xb8, 0x81, 0xfa, 0xfd, - 0x0a, 0x35, 0xce, 0x2b, 0xf8, 0xf7, 0xf9, 0xcb, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x97, 0xff, - 0x17, 0x0a, 0x98, 0x17, 0x00, 0x00, +func init() { proto.RegisterFile("rpc.proto", fileDescriptor_rpc_ae4e7533275017ec) } + +var fileDescriptor_rpc_ae4e7533275017ec = []byte{ + // 2357 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x38, 0xeb, 0x76, 0x1a, 0xc9, + 0xd1, 0x80, 0x04, 0x82, 0x02, 0xa4, 0x51, 0xaf, 0xd6, 0xd6, 0xc7, 0xe7, 0xf5, 0x2a, 0x1d, 0xc7, + 0xab, 0x75, 0x6c, 0xad, 0x2d, 0xc7, 0x1b, 0x67, 0x4f, 0x92, 0x0d, 0x62, 0x91, 0xc5, 0x59, 0x19, + 0x29, 0x0d, 0x76, 0xb4, 0xf9, 0x11, 0x32, 0x62, 0x1a, 0x31, 0x47, 0xcc, 0x0c, 0x3b, 0xd3, 0xe8, + 0xb2, 0x7f, 0xf3, 0x00, 0x79, 0x94, 0x3c, 0x44, 0x9e, 0x20, 0x79, 0xa2, 0x9c, 0xea, 0xcb, 0x5c, + 0xd0, 0x38, 0xe7, 0x38, 0xbf, 0x98, 0xba, 0x57, 0x57, 0x55, 0x57, 0x55, 0x03, 0xb5, 0x70, 0x3e, + 0xde, 0x9b, 0x87, 0x81, 0x08, 0x48, 0x59, 0xdc, 0xce, 0x79, 0xd4, 0xb2, 0xce, 0x67, 0xc1, 0xf8, + 0x72, 0x3c, 0xb5, 0x5d, 0x5f, 0x11, 0x5a, 0x4d, 0x7b, 0x3c, 0x0e, 0x16, 0xbe, 0xd0, 0x20, 0xf8, + 0x81, 0xc3, 0xf5, 0x77, 0x6d, 0xbe, 0x3f, 0xd7, 0x9f, 0x0d, 0x8f, 0x8b, 0xd0, 0xd5, 0xca, 0xe8, + 0x3f, 0x8a, 0x60, 0x1d, 0xc4, 0x8a, 0x06, 0xc2, 0x16, 0x8b, 0x88, 0x3c, 0x86, 0x8d, 0x73, 0x1e, + 0x89, 0x91, 0xb4, 0x30, 0x9a, 0xda, 0xd1, 0x74, 0xbb, 0xb8, 0x53, 0xdc, 0x6d, 0xb0, 0x26, 0xa2, + 0x25, 0xfb, 0x91, 0x1d, 0x4d, 0xc9, 0xe7, 0x50, 0x97, 0x7c, 0x53, 0xee, 0x5e, 0x4c, 0xc5, 0x76, + 0x69, 0xa7, 0xb8, 0xbb, 0xca, 0x00, 0x51, 0x47, 0x12, 0x43, 0x7e, 0x01, 0xeb, 0xe3, 0xc0, 0x8f, + 0xb8, 0x1f, 0x2d, 0xa2, 0x91, 0xeb, 0x4f, 0x82, 0xed, 0x95, 0x9d, 0xe2, 0x6e, 0x8d, 0x35, 0x63, + 0x6c, 0xcf, 0x9f, 0x04, 0xe4, 0x97, 0x40, 0xa4, 0x1e, 0xe9, 0xc3, 0xc8, 0x75, 0x94, 0xc9, 0x55, + 0x69, 0x52, 0x7a, 0xd2, 0x41, 0x42, 0xcf, 0x41, 0xa3, 0x34, 0x80, 0x35, 0x0d, 0x92, 0x2d, 0x28, + 0x7b, 0xf6, 0x85, 0x3b, 0x96, 0xde, 0xd5, 0x98, 0x02, 0xc8, 0x3d, 0xa8, 0xcc, 0x17, 0xe7, 0x33, + 0x77, 0x2c, 0x1d, 0xaa, 0x32, 0x0d, 0x91, 0x6d, 0x58, 0xf3, 0x6c, 0xd7, 0xf7, 0xb9, 0x90, 0x5e, + 0x54, 0x99, 0x01, 0xc9, 0x03, 0xa8, 0xc5, 0x0e, 0x49, 0xb3, 0x35, 0x96, 0x20, 0xe8, 0xdf, 0x4b, + 0x50, 0x53, 0x16, 0xd1, 0xd7, 0x87, 0x50, 0x72, 0x1d, 0x69, 0xb0, 0xbe, 0xbf, 0xbe, 0x27, 0x53, + 0xb1, 0xa7, 0xfd, 0x61, 0x25, 0xd7, 0x21, 0x2d, 0xa8, 0x9e, 0xcf, 0xfb, 0x0b, 0xef, 0x9c, 0x87, + 0xd2, 0x7e, 0x93, 0xc5, 0x30, 0xa1, 0xd0, 0xf0, 0xec, 0x1b, 0x19, 0xd5, 0xc8, 0xfd, 0x89, 0x4b, + 0x37, 0x56, 0x59, 0x06, 0x87, 0xbe, 0x78, 0xf6, 0x8d, 0x08, 0x2e, 0xb9, 0x1f, 0xe9, 0x10, 0x24, + 0x08, 0xf2, 0x18, 0xd6, 0x23, 0x61, 0x5f, 0xba, 0xfe, 0x85, 0xe7, 0xfa, 0xae, 0xb7, 0xf0, 0xb6, + 0xcb, 0x92, 0x65, 0x09, 0x8b, 0x96, 0x44, 0x20, 0xec, 0x99, 0x46, 0x6f, 0x57, 0x24, 0x57, 0x06, + 0x87, 0x9e, 0x5e, 0xd8, 0xd1, 0x3c, 0x74, 0xc7, 0x7c, 0x7b, 0x4d, 0xd2, 0x63, 0x18, 0xbd, 0xf0, + 0x6d, 0x8f, 0x2b, 0x62, 0x55, 0x79, 0x11, 0x23, 0xe8, 0x23, 0x80, 0x8e, 0x29, 0x97, 0x08, 0xe3, + 0x1d, 0xf2, 0x79, 0x10, 0x0a, 0x9d, 0x06, 0x0d, 0xd1, 0x31, 0x94, 0x7b, 0xfe, 0x7c, 0x21, 0x08, + 0x81, 0xd5, 0x54, 0x0d, 0xc9, 0x6f, 0x4c, 0x86, 0xed, 0x38, 0x21, 0x8f, 0xa2, 0xed, 0xd2, 0xce, + 0xca, 0x6e, 0x83, 0x19, 0x10, 0x93, 0x7a, 0x65, 0xcf, 0x16, 0x2a, 0x3a, 0x0d, 0xa6, 0x00, 0x34, + 0x12, 0x8d, 0x43, 0x77, 0x2e, 0x74, 0x4c, 0x34, 0x44, 0x27, 0x50, 0x39, 0x59, 0x08, 0xb4, 0xb2, + 0x05, 0x65, 0xd7, 0x77, 0xf8, 0x8d, 0x34, 0xd3, 0x64, 0x0a, 0xc8, 0xda, 0x29, 0xfe, 0xef, 0x76, + 0xd6, 0xa0, 0xdc, 0xf5, 0xe6, 0xe2, 0x96, 0xfe, 0x1c, 0xea, 0x03, 0xd7, 0xbf, 0x98, 0xf1, 0x83, + 0x5b, 0xc1, 0x53, 0x5a, 0x8a, 0x29, 0x2d, 0xf4, 0x31, 0xac, 0xb7, 0xd5, 0x5d, 0x6c, 0x2f, 0x5b, + 0xcb, 0xf0, 0xfd, 0x25, 0xe1, 0xf3, 0x1d, 0x16, 0x04, 0x02, 0xfd, 0xd5, 0x18, 0xcd, 0xb9, 0xa6, + 0x2f, 0x35, 0x46, 0x11, 0x39, 0xf4, 0x31, 0x56, 0x43, 0xe4, 0x7e, 0x08, 0xd0, 0x09, 0xbc, 0x39, + 0x5a, 0xe0, 0x8e, 0xae, 0x6a, 0x18, 0xc7, 0x18, 0xfa, 0xaf, 0x22, 0xac, 0x9e, 0x72, 0x1e, 0x92, + 0xa7, 0x49, 0x18, 0x54, 0xe9, 0x12, 0x5d, 0xba, 0x48, 0xd5, 0x3e, 0x26, 0xa1, 0x79, 0x09, 0x35, + 0xbc, 0x75, 0xb2, 0x28, 0xa5, 0xbd, 0xfa, 0xfe, 0xa7, 0x9a, 0xbf, 0xcf, 0xaf, 0xe5, 0xfd, 0xef, + 0x07, 0xc2, 0x1d, 0x73, 0x96, 0xf0, 0xe1, 0x09, 0x23, 0x61, 0x0b, 0x15, 0xcf, 0x32, 0x53, 0x00, + 0xc6, 0x73, 0xea, 0x3a, 0x0e, 0xf7, 0x65, 0x3c, 0xab, 0x4c, 0x43, 0x58, 0x60, 0x33, 0x3b, 0x9a, + 0x76, 0xa6, 0x7c, 0x7c, 0x29, 0x6b, 0x78, 0x85, 0x25, 0x08, 0x2c, 0xcd, 0x88, 0xcf, 0x26, 0x73, + 0xce, 0x43, 0x59, 0xba, 0x55, 0x16, 0xc3, 0xf4, 0x19, 0x54, 0xd1, 0xe9, 0x63, 0x37, 0x12, 0xe4, + 0x67, 0x50, 0x46, 0x1c, 0x1e, 0x6a, 0x65, 0xb7, 0xbe, 0x5f, 0x4f, 0x1d, 0x8a, 0x29, 0x0a, 0xbd, + 0x02, 0x40, 0xd6, 0x53, 0x3b, 0xb4, 0xbd, 0x28, 0xb7, 0x14, 0xd1, 0xc5, 0x74, 0x03, 0xd3, 0x10, + 0xf2, 0xc6, 0xb7, 0xb4, 0xc9, 0xe4, 0x37, 0xf2, 0x06, 0x93, 0x49, 0xc4, 0x55, 0x79, 0x34, 0x99, + 0x86, 0x88, 0x05, 0x2b, 0x76, 0x34, 0x96, 0x07, 0xa9, 0x32, 0xfc, 0xa4, 0xaf, 0x01, 0x4e, 0xed, + 0x0b, 0xae, 0xed, 0x26, 0x72, 0xc5, 0x8c, 0x9c, 0xb1, 0x51, 0x4a, 0x6c, 0xd0, 0x1b, 0x58, 0x97, + 0x21, 0x3e, 0x08, 0x9c, 0x5b, 0x54, 0x21, 0xfb, 0x9c, 0xbc, 0xb9, 0xa6, 0xb4, 0x25, 0x90, 0xd2, + 0x59, 0xca, 0xd5, 0x99, 0xf6, 0xfb, 0x11, 0xac, 0x9e, 0x07, 0xce, 0xad, 0xf4, 0xba, 0xbe, 0x6f, + 0xe9, 0x38, 0xc5, 0x66, 0x98, 0xa4, 0xd2, 0xbf, 0xc2, 0x46, 0xca, 0xb2, 0x74, 0x9c, 0x42, 0x03, + 0x83, 0x14, 0x84, 0xbe, 0x6a, 0x69, 0x2a, 0x70, 0x19, 0x1c, 0xf9, 0x12, 0x2a, 0x73, 0xfb, 0x02, + 0xdb, 0x8c, 0xaa, 0x95, 0x4d, 0x93, 0x86, 0xf8, 0xfc, 0x4c, 0x33, 0xd0, 0x5f, 0x6b, 0x0b, 0x47, + 0xdc, 0x76, 0x74, 0x0e, 0x1f, 0x41, 0x45, 0x75, 0x3f, 0x9d, 0xc4, 0x46, 0xda, 0x39, 0xa6, 0x69, + 0xd4, 0x85, 0xa6, 0x44, 0xbc, 0xe5, 0xc2, 0x76, 0x6c, 0x61, 0xe7, 0x66, 0xf2, 0x09, 0x66, 0x12, + 0x15, 0x6b, 0x47, 0x48, 0x5a, 0x95, 0x32, 0xc9, 0x34, 0x07, 0x5e, 0x34, 0x71, 0xa3, 0x2e, 0x9a, + 0x2a, 0x58, 0x03, 0xd2, 0x36, 0x6c, 0x66, 0x4c, 0x49, 0x2f, 0x9f, 0x2e, 0x79, 0xb9, 0x95, 0x56, + 0x6d, 0x38, 0x63, 0x6f, 0x39, 0x34, 0x3a, 0x81, 0xe7, 0xb9, 0x82, 0xf1, 0x68, 0x31, 0xcb, 0xef, + 0x80, 0x5f, 0x42, 0x99, 0x87, 0x61, 0xa0, 0x7c, 0x5d, 0xdf, 0xff, 0xc4, 0xcc, 0x12, 0x29, 0xa7, + 0x06, 0x31, 0x53, 0x1c, 0x98, 0x69, 0x87, 0x0b, 0xdb, 0x9d, 0xe9, 0xf1, 0xa9, 0x21, 0xda, 0x06, + 0x2b, 0x6d, 0x46, 0x3a, 0xfa, 0x0c, 0xd6, 0x42, 0x09, 0x19, 0x4f, 0xb3, 0x8a, 0x15, 0x27, 0x33, + 0x3c, 0x74, 0x08, 0x8d, 0xf7, 0x3c, 0x74, 0x27, 0xb7, 0xda, 0xd3, 0xff, 0x83, 0x92, 0xb8, 0xd1, + 0x3d, 0xa2, 0xa6, 0x25, 0x87, 0x37, 0xac, 0x24, 0x6e, 0x3e, 0xe4, 0xb0, 0x12, 0xcf, 0x38, 0x4c, + 0x87, 0x78, 0x47, 0xc3, 0x28, 0xf0, 0xed, 0x19, 0xf6, 0xa8, 0xb9, 0x1d, 0x45, 0xf3, 0x69, 0x68, + 0x47, 0x5c, 0x8f, 0x88, 0x14, 0x86, 0xec, 0x82, 0x69, 0x71, 0x3a, 0x6b, 0x66, 0xaa, 0xea, 0x3e, + 0x18, 0x77, 0x40, 0x3a, 0x85, 0x46, 0xcf, 0xc3, 0xd1, 0x72, 0x18, 0x84, 0x9e, 0x8d, 0x95, 0xb3, + 0x72, 0xed, 0x4e, 0x96, 0x1a, 0x5a, 0xaa, 0x39, 0x33, 0x24, 0x63, 0xa2, 0x83, 0x99, 0x83, 0x06, + 0xa5, 0xfe, 0x1a, 0x33, 0x20, 0x52, 0x7c, 0x7e, 0x2d, 0x29, 0x2a, 0xae, 0x06, 0xa4, 0xaf, 0x60, + 0x6d, 0xa0, 0xa7, 0xe4, 0x3d, 0xa8, 0xd8, 0x5e, 0xaa, 0x1f, 0x6b, 0x08, 0x53, 0x7a, 0x3d, 0xe5, + 0xbe, 0xee, 0x19, 0xf2, 0x9b, 0xfe, 0x16, 0x56, 0xdf, 0x07, 0x42, 0x4e, 0xcf, 0xb1, 0xed, 0x3b, + 0xae, 0x83, 0xed, 0x50, 0x89, 0x25, 0x88, 0x94, 0xc6, 0x52, 0x5a, 0x23, 0xdd, 0x07, 0x40, 0x69, + 0x7d, 0xf1, 0xd6, 0xe3, 0x3d, 0xa3, 0x26, 0xf7, 0x8a, 0x2d, 0x28, 0x27, 0x41, 0x6a, 0x32, 0x05, + 0x50, 0x07, 0x36, 0x74, 0x98, 0x50, 0x54, 0x2e, 0x28, 0xbb, 0xb0, 0x66, 0xa6, 0x7e, 0x76, 0x4b, + 0xd1, 0x27, 0x62, 0x86, 0x4c, 0xbe, 0x80, 0xca, 0x55, 0x20, 0xd4, 0xbd, 0xc5, 0x4a, 0xd9, 0x30, + 0x19, 0xd5, 0xaa, 0x98, 0x26, 0xd3, 0x6f, 0xa0, 0x1a, 0xab, 0x57, 0x7e, 0x95, 0x62, 0xbf, 0x1e, + 0x02, 0xc4, 0x47, 0xc3, 0x38, 0xae, 0x60, 0x7a, 0x13, 0x0c, 0xfd, 0x9d, 0x92, 0x35, 0xed, 0xfa, + 0x2a, 0x40, 0xb6, 0x6c, 0xbb, 0x46, 0x3a, 0x53, 0x94, 0x65, 0xf5, 0xb4, 0x0d, 0x6b, 0xfd, 0xc0, + 0xe1, 0x8c, 0xff, 0x28, 0x6f, 0xac, 0xeb, 0xf1, 0x60, 0x11, 0x8f, 0x46, 0x0d, 0xaa, 0xfd, 0xcd, + 0x9b, 0x07, 0x3e, 0x8f, 0x83, 0x9a, 0x20, 0x68, 0x0b, 0x56, 0xfb, 0xb6, 0xc7, 0x31, 0x63, 0xb8, + 0xc2, 0xe8, 0x98, 0xca, 0x6f, 0x3a, 0x86, 0x2a, 0xd2, 0xe4, 0xc9, 0x3e, 0x4f, 0xd1, 0x13, 0xe7, + 0x90, 0xac, 0x98, 0x31, 0x05, 0xc1, 0xb5, 0xaf, 0xbb, 0x4b, 0x83, 0x29, 0x80, 0xec, 0x40, 0xdd, + 0xe1, 0x91, 0x70, 0x7d, 0x5b, 0xb8, 0x81, 0xaf, 0xb7, 0x89, 0x34, 0x8a, 0x76, 0xa1, 0x8e, 0x13, + 0x29, 0xd2, 0x99, 0x6d, 0x41, 0xd5, 0x0f, 0x8e, 0xd4, 0x50, 0x2c, 0xaa, 0xe1, 0x66, 0x60, 0x39, + 0xf8, 0xa6, 0xc1, 0xf5, 0x80, 0xcf, 0x26, 0x7a, 0x7b, 0x8d, 0x61, 0xfa, 0x19, 0xd4, 0xbe, 0xe7, + 0xa6, 0x2f, 0x5b, 0xb0, 0x72, 0xc9, 0x6f, 0x65, 0x20, 0x6b, 0x0c, 0x3f, 0xe9, 0xdf, 0x4a, 0x00, + 0x03, 0x1e, 0x5e, 0xf1, 0x50, 0x9e, 0xe6, 0x15, 0x54, 0x22, 0x79, 0x27, 0x75, 0xb0, 0x3f, 0x33, + 0x55, 0x10, 0xb3, 0xec, 0xa9, 0x3b, 0xdb, 0xf5, 0x45, 0x78, 0xcb, 0x34, 0x33, 0x8a, 0x8d, 0x03, + 0x7f, 0xe2, 0x9a, 0x9a, 0xc8, 0x11, 0xeb, 0x48, 0xba, 0x16, 0x53, 0xcc, 0xad, 0xdf, 0x40, 0x3d, + 0xa5, 0x2d, 0xf1, 0xae, 0xa8, 0xbd, 0x4b, 0xf6, 0x1f, 0x95, 0x5a, 0x05, 0x7c, 0x53, 0x7a, 0x5d, + 0x6c, 0x1d, 0x43, 0x3d, 0xa5, 0x31, 0x47, 0xf4, 0x8b, 0xb4, 0x68, 0x32, 0x5d, 0x94, 0x50, 0x4f, + 0x70, 0x2f, 0xa5, 0x8d, 0xfe, 0x84, 0x1b, 0x91, 0x21, 0x90, 0x7d, 0x28, 0xcf, 0xc3, 0x60, 0x1e, + 0xe9, 0xc3, 0x3c, 0xb8, 0x23, 0xba, 0x77, 0x8a, 0x64, 0x75, 0x16, 0xc5, 0xda, 0xc2, 0xc1, 0x1d, + 0x23, 0x3f, 0xe6, 0x24, 0xf4, 0x05, 0xd4, 0xba, 0x57, 0xdc, 0x17, 0x66, 0xac, 0x71, 0x04, 0x96, + 0xc7, 0x9a, 0xe4, 0x60, 0x9a, 0x46, 0x7b, 0xd0, 0xec, 0x64, 0x9e, 0x42, 0x04, 0x56, 0x91, 0xcf, + 0x14, 0x29, 0x7e, 0x23, 0x4e, 0xbe, 0x9d, 0x94, 0x41, 0xf9, 0x8d, 0x7e, 0x9d, 0xcf, 0xcd, 0x7d, + 0xc3, 0xcf, 0x27, 0xff, 0x2e, 0x9a, 0xa1, 0xa3, 0x5f, 0x71, 0x35, 0x28, 0x0f, 0xcf, 0x46, 0x27, + 0xdf, 0x5b, 0x05, 0xb2, 0x05, 0xd6, 0xf0, 0x6c, 0xd4, 0x3f, 0xe9, 0x77, 0xba, 0xa3, 0xe1, 0xc9, + 0xc9, 0xe8, 0xf8, 0xe4, 0x4f, 0x56, 0x91, 0x7c, 0x0a, 0x9b, 0xc3, 0xb3, 0x51, 0xfb, 0x98, 0x75, + 0xdb, 0xdf, 0xfd, 0x30, 0xea, 0x9e, 0xf5, 0x06, 0xc3, 0x81, 0x55, 0x22, 0x9f, 0xc0, 0xc6, 0xf0, + 0x6c, 0xd4, 0xeb, 0xbf, 0x6f, 0x1f, 0xf7, 0xbe, 0x1b, 0x1d, 0xb5, 0x07, 0x47, 0xd6, 0xca, 0x12, + 0x72, 0xd0, 0x7b, 0xd3, 0xb7, 0x56, 0xb5, 0x02, 0x83, 0x3c, 0x3c, 0x61, 0x6f, 0xdb, 0x43, 0xab, + 0x4c, 0xfe, 0x1f, 0xee, 0x4b, 0xf4, 0xe0, 0xdd, 0xe1, 0x61, 0xaf, 0xd3, 0xeb, 0xf6, 0x87, 0xa3, + 0x83, 0xf6, 0x71, 0xbb, 0xdf, 0xe9, 0x5a, 0x15, 0x2d, 0x73, 0xd4, 0x1e, 0x8c, 0x06, 0xed, 0xb7, + 0x5d, 0xe5, 0x93, 0xb5, 0x16, 0xab, 0x1a, 0x76, 0x59, 0xbf, 0x7d, 0x3c, 0xea, 0x32, 0x76, 0xc2, + 0xac, 0xda, 0x93, 0x89, 0x19, 0x4f, 0xfa, 0x4c, 0x5b, 0x60, 0xbd, 0xef, 0xb2, 0xde, 0xe1, 0x0f, + 0xa3, 0xc1, 0xb0, 0x3d, 0x7c, 0x37, 0x50, 0xc7, 0xdb, 0x81, 0x07, 0x59, 0x2c, 0xfa, 0x37, 0xea, + 0x9f, 0x0c, 0x47, 0x6f, 0xdb, 0xc3, 0xce, 0x91, 0x55, 0x24, 0x0f, 0xa1, 0x95, 0xe5, 0xc8, 0x1c, + 0xaf, 0xb4, 0xff, 0x4f, 0x0b, 0x36, 0xda, 0x3c, 0xbc, 0x08, 0xd8, 0x69, 0x07, 0x4b, 0x1d, 0xdf, + 0x40, 0x2f, 0xa0, 0x86, 0xad, 0x67, 0x20, 0xf7, 0x58, 0xd3, 0x44, 0x75, 0x33, 0x6a, 0xe5, 0x8c, + 0x1b, 0x5a, 0x20, 0x2f, 0xa0, 0xf2, 0x56, 0xbe, 0xae, 0x89, 0xd9, 0x97, 0x15, 0x18, 0x31, 0xfe, + 0xe3, 0x82, 0x47, 0xa2, 0xb5, 0x9e, 0x45, 0xd3, 0x02, 0x79, 0x05, 0x90, 0xbc, 0xbf, 0x49, 0x5c, + 0x25, 0xf8, 0xd6, 0x68, 0xdd, 0x4f, 0x2f, 0x19, 0xa9, 0x07, 0x3a, 0x2d, 0x90, 0xe7, 0xd0, 0x78, + 0xc3, 0x45, 0xf2, 0x2c, 0xcd, 0x0a, 0x5a, 0x99, 0x87, 0xa9, 0x3f, 0x09, 0x68, 0x81, 0xec, 0xe9, + 0x57, 0x2c, 0xaa, 0x58, 0x62, 0xdf, 0x4c, 0xb3, 0xcb, 0x47, 0x1d, 0x2d, 0x90, 0x6f, 0xc1, 0xc2, + 0x42, 0x4e, 0xed, 0x4e, 0x11, 0x31, 0x8c, 0xc9, 0x46, 0xdd, 0xba, 0x77, 0x77, 0xc7, 0x42, 0x2a, + 0x2d, 0x90, 0x03, 0xd8, 0x8c, 0x15, 0xc4, 0x6b, 0x5b, 0x8e, 0x86, 0xed, 0xbc, 0x55, 0x4a, 0xeb, + 0x78, 0x01, 0x1b, 0xb1, 0x8e, 0x81, 0x08, 0xb9, 0xed, 0x2d, 0xb9, 0x9e, 0xd9, 0x16, 0x69, 0xe1, + 0x79, 0x91, 0xb4, 0xe1, 0xfe, 0x1d, 0xb3, 0xb9, 0xa2, 0xb9, 0x2b, 0x9c, 0x54, 0xb1, 0x07, 0xd5, + 0x37, 0x5c, 0x69, 0x20, 0x39, 0x89, 0x5e, 0x36, 0x4a, 0x7e, 0x0f, 0x96, 0xe1, 0x4f, 0xf6, 0xd3, + 0x1c, 0xb9, 0x0f, 0x58, 0x24, 0xdf, 0xca, 0x64, 0xc6, 0xab, 0x37, 0xb9, 0xb7, 0xbc, 0x9f, 0xeb, + 0x48, 0x7d, 0x7a, 0x17, 0x7f, 0xc1, 0x1d, 0x5a, 0x20, 0xbb, 0x50, 0x7e, 0xc3, 0xc5, 0xf0, 0x2c, + 0xd7, 0x6a, 0xb2, 0xc6, 0xd1, 0x02, 0xf9, 0x15, 0x80, 0x31, 0xf5, 0x01, 0x76, 0x2b, 0x66, 0xef, + 0xf9, 0xe6, 0x80, 0xfb, 0x52, 0x8a, 0xf1, 0x31, 0x77, 0xe7, 0x22, 0x57, 0xca, 0x14, 0xb6, 0xe6, + 0xa1, 0x05, 0x5c, 0xc6, 0xdf, 0x70, 0xd1, 0x3e, 0xe8, 0xe5, 0xf2, 0x83, 0x59, 0xf2, 0x0e, 0x7a, + 0x8a, 0x77, 0xc0, 0x7d, 0x67, 0x78, 0x46, 0x12, 0x67, 0x5b, 0x79, 0x8b, 0x2b, 0xc5, 0xcb, 0x5e, + 0x19, 0xb8, 0x17, 0x7e, 0x96, 0x37, 0x73, 0xc6, 0xa7, 0x50, 0x55, 0x4d, 0x23, 0x5f, 0x5f, 0x7a, + 0xdf, 0x95, 0x11, 0xa9, 0x2a, 0x0b, 0xc3, 0x33, 0xd2, 0x8c, 0xb9, 0xb1, 0x84, 0xe2, 0xfb, 0xb7, + 0xbc, 0x64, 0xcb, 0xdb, 0x84, 0x25, 0xa2, 0x7a, 0xc3, 0x7f, 0x2b, 0x11, 0xc9, 0x41, 0x0b, 0xe4, + 0x0f, 0xb2, 0x44, 0x24, 0xd4, 0xf6, 0x9d, 0xd3, 0x30, 0x08, 0x26, 0x71, 0x8f, 0xc8, 0xfe, 0x05, + 0x10, 0xfb, 0xa9, 0xd1, 0x92, 0x57, 0xe6, 0xa0, 0xd9, 0x09, 0x39, 0xca, 0xeb, 0x3f, 0x04, 0x36, + 0xe2, 0xd7, 0xae, 0xda, 0xb4, 0x5b, 0x4b, 0x8b, 0xb3, 0xbc, 0x3e, 0x75, 0xcc, 0x81, 0x82, 0xa3, + 0xa5, 0xfa, 0x27, 0x59, 0x76, 0x7d, 0xb0, 0xe7, 0x50, 0x3f, 0x0e, 0xc6, 0x97, 0x1f, 0x61, 0x64, + 0x1f, 0x9a, 0xef, 0xfc, 0xd9, 0xc7, 0xc9, 0x7c, 0x0d, 0x4d, 0xb5, 0xca, 0x1b, 0x19, 0x73, 0xe8, + 0xf4, 0x82, 0x9f, 0x2f, 0xd7, 0xbd, 0x49, 0xcb, 0xdd, 0xb1, 0x95, 0xdf, 0x98, 0x5f, 0x42, 0xf3, + 0x8f, 0x0b, 0x1e, 0xde, 0x76, 0x02, 0x5f, 0x84, 0xf6, 0x38, 0x69, 0x80, 0x12, 0xfb, 0x01, 0xa1, + 0x36, 0x90, 0x8c, 0x90, 0xca, 0xf6, 0x66, 0x3a, 0xb3, 0x4a, 0xfc, 0xde, 0x1d, 0x94, 0x49, 0xda, + 0x0b, 0x59, 0x26, 0x72, 0xfb, 0x23, 0xe9, 0xbf, 0x5c, 0xf4, 0x2e, 0xd8, 0xda, 0x48, 0xe1, 0xe2, + 0x04, 0xa0, 0xc8, 0x7b, 0xb9, 0x0d, 0x6f, 0xa6, 0x36, 0xe4, 0x25, 0x09, 0xb3, 0x54, 0xcb, 0x46, + 0xbb, 0x91, 0x64, 0x59, 0x09, 0x2e, 0x97, 0x96, 0xfa, 0x63, 0x27, 0x76, 0x74, 0xe9, 0xcd, 0xa0, + 0xc6, 0x90, 0xaa, 0x4f, 0xf9, 0x32, 0xf8, 0x80, 0xf8, 0xd2, 0x4b, 0x82, 0x16, 0xc8, 0x33, 0x59, + 0x60, 0xf1, 0x0a, 0x9d, 0x5e, 0x9a, 0x63, 0x4f, 0x0d, 0x55, 0xa6, 0x4f, 0xb6, 0x73, 0xb9, 0x03, + 0xe9, 0x9e, 0x6c, 0x8e, 0x78, 0xe8, 0xce, 0x84, 0x5a, 0x30, 0x5b, 0x99, 0x55, 0x49, 0x36, 0xe4, + 0x97, 0xea, 0x4f, 0x1c, 0x89, 0x88, 0xf2, 0x44, 0xac, 0xb4, 0x88, 0x0e, 0xcb, 0xd7, 0xd0, 0xc4, + 0x23, 0x25, 0x2b, 0xb1, 0x61, 0x8a, 0xb7, 0xe8, 0x78, 0xf0, 0x25, 0x4c, 0xb4, 0x40, 0x5e, 0xcb, + 0xab, 0x9a, 0x5d, 0xcb, 0xf2, 0x27, 0x47, 0x86, 0x87, 0x16, 0x0e, 0x76, 0xfe, 0xfc, 0xf0, 0xc2, + 0x15, 0xd3, 0xc5, 0xf9, 0xde, 0x38, 0xf0, 0xbe, 0xb2, 0x71, 0x9f, 0x70, 0x03, 0xf5, 0xfb, 0x95, + 0x94, 0x38, 0xaf, 0xc8, 0x7f, 0xdd, 0x5f, 0xfe, 0x27, 0x00, 0x00, 0xff, 0xff, 0xe3, 0x9c, 0x23, + 0xcb, 0xcf, 0x17, 0x00, 0x00, } From 0ab7706b24334bdaaa7f3c52ddb957516770d5c0 Mon Sep 17 00:00:00 2001 From: Sung-Jae Woo Date: Mon, 15 Apr 2019 20:28:31 +0900 Subject: [PATCH 028/148] [rpc] add chainstat RPC command --- aergo-protobuf | 2 +- cmd/aergocli/cmd/chainstat.go | 29 +++++++++++++++++++++++++++++ rpc/grpcserver.go | 8 ++++++-- 3 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 cmd/aergocli/cmd/chainstat.go diff --git a/aergo-protobuf b/aergo-protobuf index cf06c4811..73db589c5 160000 --- a/aergo-protobuf +++ b/aergo-protobuf @@ -1 +1 @@ -Subproject commit cf06c4811a678504a58d12627b2f295f55acac2b +Subproject commit 73db589c5f9825b5ed6882cde1ca4dece54834b8 diff --git a/cmd/aergocli/cmd/chainstat.go b/cmd/aergocli/cmd/chainstat.go new file mode 100644 index 000000000..b94f25ff7 --- /dev/null +++ b/cmd/aergocli/cmd/chainstat.go @@ -0,0 +1,29 @@ +/** + * @file + * @copyright defined in aergo/LICENSE.txt + */ +package cmd + +import ( + "context" + + aergorpc "github.com/aergoio/aergo/types" + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(chainstatCmd) +} + +var chainstatCmd = &cobra.Command{ + Use: "chainstat", + Short: "Print chain statistics", + Run: func(cmd *cobra.Command, args []string) { + msg, err := client.ChainStat(context.Background(), &aergorpc.Empty{}) + if err != nil { + cmd.Printf("Failed: %s\n", err.Error()) + return + } + cmd.Println(msg.Report) + }, +} diff --git a/rpc/grpcserver.go b/rpc/grpcserver.go index 6638f934a..8b983ecb5 100644 --- a/rpc/grpcserver.go +++ b/rpc/grpcserver.go @@ -1049,7 +1049,11 @@ func (rpc *AergoRPCService) GetConsensusInfo(ctx context.Context, in *types.Empt return rpc.consensusAccessor.ConsensusInfo(), nil } -// Chainstat handles rpc request chainstat. +// ChainStat handles rpc request chainstat. func (rpc *AergoRPCService) ChainStat(ctx context.Context, in *types.Empty) (*types.ChainStats, error) { - return nil, nil + ca := rpc.actorHelper.GetChainAccessor() + if ca == nil { + return nil, ErrUninitAccessor + } + return &types.ChainStats{Report: ca.GetChainStats()}, nil } From a4f90d186d40dcfc57db305a9887dd3f221545b6 Mon Sep 17 00:00:00 2001 From: Hayarobi Park Date: Mon, 22 Apr 2019 12:04:00 +0900 Subject: [PATCH 029/148] [P2P] Improve debug logging - add send block notice log --- p2p/protobufHelper.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/p2p/protobufHelper.go b/p2p/protobufHelper.go index 54b701345..a3d7ec063 100644 --- a/p2p/protobufHelper.go +++ b/p2p/protobufHelper.go @@ -126,12 +126,13 @@ func (pr *pbBlkNoticeOrder) SendTo(pi p2pcommon.RemotePeer) error { } if skipNotice || passedTime < MinNewBlkNotiInterval { p.skipCnt++ + if p.skipCnt&0x03ff == 0 { + p.logger.Debug().Str(p2putil.LogPeerName, p.Name()).Str(p2putil.LogProtoID, pr.GetProtocolID().String()).Int32("skip_cnt", p.skipCnt).Msg("Skipped NewBlockNotice ") + + } return nil } - if p.skipCnt > 100 { - p.logger.Debug().Str(p2putil.LogPeerName, p.Name()).Str(p2putil.LogProtoID, pr.GetProtocolID().String()).Int32("skip_cnt", p.skipCnt).Str(p2putil.LogMsgID, pr.GetMsgID().String()).Str(p2putil.LogOrgReqID, pr.message.OriginalID().String()).Msg("Send NewBlockNotice after long skip") - } if ok, _ := p.blkHashCache.ContainsOrAdd(blkhash, cachePlaceHolder); ok { // the remote peer already know this block hash. skip it // too many not-insteresting log, @@ -144,8 +145,11 @@ func (pr *pbBlkNoticeOrder) SendTo(pi p2pcommon.RemotePeer) error { p.logger.Warn().Str(p2putil.LogPeerName, p.Name()).Str(p2putil.LogProtoID, pr.GetProtocolID().String()).Str(p2putil.LogMsgID, pr.GetMsgID().String()).Err(err).Msg("fail to SendTo") return err } - p.skipCnt = 0 p.lastBlkNoticeTime = time.Now() + if p.skipCnt > 100 { + p.logger.Debug().Str(p2putil.LogPeerName, p.Name()).Str(p2putil.LogProtoID, pr.GetProtocolID().String()).Int32("skip_cnt", p.skipCnt).Msg("Send NewBlockNotice after long skip") + } + p.skipCnt = 0 return nil } From b9086d116c4b27782f4fb880ed0411c48bf6ca10 Mon Sep 17 00:00:00 2001 From: bjjeon Date: Mon, 22 Apr 2019 15:51:32 +0900 Subject: [PATCH 030/148] [brick] can batch or deploy a file over http --- cmd/brick/README.md | 9 +++- cmd/brick/exec/batch.go | 74 +++++++++++++++++++++++--------- cmd/brick/exec/deployContract.go | 39 +++++++++++++++-- 3 files changed, 97 insertions(+), 25 deletions(-) diff --git a/cmd/brick/README.md b/cmd/brick/README.md index d8ce1ac62..9d0c027d8 100644 --- a/cmd/brick/README.md +++ b/cmd/brick/README.md @@ -76,6 +76,13 @@ deploy a smart contract. `deploy deploy tester 0 helloContract https://raw.githubusercontent.com/aergoio/aergo-contract-ex/master/contracts/helloworld/test/test-helloworld.brick + INF deploy a smart contract successfully cmd=deploy module=brick +``` + ### call call to execute a smart contract. `call [expected_error]` @@ -105,7 +112,7 @@ query to a smart contract. `query [ ### batch -keeps commands in a text file and use at later. `batch ` +keeps commands in a text file (local or http) and use at later. `batch ` ``` lua 4> batch ./example/hello.brick diff --git a/cmd/brick/exec/batch.go b/cmd/brick/exec/batch.go index 6eeb10990..5c0d53929 100644 --- a/cmd/brick/exec/batch.go +++ b/cmd/brick/exec/batch.go @@ -3,8 +3,10 @@ package exec import ( "bufio" "fmt" + "net/http" "os" "path/filepath" + "strings" "github.com/aergoio/aergo/cmd/brick/context" "github.com/fsnotify/fsnotify" @@ -64,23 +66,60 @@ func (c *batch) Validate(args string) error { return err } +func (c *batch) readBatchFile(batchFilePath string) ([]string, error) { + if strings.HasPrefix(batchFilePath, "http") { + // search in the web + req, err := http.NewRequest("GET", batchFilePath, nil) + if err != nil { + return nil, err + } + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + var cmdLines []string + scanner := bufio.NewScanner(resp.Body) + for scanner.Scan() { + cmdLines = append(cmdLines, scanner.Text()) + } + + return cmdLines, nil + } + + batchFile, err := os.Open(batchFilePath) + if err != nil { + return nil, err + } + defer batchFile.Close() + + var cmdLines []string + scanner := bufio.NewScanner(batchFile) + for scanner.Scan() { + cmdLines = append(cmdLines, scanner.Text()) + } + + return cmdLines, nil +} + func (c *batch) parse(args string) (string, error) { splitArgs := context.SplitSpaceAndAccent(args, false) if len(splitArgs) != 1 { return "", fmt.Errorf("invalid format. usage: %s", c.Usage()) } - batchFilePath := splitArgs[0] + batchFilePath := splitArgs[0].Text - if _, err := os.Stat(batchFilePath.Text); os.IsNotExist(err) { - return "", fmt.Errorf("fail to read a brick batch file %s: %s", batchFilePath.Text, err.Error()) + if _, err := c.readBatchFile(batchFilePath); err != nil { + return "", fmt.Errorf("fail to read a brick batch file %s: %s", batchFilePath, err.Error()) } - return batchFilePath.Text, nil + return batchFilePath, nil } func (c *batch) Run(args string) (string, error) { - batchFilePath, _ := c.parse(args) stdOut := colorable.NewColorableStdout() var err error @@ -97,28 +136,21 @@ func (c *batch) Run(args string) (string, error) { prefix := "" - batchFile, err := os.Open(batchFilePath) + batchFilePath, _ := c.parse(args) + cmdLines, err := c.readBatchFile(batchFilePath) if err != nil { return "", err } - var cmdLines []string - scanner := bufio.NewScanner(batchFile) - for scanner.Scan() { - cmdLines = append(cmdLines, scanner.Text()) - } - - batchFile.Close() - c.level++ // set highest log level to turn off verbose if false == verboseBatch { zerolog.SetGlobalLevel(zerolog.ErrorLevel) - fmt.Fprintf(stdOut, "> %s\n", batchFile.Name()) + fmt.Fprintf(stdOut, "> %s\n", batchFilePath) } else if verboseBatch && c.level != 1 { prefix = fmt.Sprintf("%d-", c.level-1) - fmt.Fprintf(stdOut, "\n<<<<<<< %s\n", batchFile.Name()) + fmt.Fprintf(stdOut, "\n<<<<<<< %s\n", batchFilePath) } for i, line := range cmdLines { @@ -144,13 +176,13 @@ func (c *batch) Run(args string) (string, error) { if letBatchKnowErr != nil { // if there is error during execution, then print line for error trace - fmt.Fprintf(stdOut, "\x1B[0;37m%s:%d \x1B[34;1m%s \x1B[0m%s\n\n", batchFile.Name(), lineNum, cmd, args) + fmt.Fprintf(stdOut, "\x1B[0;37m%s:%d \x1B[34;1m%s \x1B[0m%s\n\n", batchFilePath, lineNum, cmd, args) letBatchKnowErr = nil } } if c.level != 1 && verboseBatch { - fmt.Fprintf(stdOut, ">>>>>>> %s\n", batchFile.Name()) + fmt.Fprintf(stdOut, ">>>>>>> %s\n", batchFilePath) } c.level-- @@ -168,8 +200,8 @@ func (c *batch) Run(args string) (string, error) { } // add file to watch list - if enableWatch { - absPath, _ := filepath.Abs(batchFile.Name()) + if enableWatch && !strings.HasPrefix(batchFilePath, "http") { + absPath, _ := filepath.Abs(batchFilePath) watcher.Add(absPath) } @@ -182,7 +214,7 @@ func (c *batch) Run(args string) (string, error) { break fileWatching case err, _ := <-watcher.Errors: if err != nil { - fmt.Fprintf(stdOut, "\x1B[0;37mWatching File %s Error: %s\x1B[0m\n", batchFile.Name(), err.Error()) + fmt.Fprintf(stdOut, "\x1B[0;37mWatching File %s Error: %s\x1B[0m\n", batchFilePath, err.Error()) } break fileWatching } diff --git a/cmd/brick/exec/deployContract.go b/cmd/brick/exec/deployContract.go index 4b9f517f9..eae954900 100644 --- a/cmd/brick/exec/deployContract.go +++ b/cmd/brick/exec/deployContract.go @@ -4,8 +4,10 @@ import ( "fmt" "io/ioutil" "math/big" + "net/http" "os" "path/filepath" + "strings" "github.com/aergoio/aergo/cmd/brick/context" "github.com/aergoio/aergo/contract" @@ -46,6 +48,37 @@ func (c *deployContract) Validate(args string) error { return err } +func (c *deployContract) readDefFile(defPath string) ([]byte, error) { + if strings.HasPrefix(defPath, "http") { + // search in the web + req, err := http.NewRequest("GET", defPath, nil) + if err != nil { + return nil, err + } + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + defByte, _ := ioutil.ReadAll(resp.Body) + + return defByte, nil + } + + // search in a local file system + if _, err := os.Stat(defPath); os.IsNotExist(err) { + return nil, err + } + defByte, err := ioutil.ReadFile(defPath) + if err != nil { + return nil, err + } + + return defByte, nil + +} + func (c *deployContract) parse(args string) (string, *big.Int, string, string, string, error) { splitArgs := context.SplitSpaceAndAccent(args, false) if len(splitArgs) < 4 { @@ -58,7 +91,7 @@ func (c *deployContract) parse(args string) (string, *big.Int, string, string, s } defPath := splitArgs[3].Text - if _, err := os.Stat(defPath); os.IsNotExist(err) { + if _, err := c.readDefFile(defPath); err != nil { return "", nil, "", "", "", fmt.Errorf("fail to read a contrat def file %s: %s", splitArgs[3].Text, err.Error()) } @@ -80,7 +113,7 @@ func (c *deployContract) parse(args string) (string, *big.Int, string, string, s func (c *deployContract) Run(args string) (string, error) { accountName, amount, contractName, defPath, constuctorArg, _ := c.parse(args) - defByte, err := ioutil.ReadFile(defPath) + defByte, err := c.readDefFile(defPath) if err != nil { return "", err } @@ -98,7 +131,7 @@ func (c *deployContract) Run(args string) (string, error) { Index(context.ContractSymbol, contractName) Index(context.AccountSymbol, contractName) - if enableWatch { + if enableWatch && !strings.HasPrefix(defPath, "http") { absPath, _ := filepath.Abs(defPath) watcher.Add(absPath) } From b4ea3e05b8d7f81bf9e203eac0cb999f285096b6 Mon Sep 17 00:00:00 2001 From: Hayarobi Park Date: Mon, 22 Apr 2019 16:40:04 +0900 Subject: [PATCH 031/148] [P2P] Refactor code - Completely deecouple peermanager and remorepeerimpl. remove type conversion to concreate pointer - Move some interfaces to common area --- p2p/handshake.go | 11 -- p2p/p2p.go | 54 ++++--- p2p/p2pcommon/handshake.go | 26 ++++ p2p/p2pcommon/message.go | 5 + p2p/p2pcommon/others.go | 33 ----- p2p/p2pcommon/remotepeer.go | 47 +++++++ p2p/p2pmock/mock_hsfactory.go | 149 ++++++++++++++++++++ p2p/p2pmock/mock_message.go | 98 +++++++------ p2p/p2pmock/mock_remotepeer.go | 249 +++++++++++++++------------------ p2p/peermanager.go | 8 +- p2p/remotepeer.go | 4 + 11 files changed, 431 insertions(+), 253 deletions(-) create mode 100644 p2p/p2pcommon/handshake.go create mode 100644 p2p/p2pcommon/remotepeer.go create mode 100644 p2p/p2pmock/mock_hsfactory.go diff --git a/p2p/handshake.go b/p2p/handshake.go index 76a0f3ec8..7bbd7184f 100644 --- a/p2p/handshake.go +++ b/p2p/handshake.go @@ -18,17 +18,6 @@ import ( "github.com/libp2p/go-libp2p-peer" ) -// HSHandlerFactory is creator of HSHandler -type HSHandlerFactory interface { - CreateHSHandler(outbound bool, pm p2pcommon.PeerManager, actor p2pcommon.ActorService, log *log.Logger, pid peer.ID) HSHandler -} - -// HSHandler will do handshake with remote peer -type HSHandler interface { - // Handle peer handshake till ttl, and return msgrw for this connection, and status of remote peer. - Handle(r io.Reader, w io.Writer, ttl time.Duration) (p2pcommon.MsgReadWriter, *types.Status, error) -} - type InboundHSHandler struct { *PeerHandshaker } diff --git a/p2p/p2p.go b/p2p/p2p.go index 1d3fa1840..54c662c66 100644 --- a/p2p/p2p.go +++ b/p2p/p2p.go @@ -14,7 +14,7 @@ import ( "github.com/aergoio/aergo/p2p/metric" "github.com/aergoio/aergo/p2p/p2pcommon" "github.com/aergoio/aergo/p2p/p2putil" - subproto "github.com/aergoio/aergo/p2p/subproto" + "github.com/aergoio/aergo/p2p/subproto" "github.com/aergoio/aergo-actor/actor" "github.com/aergoio/aergo-lib/log" @@ -52,13 +52,9 @@ type P2P struct { mutex sync.Mutex } -type HandlerFactory interface { - insertHandlers(peer *remotePeerImpl) -} - var ( - _ p2pcommon.ActorService = (*P2P)(nil) - _ HSHandlerFactory = (*P2P)(nil) + _ p2pcommon.ActorService = (*P2P)(nil) + _ p2pcommon.HSHandlerFactory = (*P2P)(nil) ni *nodeInfo ) @@ -338,40 +334,40 @@ func (p2ps *P2P) GetChainAccessor() types.ChainAccessor { return p2ps.ca } -func (p2ps *P2P) insertHandlers(peer *remotePeerImpl) { +func (p2ps *P2P) InsertHandlers(peer p2pcommon.RemotePeer) { logger := p2ps.Logger // PingHandlers - peer.handlers[subproto.PingRequest] = subproto.NewPingReqHandler(p2ps.pm, peer, logger, p2ps) - peer.handlers[subproto.PingResponse] = subproto.NewPingRespHandler(p2ps.pm, peer, logger, p2ps) - peer.handlers[subproto.GoAway] = subproto.NewGoAwayHandler(p2ps.pm, peer, logger, p2ps) - peer.handlers[subproto.AddressesRequest] = subproto.NewAddressesReqHandler(p2ps.pm, peer, logger, p2ps) - peer.handlers[subproto.AddressesResponse] = subproto.NewAddressesRespHandler(p2ps.pm, peer, logger, p2ps) + peer.AddMessageHandler(subproto.PingRequest,subproto.NewPingReqHandler(p2ps.pm, peer, logger, p2ps)) + peer.AddMessageHandler(subproto.PingResponse,subproto.NewPingRespHandler(p2ps.pm, peer, logger, p2ps)) + peer.AddMessageHandler(subproto.GoAway,subproto.NewGoAwayHandler(p2ps.pm, peer, logger, p2ps)) + peer.AddMessageHandler(subproto.AddressesRequest,subproto.NewAddressesReqHandler(p2ps.pm, peer, logger, p2ps)) + peer.AddMessageHandler(subproto.AddressesResponse,subproto.NewAddressesRespHandler(p2ps.pm, peer, logger, p2ps)) // BlockHandlers - peer.handlers[subproto.GetBlocksRequest] = subproto.NewBlockReqHandler(p2ps.pm, peer, logger, p2ps) - peer.handlers[subproto.GetBlocksResponse] = subproto.NewBlockRespHandler(p2ps.pm, peer, logger, p2ps, p2ps.sm) - peer.handlers[subproto.GetBlockHeadersRequest] = subproto.NewListBlockHeadersReqHandler(p2ps.pm, peer, logger, p2ps) - peer.handlers[subproto.GetBlockHeadersResponse] = subproto.NewListBlockRespHandler(p2ps.pm, peer, logger, p2ps) - peer.handlers[subproto.NewBlockNotice] = subproto.NewNewBlockNoticeHandler(p2ps.pm, peer, logger, p2ps, p2ps.sm) - peer.handlers[subproto.GetAncestorRequest] = subproto.NewGetAncestorReqHandler(p2ps.pm, peer, logger, p2ps) - peer.handlers[subproto.GetAncestorResponse] = subproto.NewGetAncestorRespHandler(p2ps.pm, peer, logger, p2ps) - peer.handlers[subproto.GetHashesRequest] = subproto.NewGetHashesReqHandler(p2ps.pm, peer, logger, p2ps) - peer.handlers[subproto.GetHashesResponse] = subproto.NewGetHashesRespHandler(p2ps.pm, peer, logger, p2ps) - peer.handlers[subproto.GetHashByNoRequest] = subproto.NewGetHashByNoReqHandler(p2ps.pm, peer, logger, p2ps) - peer.handlers[subproto.GetHashByNoResponse] = subproto.NewGetHashByNoRespHandler(p2ps.pm, peer, logger, p2ps) + peer.AddMessageHandler(subproto.GetBlocksRequest,subproto.NewBlockReqHandler(p2ps.pm, peer, logger, p2ps)) + peer.AddMessageHandler(subproto.GetBlocksResponse,subproto.NewBlockRespHandler(p2ps.pm, peer, logger, p2ps, p2ps.sm)) + peer.AddMessageHandler(subproto.GetBlockHeadersRequest,subproto.NewListBlockHeadersReqHandler(p2ps.pm, peer, logger, p2ps)) + peer.AddMessageHandler(subproto.GetBlockHeadersResponse,subproto.NewListBlockRespHandler(p2ps.pm, peer, logger, p2ps)) + peer.AddMessageHandler(subproto.NewBlockNotice,subproto.NewNewBlockNoticeHandler(p2ps.pm, peer, logger, p2ps, p2ps.sm)) + peer.AddMessageHandler(subproto.GetAncestorRequest,subproto.NewGetAncestorReqHandler(p2ps.pm, peer, logger, p2ps)) + peer.AddMessageHandler(subproto.GetAncestorResponse,subproto.NewGetAncestorRespHandler(p2ps.pm, peer, logger, p2ps)) + peer.AddMessageHandler(subproto.GetHashesRequest,subproto.NewGetHashesReqHandler(p2ps.pm, peer, logger, p2ps)) + peer.AddMessageHandler(subproto.GetHashesResponse,subproto.NewGetHashesRespHandler(p2ps.pm, peer, logger, p2ps)) + peer.AddMessageHandler(subproto.GetHashByNoRequest,subproto.NewGetHashByNoReqHandler(p2ps.pm, peer, logger, p2ps)) + peer.AddMessageHandler(subproto.GetHashByNoResponse,subproto.NewGetHashByNoRespHandler(p2ps.pm, peer, logger, p2ps)) // TxHandlers - peer.handlers[subproto.GetTXsRequest] = subproto.NewTxReqHandler(p2ps.pm, peer, logger, p2ps) - peer.handlers[subproto.GetTXsResponse] = subproto.NewTxRespHandler(p2ps.pm, peer, logger, p2ps) - peer.handlers[subproto.NewTxNotice] = subproto.NewNewTxNoticeHandler(p2ps.pm, peer, logger, p2ps, p2ps.sm) + peer.AddMessageHandler(subproto.GetTXsRequest,subproto.NewTxReqHandler(p2ps.pm, peer, logger, p2ps)) + peer.AddMessageHandler(subproto.GetTXsResponse,subproto.NewTxRespHandler(p2ps.pm, peer, logger, p2ps)) + peer.AddMessageHandler(subproto.NewTxNotice,subproto.NewNewTxNoticeHandler(p2ps.pm, peer, logger, p2ps, p2ps.sm)) // BP protocol handlers - peer.handlers[subproto.BlockProducedNotice] = subproto.NewBlockProducedNoticeHandler(p2ps.pm, peer, logger, p2ps, p2ps.sm) + peer.AddMessageHandler(subproto.BlockProducedNotice,subproto.NewBlockProducedNoticeHandler(p2ps.pm, peer, logger, p2ps, p2ps.sm)) } -func (p2ps *P2P) CreateHSHandler(outbound bool, pm p2pcommon.PeerManager, actor p2pcommon.ActorService, log *log.Logger, pid peer.ID) HSHandler { +func (p2ps *P2P) CreateHSHandler(outbound bool, pm p2pcommon.PeerManager, actor p2pcommon.ActorService, log *log.Logger, pid peer.ID) p2pcommon.HSHandler { handshakeHandler := &PeerHandshaker{pm: pm, actorServ: actor, logger: log, localChainID: p2ps.chainID, peerID: pid} if outbound { return &OutboundHSHandler{PeerHandshaker: handshakeHandler} diff --git a/p2p/p2pcommon/handshake.go b/p2p/p2pcommon/handshake.go new file mode 100644 index 000000000..08b34998e --- /dev/null +++ b/p2p/p2pcommon/handshake.go @@ -0,0 +1,26 @@ +/* + * @file + * @copyright defined in aergo/LICENSE.txt + */ + +package p2pcommon + +import ( + "github.com/aergoio/aergo-lib/log" + "github.com/aergoio/aergo/types" + "github.com/libp2p/go-libp2p-peer" + "io" + "time" +) + +// HSHandlerFactory is creator of HSHandler +type HSHandlerFactory interface { + CreateHSHandler(outbound bool, pm PeerManager, actor ActorService, log *log.Logger, pid peer.ID) HSHandler +} + +// HSHandler will do handshake with remote peer +type HSHandler interface { + // Handle peer handshake till ttl, and return msgrw for this connection, and status of remote peer. + Handle(r io.Reader, w io.Writer, ttl time.Duration) (MsgReadWriter, *types.Status, error) +} + diff --git a/p2p/p2pcommon/message.go b/p2p/p2pcommon/message.go index 7002d2da7..1e2ad715f 100644 --- a/p2p/p2pcommon/message.go +++ b/p2p/p2pcommon/message.go @@ -20,3 +20,8 @@ type Message interface { // marshaled by google protocol buffer v3. object is determined by Subprotocol Payload() []byte } + +type HandlerFactory interface { + InsertHandlers(peer RemotePeer) +} + diff --git a/p2p/p2pcommon/others.go b/p2p/p2pcommon/others.go index 52e1003c3..f1ba3b47d 100644 --- a/p2p/p2pcommon/others.go +++ b/p2p/p2pcommon/others.go @@ -14,39 +14,6 @@ import ( protocol "github.com/libp2p/go-libp2p-protocol" ) -type RemotePeer interface { - ID() peer.ID - Meta() PeerMeta - ManageNumber() uint32 - Name() string - - State() types.PeerState - // LastStatus returns last observed status of remote peer. this value will be changed by notice, or ping - LastStatus() *types.LastBlockStatus - - RunPeer() - Stop() - - SendMessage(msg MsgOrder) - SendAndWaitMessage(msg MsgOrder, ttl time.Duration) error - - PushTxsNotice(txHashes []types.TxID) - // utility method - - ConsumeRequest(msgID MsgID) - GetReceiver(id MsgID) ResponseReceiver - - // updateBlkCache add hash to block cache and return true if this hash already exists. - UpdateBlkCache(blkHash []byte, blkNumber uint64) bool - // updateTxCache add hashes to transaction cache and return newly added hashes. - UpdateTxCache(hashes []types.TxID) []types.TxID - // updateLastNotice change estimate of the last status of remote peer - UpdateLastNotice(blkHash []byte, blkNumber uint64) - - // TODO - MF() MoFactory -} - // msgOrder is abstraction information about the message that will be sent to peer // some type of msgOrder, such as notice mo, should thread-safe and re-entrant type MsgOrder interface { diff --git a/p2p/p2pcommon/remotepeer.go b/p2p/p2pcommon/remotepeer.go new file mode 100644 index 000000000..f1366af44 --- /dev/null +++ b/p2p/p2pcommon/remotepeer.go @@ -0,0 +1,47 @@ +/* + * @file + * @copyright defined in aergo/LICENSE.txt + */ + +package p2pcommon + +import ( + "github.com/aergoio/aergo/types" + "github.com/libp2p/go-libp2p-peer" + "time" +) + +type RemotePeer interface { + ID() peer.ID + Meta() PeerMeta + ManageNumber() uint32 + Name() string + + AddMessageHandler(subProtocol SubProtocol, handler MessageHandler) + + State() types.PeerState + // LastStatus returns last observed status of remote peer. this value will be changed by notice, or ping + LastStatus() *types.LastBlockStatus + + RunPeer() + Stop() + + SendMessage(msg MsgOrder) + SendAndWaitMessage(msg MsgOrder, ttl time.Duration) error + + PushTxsNotice(txHashes []types.TxID) + // utility method + + ConsumeRequest(msgID MsgID) + GetReceiver(id MsgID) ResponseReceiver + + // updateBlkCache add hash to block cache and return true if this hash already exists. + UpdateBlkCache(blkHash []byte, blkNumber uint64) bool + // updateTxCache add hashes to transaction cache and return newly added hashes. + UpdateTxCache(hashes []types.TxID) []types.TxID + // updateLastNotice change estimate of the last status of remote peer + UpdateLastNotice(blkHash []byte, blkNumber uint64) + + // TODO + MF() MoFactory +} diff --git a/p2p/p2pmock/mock_hsfactory.go b/p2p/p2pmock/mock_hsfactory.go new file mode 100644 index 000000000..1ed7a6b8b --- /dev/null +++ b/p2p/p2pmock/mock_hsfactory.go @@ -0,0 +1,149 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: p2p/handshake.go + +// Package p2pmock is a generated GoMock package. +package p2pmock + +import ( + "github.com/aergoio/aergo-lib/log" + "github.com/aergoio/aergo/p2p/p2pcommon" + "github.com/aergoio/aergo/types" + "github.com/golang/mock/gomock" + go_libp2p_peer "github.com/libp2p/go-libp2p-peer" + "io" + "reflect" + "time" +) + +// MockHSHandlerFactory is a mock of HSHandlerFactory interface +type MockHSHandlerFactory struct { + ctrl *gomock.Controller + recorder *MockHSHandlerFactoryMockRecorder +} + +// MockHSHandlerFactoryMockRecorder is the mock recorder for MockHSHandlerFactory +type MockHSHandlerFactoryMockRecorder struct { + mock *MockHSHandlerFactory +} + +// NewMockHSHandlerFactory creates a new mock instance +func NewMockHSHandlerFactory(ctrl *gomock.Controller) *MockHSHandlerFactory { + mock := &MockHSHandlerFactory{ctrl: ctrl} + mock.recorder = &MockHSHandlerFactoryMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockHSHandlerFactory) EXPECT() *MockHSHandlerFactoryMockRecorder { + return m.recorder +} + +// CreateHSHandler mocks base method +func (m *MockHSHandlerFactory) CreateHSHandler(outbound bool, pm p2pcommon.PeerManager, actor p2pcommon.ActorService, log *log.Logger, pid go_libp2p_peer.ID) p2pcommon.HSHandler { + ret := m.ctrl.Call(m, "CreateHSHandler", outbound, pm, actor, log, pid) + ret0, _ := ret[0].(p2pcommon.HSHandler) + return ret0 +} + +// CreateHSHandler indicates an expected call of CreateHSHandler +func (mr *MockHSHandlerFactoryMockRecorder) CreateHSHandler(outbound, pm, actor, log, pid interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateHSHandler", reflect.TypeOf((*MockHSHandlerFactory)(nil).CreateHSHandler), outbound, pm, actor, log, pid) +} + +// MockHSHandler is a mock of HSHandler interface +type MockHSHandler struct { + ctrl *gomock.Controller + recorder *MockHSHandlerMockRecorder +} + +// MockHSHandlerMockRecorder is the mock recorder for MockHSHandler +type MockHSHandlerMockRecorder struct { + mock *MockHSHandler +} + +// NewMockHSHandler creates a new mock instance +func NewMockHSHandler(ctrl *gomock.Controller) *MockHSHandler { + mock := &MockHSHandler{ctrl: ctrl} + mock.recorder = &MockHSHandlerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockHSHandler) EXPECT() *MockHSHandlerMockRecorder { + return m.recorder +} + +// Handle mocks base method +func (m *MockHSHandler) Handle(r io.Reader, w io.Writer, ttl time.Duration) (p2pcommon.MsgReadWriter, *types.Status, error) { + ret := m.ctrl.Call(m, "Handle", r, w, ttl) + ret0, _ := ret[0].(p2pcommon.MsgReadWriter) + ret1, _ := ret[1].(*types.Status) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// Handle indicates an expected call of Handle +func (mr *MockHSHandlerMockRecorder) Handle(r, w, ttl interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Handle", reflect.TypeOf((*MockHSHandler)(nil).Handle), r, w, ttl) +} + +// MockinnerHandshaker is a mock of innerHandshaker interface +type MockinnerHandshaker struct { + ctrl *gomock.Controller + recorder *MockinnerHandshakerMockRecorder +} + +// MockinnerHandshakerMockRecorder is the mock recorder for MockinnerHandshaker +type MockinnerHandshakerMockRecorder struct { + mock *MockinnerHandshaker +} + +// NewMockinnerHandshaker creates a new mock instance +func NewMockinnerHandshaker(ctrl *gomock.Controller) *MockinnerHandshaker { + mock := &MockinnerHandshaker{ctrl: ctrl} + mock.recorder = &MockinnerHandshakerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockinnerHandshaker) EXPECT() *MockinnerHandshakerMockRecorder { + return m.recorder +} + +// doForOutbound mocks base method +func (m *MockinnerHandshaker) doForOutbound() (*types.Status, error) { + ret := m.ctrl.Call(m, "doForOutbound") + ret0, _ := ret[0].(*types.Status) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// doForOutbound indicates an expected call of doForOutbound +func (mr *MockinnerHandshakerMockRecorder) doForOutbound() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "doForOutbound", reflect.TypeOf((*MockinnerHandshaker)(nil).doForOutbound)) +} + +// doForInbound mocks base method +func (m *MockinnerHandshaker) doForInbound() (*types.Status, error) { + ret := m.ctrl.Call(m, "doForInbound") + ret0, _ := ret[0].(*types.Status) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// doForInbound indicates an expected call of doForInbound +func (mr *MockinnerHandshakerMockRecorder) doForInbound() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "doForInbound", reflect.TypeOf((*MockinnerHandshaker)(nil).doForInbound)) +} + +// GetMsgRW mocks base method +func (m *MockinnerHandshaker) GetMsgRW() p2pcommon.MsgReadWriter { + ret := m.ctrl.Call(m, "GetMsgRW") + ret0, _ := ret[0].(p2pcommon.MsgReadWriter) + return ret0 +} + +// GetMsgRW indicates an expected call of GetMsgRW +func (mr *MockinnerHandshakerMockRecorder) GetMsgRW() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMsgRW", reflect.TypeOf((*MockinnerHandshaker)(nil).GetMsgRW)) +} diff --git a/p2p/p2pmock/mock_message.go b/p2p/p2pmock/mock_message.go index d113c412d..e1d2b9c0e 100644 --- a/p2p/p2pmock/mock_message.go +++ b/p2p/p2pmock/mock_message.go @@ -1,14 +1,13 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/aergoio/aergo/p2p/p2pcommon (interfaces: Message) +// Source: p2p/p2pcommon/message.go -// Package mock_p2pcommon is a generated GoMock package. +// Package p2pmock is a generated GoMock package. package p2pmock import ( - reflect "reflect" - p2pcommon "github.com/aergoio/aergo/p2p/p2pcommon" gomock "github.com/golang/mock/gomock" + reflect "reflect" ) // MockMessage is a mock of Message interface @@ -34,23 +33,20 @@ func (m *MockMessage) EXPECT() *MockMessageMockRecorder { return m.recorder } -// ID mocks base method -func (m *MockMessage) ID() p2pcommon.MsgID { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ID") - ret0, _ := ret[0].(p2pcommon.MsgID) +// Subprotocol mocks base method +func (m *MockMessage) Subprotocol() p2pcommon.SubProtocol { + ret := m.ctrl.Call(m, "Subprotocol") + ret0, _ := ret[0].(p2pcommon.SubProtocol) return ret0 } -// ID indicates an expected call of ID -func (mr *MockMessageMockRecorder) ID() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ID", reflect.TypeOf((*MockMessage)(nil).ID)) +// Subprotocol indicates an expected call of Subprotocol +func (mr *MockMessageMockRecorder) Subprotocol() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Subprotocol", reflect.TypeOf((*MockMessage)(nil).Subprotocol)) } // Length mocks base method func (m *MockMessage) Length() uint32 { - m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Length") ret0, _ := ret[0].(uint32) return ret0 @@ -58,13 +54,35 @@ func (m *MockMessage) Length() uint32 { // Length indicates an expected call of Length func (mr *MockMessageMockRecorder) Length() *gomock.Call { - mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Length", reflect.TypeOf((*MockMessage)(nil).Length)) } +// Timestamp mocks base method +func (m *MockMessage) Timestamp() int64 { + ret := m.ctrl.Call(m, "Timestamp") + ret0, _ := ret[0].(int64) + return ret0 +} + +// Timestamp indicates an expected call of Timestamp +func (mr *MockMessageMockRecorder) Timestamp() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Timestamp", reflect.TypeOf((*MockMessage)(nil).Timestamp)) +} + +// ID mocks base method +func (m *MockMessage) ID() p2pcommon.MsgID { + ret := m.ctrl.Call(m, "ID") + ret0, _ := ret[0].(p2pcommon.MsgID) + return ret0 +} + +// ID indicates an expected call of ID +func (mr *MockMessageMockRecorder) ID() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ID", reflect.TypeOf((*MockMessage)(nil).ID)) +} + // OriginalID mocks base method func (m *MockMessage) OriginalID() p2pcommon.MsgID { - m.ctrl.T.Helper() ret := m.ctrl.Call(m, "OriginalID") ret0, _ := ret[0].(p2pcommon.MsgID) return ret0 @@ -72,13 +90,11 @@ func (m *MockMessage) OriginalID() p2pcommon.MsgID { // OriginalID indicates an expected call of OriginalID func (mr *MockMessageMockRecorder) OriginalID() *gomock.Call { - mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OriginalID", reflect.TypeOf((*MockMessage)(nil).OriginalID)) } // Payload mocks base method func (m *MockMessage) Payload() []byte { - m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Payload") ret0, _ := ret[0].([]byte) return ret0 @@ -86,34 +102,38 @@ func (m *MockMessage) Payload() []byte { // Payload indicates an expected call of Payload func (mr *MockMessageMockRecorder) Payload() *gomock.Call { - mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Payload", reflect.TypeOf((*MockMessage)(nil).Payload)) } -// Subprotocol mocks base method -func (m *MockMessage) Subprotocol() p2pcommon.SubProtocol { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Subprotocol") - ret0, _ := ret[0].(p2pcommon.SubProtocol) - return ret0 +// MockHandlerFactory is a mock of HandlerFactory interface +type MockHandlerFactory struct { + ctrl *gomock.Controller + recorder *MockHandlerFactoryMockRecorder } -// Subprotocol indicates an expected call of Subprotocol -func (mr *MockMessageMockRecorder) Subprotocol() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Subprotocol", reflect.TypeOf((*MockMessage)(nil).Subprotocol)) +// MockHandlerFactoryMockRecorder is the mock recorder for MockHandlerFactory +type MockHandlerFactoryMockRecorder struct { + mock *MockHandlerFactory } -// Timestamp mocks base method -func (m *MockMessage) Timestamp() int64 { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Timestamp") - ret0, _ := ret[0].(int64) - return ret0 +// NewMockHandlerFactory creates a new mock instance +func NewMockHandlerFactory(ctrl *gomock.Controller) *MockHandlerFactory { + mock := &MockHandlerFactory{ctrl: ctrl} + mock.recorder = &MockHandlerFactoryMockRecorder{mock} + return mock } -// Timestamp indicates an expected call of Timestamp -func (mr *MockMessageMockRecorder) Timestamp() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Timestamp", reflect.TypeOf((*MockMessage)(nil).Timestamp)) +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockHandlerFactory) EXPECT() *MockHandlerFactoryMockRecorder { + return m.recorder +} + +// InsertHandlers mocks base method +func (m *MockHandlerFactory) InsertHandlers(peer p2pcommon.RemotePeer) { + m.ctrl.Call(m, "InsertHandlers", peer) +} + +// InsertHandlers indicates an expected call of InsertHandlers +func (mr *MockHandlerFactoryMockRecorder) InsertHandlers(peer interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertHandlers", reflect.TypeOf((*MockHandlerFactory)(nil).InsertHandlers), peer) } diff --git a/p2p/p2pmock/mock_remotepeer.go b/p2p/p2pmock/mock_remotepeer.go index 820d7156c..c85441ed4 100644 --- a/p2p/p2pmock/mock_remotepeer.go +++ b/p2p/p2pmock/mock_remotepeer.go @@ -1,17 +1,16 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/aergoio/aergo/p2p/p2pcommon (interfaces: RemotePeer) +// Source: p2p/p2pcommon/remotepeer.go -// Package mock_p2pcommon is a generated GoMock package. +// Package p2pmock is a generated GoMock package. package p2pmock import ( - reflect "reflect" - time "time" - p2pcommon "github.com/aergoio/aergo/p2p/p2pcommon" types "github.com/aergoio/aergo/types" gomock "github.com/golang/mock/gomock" go_libp2p_peer "github.com/libp2p/go-libp2p-peer" + reflect "reflect" + time "time" ) // MockRemotePeer is a mock of RemotePeer interface @@ -37,35 +36,8 @@ func (m *MockRemotePeer) EXPECT() *MockRemotePeerMockRecorder { return m.recorder } -// ConsumeRequest mocks base method -func (m *MockRemotePeer) ConsumeRequest(arg0 p2pcommon.MsgID) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "ConsumeRequest", arg0) -} - -// ConsumeRequest indicates an expected call of ConsumeRequest -func (mr *MockRemotePeerMockRecorder) ConsumeRequest(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConsumeRequest", reflect.TypeOf((*MockRemotePeer)(nil).ConsumeRequest), arg0) -} - -// GetReceiver mocks base method -func (m *MockRemotePeer) GetReceiver(arg0 p2pcommon.MsgID) p2pcommon.ResponseReceiver { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetReceiver", arg0) - ret0, _ := ret[0].(p2pcommon.ResponseReceiver) - return ret0 -} - -// GetReceiver indicates an expected call of GetReceiver -func (mr *MockRemotePeerMockRecorder) GetReceiver(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetReceiver", reflect.TypeOf((*MockRemotePeer)(nil).GetReceiver), arg0) -} - // ID mocks base method func (m *MockRemotePeer) ID() go_libp2p_peer.ID { - m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ID") ret0, _ := ret[0].(go_libp2p_peer.ID) return ret0 @@ -73,41 +45,23 @@ func (m *MockRemotePeer) ID() go_libp2p_peer.ID { // ID indicates an expected call of ID func (mr *MockRemotePeerMockRecorder) ID() *gomock.Call { - mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ID", reflect.TypeOf((*MockRemotePeer)(nil).ID)) } -// LastStatus mocks base method -func (m *MockRemotePeer) LastStatus() *types.LastBlockStatus { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "LastStatus") - ret0, _ := ret[0].(*types.LastBlockStatus) - return ret0 -} - -// LastStatus indicates an expected call of LastStatus -func (mr *MockRemotePeerMockRecorder) LastNotice() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LastStatus", reflect.TypeOf((*MockRemotePeer)(nil).LastStatus)) -} - -// MF mocks base method -func (m *MockRemotePeer) MF() p2pcommon.MoFactory { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "MF") - ret0, _ := ret[0].(p2pcommon.MoFactory) +// Meta mocks base method +func (m *MockRemotePeer) Meta() p2pcommon.PeerMeta { + ret := m.ctrl.Call(m, "Meta") + ret0, _ := ret[0].(p2pcommon.PeerMeta) return ret0 } -// MF indicates an expected call of MF -func (mr *MockRemotePeerMockRecorder) MF() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MF", reflect.TypeOf((*MockRemotePeer)(nil).MF)) +// Meta indicates an expected call of Meta +func (mr *MockRemotePeerMockRecorder) Meta() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Meta", reflect.TypeOf((*MockRemotePeer)(nil).Meta)) } // ManageNumber mocks base method func (m *MockRemotePeer) ManageNumber() uint32 { - m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ManageNumber") ret0, _ := ret[0].(uint32) return ret0 @@ -115,27 +69,11 @@ func (m *MockRemotePeer) ManageNumber() uint32 { // ManageNumber indicates an expected call of ManageNumber func (mr *MockRemotePeerMockRecorder) ManageNumber() *gomock.Call { - mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ManageNumber", reflect.TypeOf((*MockRemotePeer)(nil).ManageNumber)) } -// Meta mocks base method -func (m *MockRemotePeer) Meta() p2pcommon.PeerMeta { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Meta") - ret0, _ := ret[0].(p2pcommon.PeerMeta) - return ret0 -} - -// Meta indicates an expected call of Meta -func (mr *MockRemotePeerMockRecorder) Meta() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Meta", reflect.TypeOf((*MockRemotePeer)(nil).Meta)) -} - // Name mocks base method func (m *MockRemotePeer) Name() string { - m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Name") ret0, _ := ret[0].(string) return ret0 @@ -143,122 +81,159 @@ func (m *MockRemotePeer) Name() string { // Name indicates an expected call of Name func (mr *MockRemotePeerMockRecorder) Name() *gomock.Call { - mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockRemotePeer)(nil).Name)) } -// PushTxsNotice mocks base method -func (m *MockRemotePeer) PushTxsNotice(arg0 []types.TxID) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "PushTxsNotice", arg0) +// AddMessageHandler mocks base method +func (m *MockRemotePeer) AddMessageHandler(subProtocol p2pcommon.SubProtocol, handler p2pcommon.MessageHandler) { + m.ctrl.Call(m, "AddMessageHandler", subProtocol, handler) } -// PushTxsNotice indicates an expected call of PushTxsNotice -func (mr *MockRemotePeerMockRecorder) PushTxsNotice(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PushTxsNotice", reflect.TypeOf((*MockRemotePeer)(nil).PushTxsNotice), arg0) +// AddMessageHandler indicates an expected call of AddMessageHandler +func (mr *MockRemotePeerMockRecorder) AddMessageHandler(subProtocol, handler interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddMessageHandler", reflect.TypeOf((*MockRemotePeer)(nil).AddMessageHandler), subProtocol, handler) +} + +// State mocks base method +func (m *MockRemotePeer) State() types.PeerState { + ret := m.ctrl.Call(m, "State") + ret0, _ := ret[0].(types.PeerState) + return ret0 +} + +// State indicates an expected call of State +func (mr *MockRemotePeerMockRecorder) State() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "State", reflect.TypeOf((*MockRemotePeer)(nil).State)) +} + +// LastStatus mocks base method +func (m *MockRemotePeer) LastStatus() *types.LastBlockStatus { + ret := m.ctrl.Call(m, "LastStatus") + ret0, _ := ret[0].(*types.LastBlockStatus) + return ret0 +} + +// LastStatus indicates an expected call of LastStatus +func (mr *MockRemotePeerMockRecorder) LastStatus() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LastStatus", reflect.TypeOf((*MockRemotePeer)(nil).LastStatus)) } // RunPeer mocks base method func (m *MockRemotePeer) RunPeer() { - m.ctrl.T.Helper() m.ctrl.Call(m, "RunPeer") } // RunPeer indicates an expected call of RunPeer func (mr *MockRemotePeerMockRecorder) RunPeer() *gomock.Call { - mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RunPeer", reflect.TypeOf((*MockRemotePeer)(nil).RunPeer)) } +// Stop mocks base method +func (m *MockRemotePeer) Stop() { + m.ctrl.Call(m, "Stop") +} + +// Stop indicates an expected call of Stop +func (mr *MockRemotePeerMockRecorder) Stop() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stop", reflect.TypeOf((*MockRemotePeer)(nil).Stop)) +} + +// SendMessage mocks base method +func (m *MockRemotePeer) SendMessage(msg p2pcommon.MsgOrder) { + m.ctrl.Call(m, "SendMessage", msg) +} + +// SendMessage indicates an expected call of SendMessage +func (mr *MockRemotePeerMockRecorder) SendMessage(msg interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMessage", reflect.TypeOf((*MockRemotePeer)(nil).SendMessage), msg) +} + // SendAndWaitMessage mocks base method -func (m *MockRemotePeer) SendAndWaitMessage(arg0 p2pcommon.MsgOrder, arg1 time.Duration) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SendAndWaitMessage", arg0, arg1) +func (m *MockRemotePeer) SendAndWaitMessage(msg p2pcommon.MsgOrder, ttl time.Duration) error { + ret := m.ctrl.Call(m, "SendAndWaitMessage", msg, ttl) ret0, _ := ret[0].(error) return ret0 } // SendAndWaitMessage indicates an expected call of SendAndWaitMessage -func (mr *MockRemotePeerMockRecorder) SendAndWaitMessage(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendAndWaitMessage", reflect.TypeOf((*MockRemotePeer)(nil).SendAndWaitMessage), arg0, arg1) +func (mr *MockRemotePeerMockRecorder) SendAndWaitMessage(msg, ttl interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendAndWaitMessage", reflect.TypeOf((*MockRemotePeer)(nil).SendAndWaitMessage), msg, ttl) } -// SendMessage mocks base method -func (m *MockRemotePeer) SendMessage(arg0 p2pcommon.MsgOrder) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SendMessage", arg0) +// PushTxsNotice mocks base method +func (m *MockRemotePeer) PushTxsNotice(txHashes []types.TxID) { + m.ctrl.Call(m, "PushTxsNotice", txHashes) } -// SendMessage indicates an expected call of SendMessage -func (mr *MockRemotePeerMockRecorder) SendMessage(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMessage", reflect.TypeOf((*MockRemotePeer)(nil).SendMessage), arg0) +// PushTxsNotice indicates an expected call of PushTxsNotice +func (mr *MockRemotePeerMockRecorder) PushTxsNotice(txHashes interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PushTxsNotice", reflect.TypeOf((*MockRemotePeer)(nil).PushTxsNotice), txHashes) } -// State mocks base method -func (m *MockRemotePeer) State() types.PeerState { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "State") - ret0, _ := ret[0].(types.PeerState) - return ret0 +// ConsumeRequest mocks base method +func (m *MockRemotePeer) ConsumeRequest(msgID p2pcommon.MsgID) { + m.ctrl.Call(m, "ConsumeRequest", msgID) } -// State indicates an expected call of State -func (mr *MockRemotePeerMockRecorder) State() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "State", reflect.TypeOf((*MockRemotePeer)(nil).State)) +// ConsumeRequest indicates an expected call of ConsumeRequest +func (mr *MockRemotePeerMockRecorder) ConsumeRequest(msgID interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConsumeRequest", reflect.TypeOf((*MockRemotePeer)(nil).ConsumeRequest), msgID) } -// Stop mocks base method -func (m *MockRemotePeer) Stop() { - m.ctrl.T.Helper() - m.ctrl.Call(m, "Stop") +// GetReceiver mocks base method +func (m *MockRemotePeer) GetReceiver(id p2pcommon.MsgID) p2pcommon.ResponseReceiver { + ret := m.ctrl.Call(m, "GetReceiver", id) + ret0, _ := ret[0].(p2pcommon.ResponseReceiver) + return ret0 } -// Stop indicates an expected call of Stop -func (mr *MockRemotePeerMockRecorder) Stop() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stop", reflect.TypeOf((*MockRemotePeer)(nil).Stop)) +// GetReceiver indicates an expected call of GetReceiver +func (mr *MockRemotePeerMockRecorder) GetReceiver(id interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetReceiver", reflect.TypeOf((*MockRemotePeer)(nil).GetReceiver), id) } // UpdateBlkCache mocks base method -func (m *MockRemotePeer) UpdateBlkCache(arg0 []byte, arg1 uint64) bool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateBlkCache", arg0, arg1) +func (m *MockRemotePeer) UpdateBlkCache(blkHash []byte, blkNumber uint64) bool { + ret := m.ctrl.Call(m, "UpdateBlkCache", blkHash, blkNumber) ret0, _ := ret[0].(bool) return ret0 } // UpdateBlkCache indicates an expected call of UpdateBlkCache -func (mr *MockRemotePeerMockRecorder) UpdateBlkCache(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateBlkCache", reflect.TypeOf((*MockRemotePeer)(nil).UpdateBlkCache), arg0, arg1) +func (mr *MockRemotePeerMockRecorder) UpdateBlkCache(blkHash, blkNumber interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateBlkCache", reflect.TypeOf((*MockRemotePeer)(nil).UpdateBlkCache), blkHash, blkNumber) +} + +// UpdateTxCache mocks base method +func (m *MockRemotePeer) UpdateTxCache(hashes []types.TxID) []types.TxID { + ret := m.ctrl.Call(m, "UpdateTxCache", hashes) + ret0, _ := ret[0].([]types.TxID) + return ret0 +} + +// UpdateTxCache indicates an expected call of UpdateTxCache +func (mr *MockRemotePeerMockRecorder) UpdateTxCache(hashes interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateTxCache", reflect.TypeOf((*MockRemotePeer)(nil).UpdateTxCache), hashes) } // UpdateLastNotice mocks base method -func (m *MockRemotePeer) UpdateLastNotice(arg0 []byte, arg1 uint64) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "UpdateLastNotice", arg0, arg1) +func (m *MockRemotePeer) UpdateLastNotice(blkHash []byte, blkNumber uint64) { + m.ctrl.Call(m, "UpdateLastNotice", blkHash, blkNumber) } // UpdateLastNotice indicates an expected call of UpdateLastNotice -func (mr *MockRemotePeerMockRecorder) UpdateLastNotice(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateLastNotice", reflect.TypeOf((*MockRemotePeer)(nil).UpdateLastNotice), arg0, arg1) +func (mr *MockRemotePeerMockRecorder) UpdateLastNotice(blkHash, blkNumber interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateLastNotice", reflect.TypeOf((*MockRemotePeer)(nil).UpdateLastNotice), blkHash, blkNumber) } -// UpdateTxCache mocks base method -func (m *MockRemotePeer) UpdateTxCache(arg0 []types.TxID) []types.TxID { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateTxCache", arg0) - ret0, _ := ret[0].([]types.TxID) +// MF mocks base method +func (m *MockRemotePeer) MF() p2pcommon.MoFactory { + ret := m.ctrl.Call(m, "MF") + ret0, _ := ret[0].(p2pcommon.MoFactory) return ret0 } -// UpdateTxCache indicates an expected call of UpdateTxCache -func (mr *MockRemotePeerMockRecorder) UpdateTxCache(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateTxCache", reflect.TypeOf((*MockRemotePeer)(nil).UpdateTxCache), arg0) +// MF indicates an expected call of MF +func (mr *MockRemotePeerMockRecorder) MF() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MF", reflect.TypeOf((*MockRemotePeer)(nil).MF)) } diff --git a/p2p/peermanager.go b/p2p/peermanager.go index 5623287b0..b6f5f8ac4 100644 --- a/p2p/peermanager.go +++ b/p2p/peermanager.go @@ -39,8 +39,8 @@ const ( type peerManager struct { status int32 nt p2pcommon.NetworkTransport - hsFactory HSHandlerFactory - handlerFactory HandlerFactory + hsFactory p2pcommon.HSHandlerFactory + handlerFactory p2pcommon.HandlerFactory actorService p2pcommon.ActorService signer p2pcommon.MsgSigner mf p2pcommon.MoFactory @@ -83,7 +83,7 @@ type PeerEventListener interface { } // NewPeerManager creates a peer manager object. -func NewPeerManager(handlerFactory HandlerFactory, hsFactory HSHandlerFactory, iServ p2pcommon.ActorService, cfg *cfg.Config, signer p2pcommon.MsgSigner, nt p2pcommon.NetworkTransport, mm metric.MetricsManager, logger *log.Logger, mf p2pcommon.MoFactory) p2pcommon.PeerManager { +func NewPeerManager(handlerFactory p2pcommon.HandlerFactory, hsFactory p2pcommon.HSHandlerFactory, iServ p2pcommon.ActorService, cfg *cfg.Config, signer p2pcommon.MsgSigner, nt p2pcommon.NetworkTransport, mm metric.MetricsManager, logger *log.Logger, mf p2pcommon.MoFactory) p2pcommon.PeerManager { p2pConf := cfg.P2P //logger.SetLevel("debug") pm := &peerManager{ @@ -334,7 +334,7 @@ func (pm *peerManager) registerPeer(peerID peer.ID, receivedMeta p2pcommon.PeerM outboundPeer.UpdateBlkCache(status.GetBestBlockHash(), status.GetBestHeight()) // insert Handlers - pm.handlerFactory.insertHandlers(outboundPeer) + pm.handlerFactory.InsertHandlers(outboundPeer) go outboundPeer.RunPeer() pm.insertPeer(peerID, outboundPeer) diff --git a/p2p/remotepeer.go b/p2p/remotepeer.go index 7dc678cba..8dadf6ced 100644 --- a/p2p/remotepeer.go +++ b/p2p/remotepeer.go @@ -145,6 +145,10 @@ func (p *remotePeerImpl) Name() string { return p.name } +func (p *remotePeerImpl) AddMessageHandler(subProtocol p2pcommon.SubProtocol, handler p2pcommon.MessageHandler) { + p.handlers[subProtocol] = handler +} + func (p *remotePeerImpl) MF() p2pcommon.MoFactory { return p.mf } From 9127bea078045a05f52d94b8012f3641912ddbb4 Mon Sep 17 00:00:00 2001 From: Hayarobi Park Date: Thu, 11 Apr 2019 18:09:25 +0900 Subject: [PATCH 032/148] [P2P] Improve peer discovery - Tune discovery interval, adding more weight to polaris - refactor to change discovery policy easily later. --- p2p/p2p.go | 2 +- p2p/p2pcommon/pool.go | 50 +++++++ p2p/peerfinder.go | 165 +++++++++++++++++++++++ p2p/peerfinder_test.go | 290 +++++++++++++++++++++++++++++++++++++++++ p2p/peermanager.go | 129 ++++++++---------- 5 files changed, 561 insertions(+), 75 deletions(-) create mode 100644 p2p/p2pcommon/pool.go create mode 100644 p2p/peerfinder.go create mode 100644 p2p/peerfinder_test.go diff --git a/p2p/p2p.go b/p2p/p2p.go index 54c662c66..a63ae57c3 100644 --- a/p2p/p2p.go +++ b/p2p/p2p.go @@ -277,7 +277,7 @@ func (p2ps *P2P) Receive(context actor.Context) { } } -// TODO need refactoring. this code is copied from subprotcoladdrs.go +// TODO need refactoring. this code is copied from subproto/addrs.go func (p2ps *P2P) checkAndAddPeerAddresses(peers []*types.PeerAddress) { selfPeerID := p2ps.pm.SelfNodeID() peerMetas := make([]p2pcommon.PeerMeta, 0, len(peers)) diff --git a/p2p/p2pcommon/pool.go b/p2p/p2pcommon/pool.go new file mode 100644 index 000000000..bf1a43884 --- /dev/null +++ b/p2p/p2pcommon/pool.go @@ -0,0 +1,50 @@ +/* + * @file + * @copyright defined in aergo/LICENSE.txt + */ + +package p2pcommon + +import ( + "errors" + "github.com/libp2p/go-libp2p-peer" + "time" +) + +const ( + ManagerInterval = time.Minute + + PolarisQueryInterval = time.Minute * 10 + PeerQueryInterval = time.Hour + PeerFirstInterval = time.Second * 4 + MaxConcurrentHandshake = 5 +) + +var ( + ErrNoWaitings = errors.New("no waiting peer exists") +) + +type PeerEventListener interface { + OnPeerConnect(pid peer.ID) + OnPeerDisconnect(peer RemotePeer) +} + +// PeerFinder works for collecting peer candidate. +// It queries to Polaris or other connected peer efficiently. +// It determine if peer is +// NOTE that this object is not thread safe by itself. +type PeerFinder interface { + PeerEventListener + OnDiscoveredPeers(metas []PeerMeta) + + // Check if it need to discover more peers and send query request to polaris or other peers if needed. + CheckAndFill() +} + +type WaitingPeer struct { + Meta PeerMeta + TrialCnt int + NextTrial time.Time + + LastResult error +} diff --git a/p2p/peerfinder.go b/p2p/peerfinder.go new file mode 100644 index 000000000..14c3333ec --- /dev/null +++ b/p2p/peerfinder.go @@ -0,0 +1,165 @@ +/* + * @file + * @copyright defined in aergo/LICENSE.txt + */ + +package p2p + +import ( + "context" + "github.com/aergoio/aergo-lib/log" + "github.com/aergoio/aergo/message" + "github.com/aergoio/aergo/p2p/p2pcommon" + "github.com/aergoio/aergo/p2p/p2putil" + "github.com/libp2p/go-libp2p-peer" + "github.com/pkg/errors" + "time" +) + +const ( + macConcurrentQueryCount = 4 + // TODO manage cooltime and reconnect interval together in same file. + firstReconnectColltime = time.Minute +) + +func NewPeerFinder(logger *log.Logger, pm *peerManager, actorService p2pcommon.ActorService, maxCap int, useDiscover, usePolaris bool) p2pcommon.PeerFinder { + if !useDiscover { + return &staticPeerFinder{pm:pm, logger:logger} + } else { + dp := &dynamicPeerFinder{logger: logger, pm: pm, actorService: actorService, maxCap: maxCap, usePolaris:usePolaris} + dp.qStats = make(map[peer.ID]*queryStat) + return dp + } + +} + +// staticPeerFinder is for BP or backup node. it will not query to polaris or other peers +type staticPeerFinder struct { + pm *peerManager + logger *log.Logger +} + +func (dp *staticPeerFinder) OnPeerDisconnect(peer p2pcommon.RemotePeer) { + if _, ok := dp.pm.designatedPeers[peer.ID()]; ok { + // These peers must have cool time. + dp.pm.waitingPeers[peer.ID()] = &p2pcommon.WaitingPeer{Meta: peer.Meta(), NextTrial: time.Now().Add(firstReconnectColltime)} + dp.pm.addAwait(peer.Meta()) + } +} + +func (dp *staticPeerFinder) OnPeerConnect(pid peer.ID) { + if _, ok := dp.pm.designatedPeers[pid]; ok { + delete(dp.pm.waitingPeers, pid) + dp.pm.cancelAwait(pid) + } +} + +func (dp *staticPeerFinder) OnDiscoveredPeers(metas []p2pcommon.PeerMeta) { +} + +func (dp *staticPeerFinder) CheckAndFill() { + // find if there are not connected designated peers. designated peer + for _, meta := range dp.pm.designatedPeers { + if _, found := dp.pm.remotePeers[meta.ID]; !found { + if _, foundInWait := dp.pm.waitingPeers[meta.ID]; !foundInWait { + dp.pm.waitingPeers[meta.ID] = &p2pcommon.WaitingPeer{Meta: meta, NextTrial: time.Now()} + } + } + } +} + +func (dp *staticPeerFinder) AddWaitings(metas []p2pcommon.PeerMeta) { +} + +func (dp *staticPeerFinder) PickPeer(ctx context.Context) (p2pcommon.PeerMeta, error) { + return p2pcommon.PeerMeta{}, errors.New("no peers in pool") +} + +var _ p2pcommon.PeerFinder = (*staticPeerFinder)(nil) + +// dynamicPeerFinder is triggering map query to Polaris or address query to other connected peer +// to discover peer +// It is not thread-safe. Thread safety is responsible to the caller. +type dynamicPeerFinder struct { + logger *log.Logger + pm *peerManager + actorService p2pcommon.ActorService + usePolaris bool + + // qStats are logs of query. all connected peers must exist queryStat. + qStats map[peer.ID]*queryStat + maxCap int + + polarisTurn time.Time +} + +var _ p2pcommon.PeerFinder = (*dynamicPeerFinder)(nil) + +func (dp *dynamicPeerFinder) OnPeerDisconnect(peer p2pcommon.RemotePeer) { + // And check if to connect more peers + delete(dp.qStats, peer.ID()) + if _, ok := dp.pm.designatedPeers[peer.ID()]; ok { + dp.logger.Debug().Str(p2putil.LogPeerID, peer.Name()).Msg("server will try to reconnect designated peer after cooltime") + // These peers must have cool time. + dp.pm.waitingPeers[peer.ID()] = &p2pcommon.WaitingPeer{Meta: peer.Meta(), NextTrial: time.Now().Add(firstReconnectColltime)} + dp.pm.addAwait(peer.Meta()) + } +} + +func (dp *dynamicPeerFinder) OnPeerConnect(pid peer.ID) { + dp.logger.Debug().Str(p2putil.LogPeerID, p2putil.ShortForm(pid)).Msg("check and remove peerid in pool") + if stat := dp.qStats[pid]; stat == nil { + // first query will be sent quickly + dp.qStats[pid] = &queryStat{pid: pid, nextTurn: time.Now().Add(p2pcommon.PeerFirstInterval)} + } + // remove peer from wait pool + delete(dp.pm.waitingPeers, pid) + dp.pm.cancelAwait(pid) +} + +func (dp *dynamicPeerFinder) OnDiscoveredPeers(metas []p2pcommon.PeerMeta) { + for _, meta := range metas { + if _, ok := dp.qStats[meta.ID]; ok { + // skip connected peer + continue + } else if _, ok := dp.pm.waitingPeers[meta.ID]; ok { + continue + } + dp.pm.waitingPeers[meta.ID] = &p2pcommon.WaitingPeer{Meta: meta, NextTrial: time.Now()} + } +} + +func (dp *dynamicPeerFinder) CheckAndFill() { + toConnCount := dp.maxCap - len(dp.pm.waitingPeers) + if toConnCount <= 0 { + // if enough peer is collected already, skip collect + return + } + now := time.Now() + // query to polaris + if dp.usePolaris && now.After(dp.polarisTurn) { + dp.polarisTurn = now.Add(p2pcommon.PolarisQueryInterval) + dp.logger.Debug().Time("next_turn", dp.polarisTurn).Msg("quering to polaris") + dp.actorService.SendRequest(message.P2PSvc, &message.MapQueryMsg{Count: MaxAddrListSizePolaris}) + } + // query to peers + queried := 0 + for _, stat := range dp.qStats { + if stat.nextTurn.Before(now) { + // slowly collect + stat.lastCheck = now + stat.nextTurn = now.Add(p2pcommon.PeerQueryInterval) + dp.actorService.SendRequest(message.P2PSvc, &message.GetAddressesMsg{ToWhom: stat.pid, Size: MaxAddrListSizePeer, Offset: 0}) + queried++ + if queried >= macConcurrentQueryCount { + break + } + } + } +} + +type queryStat struct { + pid peer.ID + lastCheck time.Time + nextTurn time.Time +} diff --git a/p2p/peerfinder_test.go b/p2p/peerfinder_test.go new file mode 100644 index 000000000..03ef6f344 --- /dev/null +++ b/p2p/peerfinder_test.go @@ -0,0 +1,290 @@ +/* + * @file + * @copyright defined in aergo/LICENSE.txt + */ + +package p2p + +import ( + "reflect" + "testing" + "time" + + "github.com/aergoio/aergo-lib/log" + "github.com/aergoio/aergo/p2p/p2pcommon" + "github.com/aergoio/aergo/p2p/p2pmock" + "github.com/aergoio/aergo/p2p/p2putil" + "github.com/golang/mock/gomock" + crypto "github.com/libp2p/go-libp2p-crypto" + "github.com/libp2p/go-libp2p-peer" +) + +const desigCnt = 10 + +var ( + desigIDs []peer.ID + desigPeers []p2pcommon.PeerMeta + desigPeerMap = make(map[peer.ID]p2pcommon.PeerMeta) + + unknowIDs []peer.ID + unknowPeers []p2pcommon.PeerMeta +) + +func init() { + desigIDs = make([]peer.ID, desigCnt) + desigPeers = make([]p2pcommon.PeerMeta, desigCnt) + for i := 0; i < desigCnt; i++ { + priv, _, _ := crypto.GenerateKeyPair(crypto.Secp256k1, 256) + pid, _ := peer.IDFromPrivateKey(priv) + desigIDs[i] = pid + desigPeers[i] = p2pcommon.PeerMeta{ID: pid, Designated: true} + desigPeerMap[desigIDs[i]] = desigPeers[i] + } + unknowIDs = make([]peer.ID, desigCnt) + unknowPeers = make([]p2pcommon.PeerMeta, desigCnt) + for i := 0; i < desigCnt; i++ { + priv, _, _ := crypto.GenerateKeyPair(crypto.Secp256k1, 256) + pid, _ := peer.IDFromPrivateKey(priv) + unknowIDs[i] = pid + unknowPeers[i] = p2pcommon.PeerMeta{ID: pid, Designated: false} + } +} +func createDummyPM() *peerManager { + dummyPM := &peerManager{designatedPeers: desigPeerMap, + remotePeers: make(map[peer.ID]*remotePeerImpl), + awaitPeers: make(map[peer.ID]*reconnectJob, 10), + waitingPeers: make(map[peer.ID]*p2pcommon.WaitingPeer, 10), + } + return dummyPM +} + +func TestNewPeerFinder(t *testing.T) { + ctrl := gomock.NewController(t) + + type args struct { + useDiscover bool + usePolaris bool + } + tests := []struct { + name string + args args + want p2pcommon.PeerFinder + }{ + {"Tstatic", args{false, false}, &staticPeerFinder{}}, + {"TstaticWPolaris", args{false, true}, &staticPeerFinder{}}, + {"Tdyn", args{true, false}, &dynamicPeerFinder{}}, + {"TdynWPolaris", args{true, true}, &dynamicPeerFinder{}}, + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + dummyPM := createDummyPM() + mockActor := p2pmock.NewMockActorService(ctrl) + got := NewPeerFinder(logger, dummyPM, mockActor, 10, tt.args.useDiscover, tt.args.usePolaris) + if reflect.TypeOf(got) != reflect.TypeOf(tt.want) { + t.Errorf("NewPeerFinder() = %v, want %v", reflect.TypeOf(got), reflect.TypeOf(tt.want)) + } + }) + } +} + +func Test_staticPeerFinder_OnDiscoveredPeers(t *testing.T) { + ctrl := gomock.NewController(t) + + type args struct { + metas []p2pcommon.PeerMeta + } + tests := []struct { + name string + args args + wantCount int + }{ + {"TSingleDesign", args{desigPeers[:1]}, 0}, + {"TAllDesign", args{desigPeers}, 0}, + {"TNewID", args{unknowPeers}, 0}, + {"TMixedIDs", args{append(unknowPeers[:5], desigPeers[:5]...)}, 0}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + dummyPM := createDummyPM() + mockActor := p2pmock.NewMockActorService(ctrl) + dp := NewPeerFinder(logger, dummyPM, mockActor, 10, false, false) + + dp.OnDiscoveredPeers(tt.args.metas) + if len(dummyPM.waitingPeers) != tt.wantCount { + t.Errorf("count waitingPeer %v, want %v", len(dummyPM.waitingPeers), tt.wantCount) + } + }) + } +} + +func Test_dynamicPeerFinder_OnDiscoveredPeers(t *testing.T) { + ctrl := gomock.NewController(t) + + type args struct { + preConnected []peer.ID + metas []p2pcommon.PeerMeta + } + tests := []struct { + name string + args args + wantCount int + }{ + {"TAllNew", args{nil, desigPeers[:1]}, 1}, + {"TAllExist", args{desigIDs, desigPeers[:5]}, 0}, + {"TMixedIDs", args{desigIDs, append(unknowPeers[:5], desigPeers[:5]...)}, 5}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + dummyPM := createDummyPM() + mockActor := p2pmock.NewMockActorService(ctrl) + dp := NewPeerFinder(logger, dummyPM, mockActor, 10, true, false) + for _, id := range tt.args.preConnected { + dummyPM.remotePeers[id] = &remotePeerImpl{} + dp.OnPeerConnect(id) + } + + dp.OnDiscoveredPeers(tt.args.metas) + if len(dummyPM.waitingPeers) != tt.wantCount { + t.Errorf("count waitingPeer %v, want %v", len(dummyPM.waitingPeers), tt.wantCount) + } + }) + } +} + +func Test_staticPeerFinder_OnPeerDisconnect(t *testing.T) { + ctrl := gomock.NewController(t) + + type args struct { + inMeta p2pcommon.PeerMeta + } + tests := []struct { + name string + args args + wantCount int + }{ + {"TDesgintedPeer", args{desigPeers[0]}, 1}, + // it should not occur, though. + {"TNonPeer", args{unknowPeers[0]}, 0}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + dummyPM := createDummyPM() + mockActor := p2pmock.NewMockActorService(ctrl) + mockPeer := p2pmock.NewMockRemotePeer(ctrl) + mockPeer.EXPECT().ID().Return(tt.args.inMeta.ID).AnyTimes() + mockPeer.EXPECT().Meta().Return(tt.args.inMeta).AnyTimes() + + dp := NewPeerFinder(logger, dummyPM, mockActor, 10, false, false) + dp.OnPeerDisconnect(mockPeer) + + if len(dummyPM.waitingPeers) != tt.wantCount { + t.Errorf("count waitingPeer %v, want %v", len(dummyPM.waitingPeers), tt.wantCount) + } + }) + } +} + +func Test_dynamicPeerFinder_OnPeerDisconnect(t *testing.T) { + ctrl := gomock.NewController(t) + + type args struct { + preConnected []peer.ID + inMeta p2pcommon.PeerMeta + } + tests := []struct { + name string + args args + wantCount int + }{ + {"TDesgintedPeer", args{desigIDs, desigPeers[0]}, 1}, + // it should not occur, though. + {"TNonPeer", args{unknowIDs, unknowPeers[0]}, 0}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + dummyPM := createDummyPM() + mockActor := p2pmock.NewMockActorService(ctrl) + mockPeer := p2pmock.NewMockRemotePeer(ctrl) + mockPeer.EXPECT().ID().Return(tt.args.inMeta.ID).AnyTimes() + mockPeer.EXPECT().Meta().Return(tt.args.inMeta).AnyTimes() + mockPeer.EXPECT().Name().Return(p2putil.ShortMetaForm(tt.args.inMeta)).AnyTimes() + + dp := NewPeerFinder(logger, dummyPM, mockActor, 10, true, false).(*dynamicPeerFinder) + for _, id := range tt.args.preConnected { + dummyPM.remotePeers[id] = &remotePeerImpl{} + dp.OnPeerConnect(id) + } + statCnt := len(dp.qStats) + dp.OnPeerDisconnect(mockPeer) + if len(dummyPM.waitingPeers) != tt.wantCount { + t.Errorf("count waitingPeer %v, want %v", len(dummyPM.waitingPeers), tt.wantCount) + } + if statCnt-1 != len(dp.qStats) { + t.Errorf("count of query peers was not decreaded %v, want %v", len(dp.qStats), statCnt) + } + }) + } +} + +func Test_staticPeerFinder_OnPeerConnect(t *testing.T) { + type fields struct { + pm *peerManager + logger *log.Logger + } + type args struct { + pid peer.ID + } + tests := []struct { + name string + fields fields + args args + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + dp := &staticPeerFinder{ + pm: tt.fields.pm, + logger: tt.fields.logger, + } + dp.OnPeerConnect(tt.args.pid) + }) + } +} + +func Test_dynamicPeerFinder_OnPeerConnect(t *testing.T) { + type fields struct { + logger *log.Logger + pm *peerManager + actorService p2pcommon.ActorService + usePolaris bool + qStats map[peer.ID]*queryStat + maxCap int + polarisTurn time.Time + } + type args struct { + pid peer.ID + } + tests := []struct { + name string + fields fields + args args + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + dp := &dynamicPeerFinder{ + logger: tt.fields.logger, + pm: tt.fields.pm, + actorService: tt.fields.actorService, + usePolaris: tt.fields.usePolaris, + qStats: tt.fields.qStats, + maxCap: tt.fields.maxCap, + polarisTurn: tt.fields.polarisTurn, + } + dp.OnPeerConnect(tt.args.pid) + }) + } +} diff --git a/p2p/peermanager.go b/p2p/peermanager.go index b6f5f8ac4..a1a4db39c 100644 --- a/p2p/peermanager.go +++ b/p2p/peermanager.go @@ -46,21 +46,25 @@ type peerManager struct { mf p2pcommon.MoFactory mm metric.MetricsManager + peerFinder p2pcommon.PeerFinder + // designatedPeers and hiddenPeerSet is set in construction time once and will not be changed hiddenPeerSet map[peer.ID]bool mutex *sync.Mutex manageNumber uint32 remotePeers map[peer.ID]p2pcommon.RemotePeer - peerPool map[peer.ID]p2pcommon.PeerMeta - conf *cfg.P2PConfig + waitingPeers map[peer.ID]*p2pcommon.WaitingPeer + + conf *cfg.P2PConfig // peerCache is copy-on-write style peerCache []p2pcommon.RemotePeer - addPeerChannel chan p2pcommon.PeerMeta - fillPoolChannel chan []p2pcommon.PeerMeta - finishChannel chan struct{} - eventListeners []PeerEventListener + addPeerChannel chan p2pcommon.PeerMeta + removePeerChannel chan p2pcommon.RemotePeer + fillPoolChannel chan []p2pcommon.PeerMeta + finishChannel chan struct{} + eventListeners []PeerEventListener // designatedPeers map[peer.ID]p2pcommon.PeerMeta @@ -104,15 +108,17 @@ func NewPeerManager(handlerFactory p2pcommon.HandlerFactory, hsFactory p2pcommon remotePeers: make(map[peer.ID]p2pcommon.RemotePeer, p2pConf.NPMaxPeers), - awaitPeers: make(map[peer.ID]*reconnectJob, p2pConf.NPPeerPool), - peerPool: make(map[peer.ID]p2pcommon.PeerMeta, p2pConf.NPPeerPool), - peerCache: make([]p2pcommon.RemotePeer, 0, p2pConf.NPMaxPeers), - awaitDone: make(chan struct{}), + awaitPeers: make(map[peer.ID]*reconnectJob, p2pConf.NPPeerPool), + waitingPeers: make(map[peer.ID]*p2pcommon.WaitingPeer, p2pConf.NPPeerPool), - addPeerChannel: make(chan p2pcommon.PeerMeta, 2), - fillPoolChannel: make(chan []p2pcommon.PeerMeta, 2), - eventListeners: make([]PeerEventListener, 0, 4), - finishChannel: make(chan struct{}), + peerCache: make([]p2pcommon.RemotePeer, 0, p2pConf.NPMaxPeers), + awaitDone: make(chan struct{}), + + addPeerChannel: make(chan p2pcommon.PeerMeta, 2), + removePeerChannel: make(chan p2pcommon.RemotePeer), + fillPoolChannel: make(chan []p2pcommon.PeerMeta, 2), + eventListeners: make([]PeerEventListener, 0, 4), + finishChannel: make(chan struct{}), } // additional initializations @@ -139,25 +145,26 @@ func (pm *peerManager) init() { } pm.hiddenPeerSet[pid] = true } + + pm.peerFinder = NewPeerFinder(pm.logger, pm, pm.actorService, pm.conf.NPPeerPool, pm.conf.NPDiscoverPeers, pm.conf.NPUsePolaris) } func (pm *peerManager) Start() error { - go pm.runManagePeers() // need to start listen after chainservice is read to init // FIXME: adhoc code go func() { //time.Sleep(time.Second * 3) - pm.nt.AddStreamHandler(p2pcommon.AergoP2PSub, pm.onConnect) pm.logger.Info().Str("version", string(p2pcommon.AergoP2PSub)).Msg("Starting p2p listening") + pm.nt.AddStreamHandler(p2pcommon.AergoP2PSub, pm.onConnect) // addition should start after all modules are started - go func() { - time.Sleep(time.Second * 2) - for _, meta := range pm.designatedPeers { - pm.addPeerChannel <- meta - } - }() + time.Sleep(time.Second * 2) + dPeers := make([]p2pcommon.PeerMeta,len(pm.designatedPeers)) + for _, meta := range pm.designatedPeers { + dPeers = append(dPeers, meta) + } + pm.fillPoolChannel <- dPeers }() return nil @@ -202,15 +209,20 @@ MANLOOP: select { case meta := <-pm.addPeerChannel: if pm.addOutboundPeer(meta) { + pm.peerFinder.OnPeerConnect(meta.ID) pm.cancelAwait(meta.ID) } + case peer := <-pm.removePeerChannel: + if pm.removePeer(peer) { + pm.peerFinder.OnPeerDisconnect(peer) + } case <-initialTimer.C: initialTimer.Stop() - pm.checkAndCollectPeerListFromAll() + pm.peerFinder.CheckAndFill() case <-addrTicker.C: - pm.checkAndCollectPeerListFromAll() + pm.peerFinder.CheckAndFill() case peerMetas := <-pm.fillPoolChannel: - pm.tryFillPool(&peerMetas) + pm.peerFinder.OnDiscoveredPeers(peerMetas) case <-pm.finishChannel: addrTicker.Stop() break MANLOOP @@ -232,6 +244,8 @@ MANLOOP: CLEANUPLOOP: for { select { + case peer := <-pm.removePeerChannel: + pm.removePeer(peer) case <-finishPoll.C: pm.mutex.Lock() if len(pm.remotePeers) == 0 { @@ -365,19 +379,15 @@ func (pm *peerManager) sendGoAway(rw p2pcommon.MsgReadWriter, msg string) { rw.WriteMsg(container) } -func (pm *peerManager) AddNewPeer(peer p2pcommon.PeerMeta) { - pm.addPeerChannel <- peer +func (pm *peerManager) AddNewPeer(meta p2pcommon.PeerMeta) { + pm.addPeerChannel <- meta } func (pm *peerManager) RemovePeer(peer p2pcommon.RemotePeer) { - pm.removePeer(peer) + pm.removePeerChannel <- peer } func (pm *peerManager) NotifyPeerHandshake(peerID peer.ID) { - // TODO code smell. - if pm.conf.NPDiscoverPeers { - pm.checkAndCollectPeerList(peerID) - } } func (pm *peerManager) NotifyPeerAddressReceived(metas []p2pcommon.PeerMeta) { @@ -409,9 +419,6 @@ func (pm *peerManager) removePeer(peer p2pcommon.RemotePeer) bool { listener.OnRemovePeer(peerID) } - if meta, found := pm.designatedPeers[peer.ID()]; found { - pm.addAwait(meta) - } return true } @@ -431,41 +438,6 @@ func (pm *peerManager) onConnect(s inet.Stream) { } } -func (pm *peerManager) checkAndCollectPeerListFromAll() { - if pm.hasEnoughPeers() { - return - } - if pm.conf.NPUsePolaris { - pm.logger.Debug().Msg("Sending map query to polaris") - pm.actorService.SendRequest(message.P2PSvc, &message.MapQueryMsg{Count: MaxAddrListSizePolaris}) - } - - // if server is not discover new peer, such as of BP or backup node, it does not send addresses reqeust to other peer. - // These types are only connect to designated peers. - if pm.conf.NPDiscoverPeers { - // not strictly need to check peers. so use cache instead - for _, remotePeer := range pm.peerCache { - pm.actorService.SendRequest(message.P2PSvc, &message.GetAddressesMsg{ToWhom: remotePeer.ID(), Size: MaxAddrListSizePeer, Offset: 0}) - } - } -} - -func (pm *peerManager) checkAndCollectPeerList(ID peer.ID) { - if pm.hasEnoughPeers() { - return - } - rPeer, ok := pm.GetPeer(ID) - if !ok { - pm.logger.Warn().Str(p2putil.LogFullID, ID.Pretty()).Msg("invalid peer id") - return - } - pm.actorService.SendRequest(message.P2PSvc, &message.GetAddressesMsg{ToWhom: rPeer.ID(), Size: 20, Offset: 0}) -} - -func (pm *peerManager) hasEnoughPeers() bool { - return len(pm.peerPool) >= pm.conf.NPPeerPool -} - // tryConnectPeers should be called in runManagePeers() only func (pm *peerManager) tryFillPool(metas *[]p2pcommon.PeerMeta) { added := make([]p2pcommon.PeerMeta, 0, len(*metas)) @@ -475,12 +447,12 @@ func (pm *peerManager) tryFillPool(metas *[]p2pcommon.PeerMeta) { invalid = append(invalid, p2putil.ShortMetaForm(meta)) continue } - _, found := pm.peerPool[meta.ID] + _, found := pm.waitingPeers[meta.ID] if !found { // change some properties meta.Outbound = true meta.Designated = false - pm.peerPool[meta.ID] = meta + pm.waitingPeers[meta.ID] = &p2pcommon.WaitingPeer{Meta: meta, NextTrial: time.Now()} added = append(added, meta) } } @@ -494,16 +466,25 @@ func (pm *peerManager) tryFillPool(metas *[]p2pcommon.PeerMeta) { // tryConnectPeers should be called in runManagePeers() only func (pm *peerManager) tryConnectPeers() { remained := pm.conf.NPMaxPeers - len(pm.remotePeers) - for ID, meta := range pm.peerPool { + now := time.Now() + for ID, wp := range pm.waitingPeers { if _, found := pm.GetPeer(ID); found { - delete(pm.peerPool, ID) + delete(pm.waitingPeers, ID) + continue + } + if wp.NextTrial.After(now) { + // cool time is not over. try connect later continue } + meta := wp.Meta if meta.IPAddress == "" || meta.Port == 0 { pm.logger.Warn().Str(p2putil.LogPeerID, p2putil.ShortForm(meta.ID)).Str("addr", meta.IPAddress). Uint32("port", meta.Port).Msg("Invalid peer meta informations") + // remove invalid peer + delete(pm.waitingPeers, ID) continue } + // TODO // in same go rountine. pm.addOutboundPeer(meta) remained-- From 40dd01a88c6f372992c47bcec99b0b796c7ebaeb Mon Sep 17 00:00:00 2001 From: Hayarobi Park Date: Mon, 15 Apr 2019 14:48:33 +0900 Subject: [PATCH 033/148] [P2P] Improve peer (re)connect - Change thread model of managing discovery, reconnect and connected peers. - Concurrently try to connect multiple peers - Fix hang of peer manager in some case --- p2p/configs.go | 2 +- p2p/mockMsgSigner_test.go | 41 ---- p2p/p2pcommon/others.go | 3 +- p2p/p2pcommon/pool.go | 32 ++- p2p/p2pmock/mock_peerfinder.go | 194 ++++++++++++++++++ p2p/peerfinder.go | 61 +----- p2p/peerfinder_test.go | 186 +++-------------- p2p/peermanager.go | 363 ++++++++++----------------------- p2p/peermanager_test.go | 71 ++++++- p2p/reconnect.go | 39 ---- p2p/remotepeer.go | 8 +- p2p/waitpeermanager.go | 317 ++++++++++++++++++++++++++++ p2p/waitpeermanager_test.go | 128 ++++++++++++ 13 files changed, 884 insertions(+), 561 deletions(-) delete mode 100644 p2p/mockMsgSigner_test.go create mode 100644 p2p/p2pmock/mock_peerfinder.go create mode 100644 p2p/waitpeermanager.go create mode 100644 p2p/waitpeermanager_test.go diff --git a/p2p/configs.go b/p2p/configs.go index bb282eb1b..d6c211cd6 100644 --- a/p2p/configs.go +++ b/p2p/configs.go @@ -39,7 +39,7 @@ const ( // constants for node discovery const ( - DiscoveryQueryInterval = time.Minute * 5 + DiscoveryQueryInterval = time.Minute * 1 MaxAddrListSizePolaris = 200 MaxAddrListSizePeer = 50 diff --git a/p2p/mockMsgSigner_test.go b/p2p/mockMsgSigner_test.go deleted file mode 100644 index 557db2ba3..000000000 --- a/p2p/mockMsgSigner_test.go +++ /dev/null @@ -1,41 +0,0 @@ -package p2p - -import ( - "github.com/libp2p/go-libp2p-peer" -) -import "github.com/stretchr/testify/mock" - -import "github.com/aergoio/aergo/types" - -// mockMsgSigner is an autogenerated mock type for the msgSigner type -type mockMsgSigner struct { - mock.Mock -} - -// signMsg provides a mock function with given fields: msg -func (_m *mockMsgSigner) signMsg(msg *types.P2PMessage) error { - ret := _m.Called(msg) - - var r0 error - if rf, ok := ret.Get(0).(func(*types.P2PMessage) error); ok { - r0 = rf(msg) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// verifyMsg provides a mock function with given fields: msg, pubKey -func (_m *mockMsgSigner) verifyMsg(msg *types.P2PMessage, senderID peer.ID) error { - ret := _m.Called(msg, senderID) - - var r0 error - if rf, ok := ret.Get(0).(func(*types.P2PMessage, peer.ID) error); ok { - r0 = rf(msg, senderID) - } else { - r0 = ret.Error(0) - } - - return r0 -} diff --git a/p2p/p2pcommon/others.go b/p2p/p2pcommon/others.go index f1ba3b47d..fdf326bae 100644 --- a/p2p/p2pcommon/others.go +++ b/p2p/p2pcommon/others.go @@ -54,8 +54,7 @@ type PeerManager interface { AddNewPeer(peer PeerMeta) // Remove peer from peer list. Peer dispose relative resources and stop itself, and then call RemovePeer to peermanager RemovePeer(peer RemotePeer) - // NotifyPeerHandshake is called after remote peer is completed handshake and ready to receive or send - NotifyPeerHandshake(peerID peer.ID) + NotifyPeerAddressReceived([]PeerMeta) // GetPeer return registered(handshaked) remote peer object diff --git a/p2p/p2pcommon/pool.go b/p2p/p2pcommon/pool.go index bf1a43884..39f43ab6c 100644 --- a/p2p/p2pcommon/pool.go +++ b/p2p/p2pcommon/pool.go @@ -7,17 +7,20 @@ package p2pcommon import ( "errors" + net "github.com/libp2p/go-libp2p-net" "github.com/libp2p/go-libp2p-peer" "time" ) const ( - ManagerInterval = time.Minute + WaitingPeerManagerInterval = time.Minute PolarisQueryInterval = time.Minute * 10 PeerQueryInterval = time.Hour PeerFirstInterval = time.Second * 4 + MaxConcurrentHandshake = 5 + ) var ( @@ -35,12 +38,25 @@ type PeerEventListener interface { // NOTE that this object is not thread safe by itself. type PeerFinder interface { PeerEventListener - OnDiscoveredPeers(metas []PeerMeta) // Check if it need to discover more peers and send query request to polaris or other peers if needed. CheckAndFill() } +// WaitingPeerManager manage waint peer pool. +type WaitingPeerManager interface { + PeerEventListener + // OnDiscoveredPeers is called when response of discover query came from polaris or other peer. + // It returns the count of previously unknown peers. + OnDiscoveredPeers(metas []PeerMeta) int + // OnWorkDone + OnWorkDone(result ConnWorkResult) + + CheckAndConnect() + + OnInboundConn(s net.Stream) +} + type WaitingPeer struct { Meta PeerMeta TrialCnt int @@ -48,3 +64,15 @@ type WaitingPeer struct { LastResult error } + +type ConnWorkResult struct { + Inbound bool + Seq uint32 + // TargetPeer is nil if Inbound is true + TargetPeer *WaitingPeer + Meta PeerMeta + + P2PVer uint32 + Result error + Peer RemotePeer +} \ No newline at end of file diff --git a/p2p/p2pmock/mock_peerfinder.go b/p2p/p2pmock/mock_peerfinder.go new file mode 100644 index 000000000..aa59d58c0 --- /dev/null +++ b/p2p/p2pmock/mock_peerfinder.go @@ -0,0 +1,194 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: p2p/p2pcommon/pool.go + +// Package p2pmock is a generated GoMock package. +package p2pmock + +import ( + p2pcommon "github.com/aergoio/aergo/p2p/p2pcommon" + gomock "github.com/golang/mock/gomock" + go_libp2p_net "github.com/libp2p/go-libp2p-net" + go_libp2p_peer "github.com/libp2p/go-libp2p-peer" + reflect "reflect" +) + +// MockPeerEventListener is a mock of PeerEventListener interface +type MockPeerEventListener struct { + ctrl *gomock.Controller + recorder *MockPeerEventListenerMockRecorder +} + +// MockPeerEventListenerMockRecorder is the mock recorder for MockPeerEventListener +type MockPeerEventListenerMockRecorder struct { + mock *MockPeerEventListener +} + +// NewMockPeerEventListener creates a new mock instance +func NewMockPeerEventListener(ctrl *gomock.Controller) *MockPeerEventListener { + mock := &MockPeerEventListener{ctrl: ctrl} + mock.recorder = &MockPeerEventListenerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockPeerEventListener) EXPECT() *MockPeerEventListenerMockRecorder { + return m.recorder +} + +// OnPeerConnect mocks base method +func (m *MockPeerEventListener) OnPeerConnect(pid go_libp2p_peer.ID) { + m.ctrl.Call(m, "OnPeerConnect", pid) +} + +// OnPeerConnect indicates an expected call of OnPeerConnect +func (mr *MockPeerEventListenerMockRecorder) OnPeerConnect(pid interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnPeerConnect", reflect.TypeOf((*MockPeerEventListener)(nil).OnPeerConnect), pid) +} + +// OnPeerDisconnect mocks base method +func (m *MockPeerEventListener) OnPeerDisconnect(peer p2pcommon.RemotePeer) { + m.ctrl.Call(m, "OnPeerDisconnect", peer) +} + +// OnPeerDisconnect indicates an expected call of OnPeerDisconnect +func (mr *MockPeerEventListenerMockRecorder) OnPeerDisconnect(peer interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnPeerDisconnect", reflect.TypeOf((*MockPeerEventListener)(nil).OnPeerDisconnect), peer) +} + +// MockPeerFinder is a mock of PeerFinder interface +type MockPeerFinder struct { + ctrl *gomock.Controller + recorder *MockPeerFinderMockRecorder +} + +// MockPeerFinderMockRecorder is the mock recorder for MockPeerFinder +type MockPeerFinderMockRecorder struct { + mock *MockPeerFinder +} + +// NewMockPeerFinder creates a new mock instance +func NewMockPeerFinder(ctrl *gomock.Controller) *MockPeerFinder { + mock := &MockPeerFinder{ctrl: ctrl} + mock.recorder = &MockPeerFinderMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockPeerFinder) EXPECT() *MockPeerFinderMockRecorder { + return m.recorder +} + +// OnPeerConnect mocks base method +func (m *MockPeerFinder) OnPeerConnect(pid go_libp2p_peer.ID) { + m.ctrl.Call(m, "OnPeerConnect", pid) +} + +// OnPeerConnect indicates an expected call of OnPeerConnect +func (mr *MockPeerFinderMockRecorder) OnPeerConnect(pid interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnPeerConnect", reflect.TypeOf((*MockPeerFinder)(nil).OnPeerConnect), pid) +} + +// OnPeerDisconnect mocks base method +func (m *MockPeerFinder) OnPeerDisconnect(peer p2pcommon.RemotePeer) { + m.ctrl.Call(m, "OnPeerDisconnect", peer) +} + +// OnPeerDisconnect indicates an expected call of OnPeerDisconnect +func (mr *MockPeerFinderMockRecorder) OnPeerDisconnect(peer interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnPeerDisconnect", reflect.TypeOf((*MockPeerFinder)(nil).OnPeerDisconnect), peer) +} + +// CheckAndFill mocks base method +func (m *MockPeerFinder) CheckAndFill() { + m.ctrl.Call(m, "CheckAndFill") +} + +// CheckAndFill indicates an expected call of CheckAndFill +func (mr *MockPeerFinderMockRecorder) CheckAndFill() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckAndFill", reflect.TypeOf((*MockPeerFinder)(nil).CheckAndFill)) +} + +// MockWaitingPeerManager is a mock of WaitingPeerManager interface +type MockWaitingPeerManager struct { + ctrl *gomock.Controller + recorder *MockWaitingPeerManagerMockRecorder +} + +// MockWaitingPeerManagerMockRecorder is the mock recorder for MockWaitingPeerManager +type MockWaitingPeerManagerMockRecorder struct { + mock *MockWaitingPeerManager +} + +// NewMockWaitingPeerManager creates a new mock instance +func NewMockWaitingPeerManager(ctrl *gomock.Controller) *MockWaitingPeerManager { + mock := &MockWaitingPeerManager{ctrl: ctrl} + mock.recorder = &MockWaitingPeerManagerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockWaitingPeerManager) EXPECT() *MockWaitingPeerManagerMockRecorder { + return m.recorder +} + +// OnPeerConnect mocks base method +func (m *MockWaitingPeerManager) OnPeerConnect(pid go_libp2p_peer.ID) { + m.ctrl.Call(m, "OnPeerConnect", pid) +} + +// OnPeerConnect indicates an expected call of OnPeerConnect +func (mr *MockWaitingPeerManagerMockRecorder) OnPeerConnect(pid interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnPeerConnect", reflect.TypeOf((*MockWaitingPeerManager)(nil).OnPeerConnect), pid) +} + +// OnPeerDisconnect mocks base method +func (m *MockWaitingPeerManager) OnPeerDisconnect(peer p2pcommon.RemotePeer) { + m.ctrl.Call(m, "OnPeerDisconnect", peer) +} + +// OnPeerDisconnect indicates an expected call of OnPeerDisconnect +func (mr *MockWaitingPeerManagerMockRecorder) OnPeerDisconnect(peer interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnPeerDisconnect", reflect.TypeOf((*MockWaitingPeerManager)(nil).OnPeerDisconnect), peer) +} + +// OnDiscoveredPeers mocks base method +func (m *MockWaitingPeerManager) OnDiscoveredPeers(metas []p2pcommon.PeerMeta) int { + ret := m.ctrl.Call(m, "OnDiscoveredPeers", metas) + ret0, _ := ret[0].(int) + return ret0 +} + +// OnDiscoveredPeers indicates an expected call of OnDiscoveredPeers +func (mr *MockWaitingPeerManagerMockRecorder) OnDiscoveredPeers(metas interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnDiscoveredPeers", reflect.TypeOf((*MockWaitingPeerManager)(nil).OnDiscoveredPeers), metas) +} + +// OnWorkDone mocks base method +func (m *MockWaitingPeerManager) OnWorkDone(result p2pcommon.ConnWorkResult) { + m.ctrl.Call(m, "OnWorkDone", result) +} + +// OnWorkDone indicates an expected call of OnWorkDone +func (mr *MockWaitingPeerManagerMockRecorder) OnWorkDone(result interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnWorkDone", reflect.TypeOf((*MockWaitingPeerManager)(nil).OnWorkDone), result) +} + +// CheckAndConnect mocks base method +func (m *MockWaitingPeerManager) CheckAndConnect() { + m.ctrl.Call(m, "CheckAndConnect") +} + +// CheckAndConnect indicates an expected call of CheckAndConnect +func (mr *MockWaitingPeerManagerMockRecorder) CheckAndConnect() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckAndConnect", reflect.TypeOf((*MockWaitingPeerManager)(nil).CheckAndConnect)) +} + +// OnInboundConn mocks base method +func (m *MockWaitingPeerManager) OnInboundConn(s go_libp2p_net.Stream) { + m.ctrl.Call(m, "OnInboundConn", s) +} + +// OnInboundConn indicates an expected call of OnInboundConn +func (mr *MockWaitingPeerManagerMockRecorder) OnInboundConn(s interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnInboundConn", reflect.TypeOf((*MockWaitingPeerManager)(nil).OnInboundConn), s) +} diff --git a/p2p/peerfinder.go b/p2p/peerfinder.go index 14c3333ec..4b139498b 100644 --- a/p2p/peerfinder.go +++ b/p2p/peerfinder.go @@ -6,13 +6,11 @@ package p2p import ( - "context" "github.com/aergoio/aergo-lib/log" "github.com/aergoio/aergo/message" "github.com/aergoio/aergo/p2p/p2pcommon" "github.com/aergoio/aergo/p2p/p2putil" "github.com/libp2p/go-libp2p-peer" - "github.com/pkg/errors" "time" ) @@ -23,13 +21,15 @@ const ( ) func NewPeerFinder(logger *log.Logger, pm *peerManager, actorService p2pcommon.ActorService, maxCap int, useDiscover, usePolaris bool) p2pcommon.PeerFinder { + var pf p2pcommon.PeerFinder if !useDiscover { - return &staticPeerFinder{pm:pm, logger:logger} + pf = &staticPeerFinder{pm:pm, logger:logger} } else { dp := &dynamicPeerFinder{logger: logger, pm: pm, actorService: actorService, maxCap: maxCap, usePolaris:usePolaris} dp.qStats = make(map[peer.ID]*queryStat) - return dp + pf = dp } + return pf } @@ -39,43 +39,17 @@ type staticPeerFinder struct { logger *log.Logger } +var _ p2pcommon.PeerFinder = (*staticPeerFinder)(nil) + func (dp *staticPeerFinder) OnPeerDisconnect(peer p2pcommon.RemotePeer) { - if _, ok := dp.pm.designatedPeers[peer.ID()]; ok { - // These peers must have cool time. - dp.pm.waitingPeers[peer.ID()] = &p2pcommon.WaitingPeer{Meta: peer.Meta(), NextTrial: time.Now().Add(firstReconnectColltime)} - dp.pm.addAwait(peer.Meta()) - } } func (dp *staticPeerFinder) OnPeerConnect(pid peer.ID) { - if _, ok := dp.pm.designatedPeers[pid]; ok { - delete(dp.pm.waitingPeers, pid) - dp.pm.cancelAwait(pid) - } -} - -func (dp *staticPeerFinder) OnDiscoveredPeers(metas []p2pcommon.PeerMeta) { } func (dp *staticPeerFinder) CheckAndFill() { - // find if there are not connected designated peers. designated peer - for _, meta := range dp.pm.designatedPeers { - if _, found := dp.pm.remotePeers[meta.ID]; !found { - if _, foundInWait := dp.pm.waitingPeers[meta.ID]; !foundInWait { - dp.pm.waitingPeers[meta.ID] = &p2pcommon.WaitingPeer{Meta: meta, NextTrial: time.Now()} - } - } - } } -func (dp *staticPeerFinder) AddWaitings(metas []p2pcommon.PeerMeta) { -} - -func (dp *staticPeerFinder) PickPeer(ctx context.Context) (p2pcommon.PeerMeta, error) { - return p2pcommon.PeerMeta{}, errors.New("no peers in pool") -} - -var _ p2pcommon.PeerFinder = (*staticPeerFinder)(nil) // dynamicPeerFinder is triggering map query to Polaris or address query to other connected peer // to discover peer @@ -98,12 +72,6 @@ var _ p2pcommon.PeerFinder = (*dynamicPeerFinder)(nil) func (dp *dynamicPeerFinder) OnPeerDisconnect(peer p2pcommon.RemotePeer) { // And check if to connect more peers delete(dp.qStats, peer.ID()) - if _, ok := dp.pm.designatedPeers[peer.ID()]; ok { - dp.logger.Debug().Str(p2putil.LogPeerID, peer.Name()).Msg("server will try to reconnect designated peer after cooltime") - // These peers must have cool time. - dp.pm.waitingPeers[peer.ID()] = &p2pcommon.WaitingPeer{Meta: peer.Meta(), NextTrial: time.Now().Add(firstReconnectColltime)} - dp.pm.addAwait(peer.Meta()) - } } func (dp *dynamicPeerFinder) OnPeerConnect(pid peer.ID) { @@ -112,27 +80,12 @@ func (dp *dynamicPeerFinder) OnPeerConnect(pid peer.ID) { // first query will be sent quickly dp.qStats[pid] = &queryStat{pid: pid, nextTurn: time.Now().Add(p2pcommon.PeerFirstInterval)} } - // remove peer from wait pool - delete(dp.pm.waitingPeers, pid) - dp.pm.cancelAwait(pid) -} - -func (dp *dynamicPeerFinder) OnDiscoveredPeers(metas []p2pcommon.PeerMeta) { - for _, meta := range metas { - if _, ok := dp.qStats[meta.ID]; ok { - // skip connected peer - continue - } else if _, ok := dp.pm.waitingPeers[meta.ID]; ok { - continue - } - dp.pm.waitingPeers[meta.ID] = &p2pcommon.WaitingPeer{Meta: meta, NextTrial: time.Now()} - } } func (dp *dynamicPeerFinder) CheckAndFill() { + // if enough peer is collected already, skip collect toConnCount := dp.maxCap - len(dp.pm.waitingPeers) if toConnCount <= 0 { - // if enough peer is collected already, skip collect return } now := time.Now() diff --git a/p2p/peerfinder_test.go b/p2p/peerfinder_test.go index 03ef6f344..fd6b9e369 100644 --- a/p2p/peerfinder_test.go +++ b/p2p/peerfinder_test.go @@ -6,17 +6,14 @@ package p2p import ( - "reflect" - "testing" - "time" - - "github.com/aergoio/aergo-lib/log" "github.com/aergoio/aergo/p2p/p2pcommon" "github.com/aergoio/aergo/p2p/p2pmock" "github.com/aergoio/aergo/p2p/p2putil" "github.com/golang/mock/gomock" crypto "github.com/libp2p/go-libp2p-crypto" "github.com/libp2p/go-libp2p-peer" + "reflect" + "testing" ) const desigCnt = 10 @@ -51,8 +48,7 @@ func init() { } func createDummyPM() *peerManager { dummyPM := &peerManager{designatedPeers: desigPeerMap, - remotePeers: make(map[peer.ID]*remotePeerImpl), - awaitPeers: make(map[peer.ID]*reconnectJob, 10), + remotePeers: make(map[peer.ID]p2pcommon.RemotePeer), waitingPeers: make(map[peer.ID]*p2pcommon.WaitingPeer, 10), } return dummyPM @@ -74,7 +70,6 @@ func TestNewPeerFinder(t *testing.T) { {"TstaticWPolaris", args{false, true}, &staticPeerFinder{}}, {"Tdyn", args{true, false}, &dynamicPeerFinder{}}, {"TdynWPolaris", args{true, true}, &dynamicPeerFinder{}}, - // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -88,84 +83,20 @@ func TestNewPeerFinder(t *testing.T) { } } -func Test_staticPeerFinder_OnDiscoveredPeers(t *testing.T) { - ctrl := gomock.NewController(t) - - type args struct { - metas []p2pcommon.PeerMeta - } - tests := []struct { - name string - args args - wantCount int - }{ - {"TSingleDesign", args{desigPeers[:1]}, 0}, - {"TAllDesign", args{desigPeers}, 0}, - {"TNewID", args{unknowPeers}, 0}, - {"TMixedIDs", args{append(unknowPeers[:5], desigPeers[:5]...)}, 0}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - dummyPM := createDummyPM() - mockActor := p2pmock.NewMockActorService(ctrl) - dp := NewPeerFinder(logger, dummyPM, mockActor, 10, false, false) - - dp.OnDiscoveredPeers(tt.args.metas) - if len(dummyPM.waitingPeers) != tt.wantCount { - t.Errorf("count waitingPeer %v, want %v", len(dummyPM.waitingPeers), tt.wantCount) - } - }) - } -} - -func Test_dynamicPeerFinder_OnDiscoveredPeers(t *testing.T) { +func Test_dynamicPeerFinder_OnPeerDisconnect(t *testing.T) { ctrl := gomock.NewController(t) type args struct { preConnected []peer.ID - metas []p2pcommon.PeerMeta - } - tests := []struct { - name string - args args - wantCount int - }{ - {"TAllNew", args{nil, desigPeers[:1]}, 1}, - {"TAllExist", args{desigIDs, desigPeers[:5]}, 0}, - {"TMixedIDs", args{desigIDs, append(unknowPeers[:5], desigPeers[:5]...)}, 5}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - dummyPM := createDummyPM() - mockActor := p2pmock.NewMockActorService(ctrl) - dp := NewPeerFinder(logger, dummyPM, mockActor, 10, true, false) - for _, id := range tt.args.preConnected { - dummyPM.remotePeers[id] = &remotePeerImpl{} - dp.OnPeerConnect(id) - } - - dp.OnDiscoveredPeers(tt.args.metas) - if len(dummyPM.waitingPeers) != tt.wantCount { - t.Errorf("count waitingPeer %v, want %v", len(dummyPM.waitingPeers), tt.wantCount) - } - }) - } -} - -func Test_staticPeerFinder_OnPeerDisconnect(t *testing.T) { - ctrl := gomock.NewController(t) - - type args struct { - inMeta p2pcommon.PeerMeta + inMeta p2pcommon.PeerMeta } tests := []struct { name string args args wantCount int }{ - {"TDesgintedPeer", args{desigPeers[0]}, 1}, - // it should not occur, though. - {"TNonPeer", args{unknowPeers[0]}, 0}, + {"TDesgintedPeer", args{desigIDs, desigPeers[0]}, 1}, + {"TNonPeer", args{unknowIDs, unknowPeers[0]}, 0}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -174,18 +105,24 @@ func Test_staticPeerFinder_OnPeerDisconnect(t *testing.T) { mockPeer := p2pmock.NewMockRemotePeer(ctrl) mockPeer.EXPECT().ID().Return(tt.args.inMeta.ID).AnyTimes() mockPeer.EXPECT().Meta().Return(tt.args.inMeta).AnyTimes() + mockPeer.EXPECT().Name().Return(p2putil.ShortMetaForm(tt.args.inMeta)).AnyTimes() - dp := NewPeerFinder(logger, dummyPM, mockActor, 10, false, false) + dp := NewPeerFinder(logger, dummyPM, mockActor, 10, true, false).(*dynamicPeerFinder) + for _, id := range tt.args.preConnected { + dummyPM.remotePeers[id] = &remotePeerImpl{} + dp.OnPeerConnect(id) + } + statCnt := len(dp.qStats) dp.OnPeerDisconnect(mockPeer) - if len(dummyPM.waitingPeers) != tt.wantCount { - t.Errorf("count waitingPeer %v, want %v", len(dummyPM.waitingPeers), tt.wantCount) + if statCnt-1 != len(dp.qStats) { + t.Errorf("count of query peers was not decreaded %v, want %v", len(dp.qStats), statCnt) } }) } } -func Test_dynamicPeerFinder_OnPeerDisconnect(t *testing.T) { +func Test_dynamicPeerFinder_OnPeerConnect(t *testing.T) { ctrl := gomock.NewController(t) type args struct { @@ -193,13 +130,12 @@ func Test_dynamicPeerFinder_OnPeerDisconnect(t *testing.T) { inMeta p2pcommon.PeerMeta } tests := []struct { - name string - args args - wantCount int + name string + args args + wantStatCount int }{ - {"TDesgintedPeer", args{desigIDs, desigPeers[0]}, 1}, - // it should not occur, though. - {"TNonPeer", args{unknowIDs, unknowPeers[0]}, 0}, + {"TDesigPeer", args{desigIDs, desigPeers[0]}, 1}, + {"TNonPeer", args{unknowIDs, unknowPeers[0]}, 1}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -211,80 +147,16 @@ func Test_dynamicPeerFinder_OnPeerDisconnect(t *testing.T) { mockPeer.EXPECT().Name().Return(p2putil.ShortMetaForm(tt.args.inMeta)).AnyTimes() dp := NewPeerFinder(logger, dummyPM, mockActor, 10, true, false).(*dynamicPeerFinder) - for _, id := range tt.args.preConnected { - dummyPM.remotePeers[id] = &remotePeerImpl{} - dp.OnPeerConnect(id) - } - statCnt := len(dp.qStats) - dp.OnPeerDisconnect(mockPeer) - if len(dummyPM.waitingPeers) != tt.wantCount { - t.Errorf("count waitingPeer %v, want %v", len(dummyPM.waitingPeers), tt.wantCount) - } - if statCnt-1 != len(dp.qStats) { - t.Errorf("count of query peers was not decreaded %v, want %v", len(dp.qStats), statCnt) - } - }) - } -} -func Test_staticPeerFinder_OnPeerConnect(t *testing.T) { - type fields struct { - pm *peerManager - logger *log.Logger - } - type args struct { - pid peer.ID - } - tests := []struct { - name string - fields fields - args args - }{ - // TODO: Add test cases. - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - dp := &staticPeerFinder{ - pm: tt.fields.pm, - logger: tt.fields.logger, - } - dp.OnPeerConnect(tt.args.pid) - }) - } -} + dp.OnPeerConnect(tt.args.inMeta.ID) -func Test_dynamicPeerFinder_OnPeerConnect(t *testing.T) { - type fields struct { - logger *log.Logger - pm *peerManager - actorService p2pcommon.ActorService - usePolaris bool - qStats map[peer.ID]*queryStat - maxCap int - polarisTurn time.Time - } - type args struct { - pid peer.ID - } - tests := []struct { - name string - fields fields - args args - }{ - // TODO: Add test cases. - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - dp := &dynamicPeerFinder{ - logger: tt.fields.logger, - pm: tt.fields.pm, - actorService: tt.fields.actorService, - usePolaris: tt.fields.usePolaris, - qStats: tt.fields.qStats, - maxCap: tt.fields.maxCap, - polarisTurn: tt.fields.polarisTurn, + if len(dp.qStats) != tt.wantStatCount { + t.Errorf("count of query peers was not decreaded %v, want %v", len(dp.qStats), tt.wantStatCount) + } else { + if _, exist := dp.qStats[tt.args.inMeta.ID] ; !exist { + t.Errorf("peer query for pid %v missing, want exists", p2putil.ShortForm(tt.args.inMeta.ID)) + } } - dp.OnPeerConnect(tt.args.pid) }) } } diff --git a/p2p/peermanager.go b/p2p/peermanager.go index a1a4db39c..e95e2cd19 100644 --- a/p2p/peermanager.go +++ b/p2p/peermanager.go @@ -3,7 +3,6 @@ package p2p import ( - "fmt" "net" "strconv" "sync" @@ -15,8 +14,6 @@ import ( "github.com/aergoio/aergo/p2p/p2putil" "github.com/aergoio/aergo/p2p/subproto" - inet "github.com/libp2p/go-libp2p-net" - "github.com/aergoio/aergo-lib/log" "github.com/aergoio/aergo/message" "github.com/aergoio/aergo/types" @@ -47,7 +44,7 @@ type peerManager struct { mm metric.MetricsManager peerFinder p2pcommon.PeerFinder - + wpManager p2pcommon.WaitingPeerManager // designatedPeers and hiddenPeerSet is set in construction time once and will not be changed hiddenPeerSet map[peer.ID]bool @@ -60,21 +57,29 @@ type peerManager struct { // peerCache is copy-on-write style peerCache []p2pcommon.RemotePeer - addPeerChannel chan p2pcommon.PeerMeta + getPeerChannel chan getPeerChan + peerHandshaked chan p2pcommon.RemotePeer removePeerChannel chan p2pcommon.RemotePeer fillPoolChannel chan []p2pcommon.PeerMeta + inboundConnChan chan inboundConnEvent + workDoneChannel chan p2pcommon.ConnWorkResult + finishChannel chan struct{} + eventListeners []PeerEventListener // designatedPeers map[peer.ID]p2pcommon.PeerMeta - awaitMutex sync.RWMutex - awaitPeers map[peer.ID]*reconnectJob - awaitDone chan struct{} logger *log.Logger } +// getPeerChan is struct to get peer for concurrent use +type getPeerChan struct { + id peer.ID + ret chan p2pcommon.RemotePeer +} + var _ p2pcommon.PeerManager = (*peerManager)(nil) // PeerEventListener listen peer manage event @@ -108,15 +113,16 @@ func NewPeerManager(handlerFactory p2pcommon.HandlerFactory, hsFactory p2pcommon remotePeers: make(map[peer.ID]p2pcommon.RemotePeer, p2pConf.NPMaxPeers), - awaitPeers: make(map[peer.ID]*reconnectJob, p2pConf.NPPeerPool), waitingPeers: make(map[peer.ID]*p2pcommon.WaitingPeer, p2pConf.NPPeerPool), peerCache: make([]p2pcommon.RemotePeer, 0, p2pConf.NPMaxPeers), - awaitDone: make(chan struct{}), - addPeerChannel: make(chan p2pcommon.PeerMeta, 2), + getPeerChannel: make(chan getPeerChan), + peerHandshaked: make(chan p2pcommon.RemotePeer), removePeerChannel: make(chan p2pcommon.RemotePeer), fillPoolChannel: make(chan []p2pcommon.PeerMeta, 2), + inboundConnChan: make(chan inboundConnEvent), + workDoneChannel: make(chan p2pcommon.ConnWorkResult), eventListeners: make([]PeerEventListener, 0, 4), finishChannel: make(chan struct{}), } @@ -147,25 +153,33 @@ func (pm *peerManager) init() { } pm.peerFinder = NewPeerFinder(pm.logger, pm, pm.actorService, pm.conf.NPPeerPool, pm.conf.NPDiscoverPeers, pm.conf.NPUsePolaris) + pm.wpManager = NewWaitingPeerManager(pm.logger, pm, pm.actorService, pm.conf.NPPeerPool, pm.conf.NPDiscoverPeers, pm.conf.NPUsePolaris) + // add designated peers to waiting pool at initial time. + for _, meta := range pm.designatedPeers { + if _, foundInWait := pm.waitingPeers[meta.ID]; !foundInWait { + pm.waitingPeers[meta.ID] = &p2pcommon.WaitingPeer{Meta: meta, NextTrial: time.Now()} + } + } + } func (pm *peerManager) Start() error { go pm.runManagePeers() // need to start listen after chainservice is read to init // FIXME: adhoc code - go func() { - //time.Sleep(time.Second * 3) - pm.logger.Info().Str("version", string(p2pcommon.AergoP2PSub)).Msg("Starting p2p listening") - pm.nt.AddStreamHandler(p2pcommon.AergoP2PSub, pm.onConnect) - - // addition should start after all modules are started - time.Sleep(time.Second * 2) - dPeers := make([]p2pcommon.PeerMeta,len(pm.designatedPeers)) - for _, meta := range pm.designatedPeers { - dPeers = append(dPeers, meta) - } - pm.fillPoolChannel <- dPeers - }() + //go func() { + //time.Sleep(time.Second * 3) + //pm.logger.Info().Str("version", string(p2pcommon.AergoP2PSub)).Msg("Starting p2p listening") + //pm.nt.AddStreamHandler(p2pcommon.AergoP2PSub, pm.onConnect) + + // addition should start after all modules are started + //time.Sleep(time.Second * 2) + //dPeers := make([]p2pcommon.PeerMeta, len(pm.designatedPeers)) + //for _, meta := range pm.designatedPeers { + // dPeers = append(dPeers, meta) + //} + //pm.fillPoolChannel <- dPeers + //}() return nil } @@ -198,38 +212,76 @@ func (pm *peerManager) initDesignatedPeerList() { } func (pm *peerManager) runManagePeers() { - initialAddrDelay := time.Second * 20 - initialTimer := time.NewTimer(initialAddrDelay) - addrTicker := time.NewTicker(DiscoveryQueryInterval) + pm.logger.Info().Str("version", string(p2pcommon.AergoP2PSub)).Msg("Starting p2p listening") + pm.nt.AddStreamHandler(p2pcommon.AergoP2PSub, pm.wpManager.OnInboundConn) + if !atomic.CompareAndSwapInt32(&pm.status, initial, running) { panic("wrong internal status") } + instantStart := time.Millisecond << 4 + initialAddrDelay := time.Second * 2 + finderTimer := time.NewTimer(initialAddrDelay) + connManTimer := time.NewTimer(initialAddrDelay << 1) + MANLOOP: for { select { - case meta := <-pm.addPeerChannel: - if pm.addOutboundPeer(meta) { - pm.peerFinder.OnPeerConnect(meta.ID) - pm.cancelAwait(meta.ID) + case req := <- pm.getPeerChannel: + peer, exist := pm.remotePeers[req.id] + if exist { + req.ret <- peer + } else { + req.ret <- nil + } + case peer := <-pm.peerHandshaked: + if pm.tryRegister(peer) { + pm.peerFinder.OnPeerConnect(peer.ID()) + pm.wpManager.OnPeerConnect(peer.ID()) } case peer := <-pm.removePeerChannel: if pm.removePeer(peer) { pm.peerFinder.OnPeerDisconnect(peer) + pm.wpManager.OnPeerDisconnect(peer) } - case <-initialTimer.C: - initialTimer.Stop() - pm.peerFinder.CheckAndFill() - case <-addrTicker.C: + if !connManTimer.Stop() { + <-connManTimer.C + } + connManTimer.Reset(instantStart) + case inInfo := <-pm.inboundConnChan: + id := inInfo.meta.ID + if _, found := pm.remotePeers[id]; found { + inInfo.foundC <- true + } else { + inInfo.foundC <- false + } + case workResult := <-pm.workDoneChannel: + pm.wpManager.OnWorkDone(workResult) + // Retry + if !connManTimer.Stop() { + <-connManTimer.C + } + connManTimer.Reset(instantStart) + case <-finderTimer.C: pm.peerFinder.CheckAndFill() + finderTimer.Reset(DiscoveryQueryInterval) + case <-connManTimer.C: + pm.wpManager.CheckAndConnect() + // fire at next interval + connManTimer.Reset(p2pcommon.WaitingPeerManagerInterval) case peerMetas := <-pm.fillPoolChannel: - pm.peerFinder.OnDiscoveredPeers(peerMetas) + if pm.wpManager.OnDiscoveredPeers(peerMetas) > 0 { + if !connManTimer.Stop() { + <-connManTimer.C + } + connManTimer.Reset(instantStart) + } case <-pm.finishChannel: - addrTicker.Stop() + finderTimer.Stop() + connManTimer.Stop() break MANLOOP } } // guarrenty no new peer connection will be made - pm.cancelAllAwait() pm.nt.RemoveStreamHandler(p2pcommon.AergoP2PSub) pm.logger.Info().Msg("Finishing peerManager") @@ -244,6 +296,8 @@ MANLOOP: CLEANUPLOOP: for { select { + case req := <-pm.getPeerChannel: + req.ret <- nil case peer := <-pm.removePeerChannel: pm.removePeer(peer) case <-finishPoll.C: @@ -262,81 +316,17 @@ CLEANUPLOOP: atomic.StoreInt32(&pm.status, stopped) } -// addOutboundPeer try to connect and handshake to remote peer. it can be called after peermanager is inited. -// It return true if peer is added or return false if failed to add peer or more suitable connection already exists. -func (pm *peerManager) addOutboundPeer(meta p2pcommon.PeerMeta) bool { - s, err := pm.nt.GetOrCreateStream(meta, p2pcommon.AergoP2PSub) - if err != nil { - pm.logger.Info().Err(err).Str(p2putil.LogPeerID, p2putil.ShortForm(meta.ID)).Msg("Failed to get stream.") - return false - } - - completeMeta, added := pm.tryAddPeer(true, meta, s) - if !added { - s.Close() - return false - } else { - if meta.IPAddress != completeMeta.IPAddress { - pm.logger.Debug().Str(p2putil.LogPeerID, p2putil.ShortForm(completeMeta.ID)).Str("before", meta.IPAddress).Str("after", completeMeta.IPAddress).Msg("IP address of remote peer is changed to ") - } - } - return true -} - -// tryAddPeer will do check connecting peer and add. it will return peer meta information received from -// remote peer. stream s will be owned to remotePeer if succeed to add perr. -func (pm *peerManager) tryAddPeer(outbound bool, meta p2pcommon.PeerMeta, s inet.Stream) (p2pcommon.PeerMeta, bool) { - var peerID = meta.ID - rd := metric.NewReader(s) - wt := metric.NewWriter(s) - h := pm.hsFactory.CreateHSHandler(outbound, pm, pm.actorService, pm.logger, peerID) - rw, remoteStatus, err := h.Handle(rd, wt, defaultHandshakeTTL) - if err != nil { - pm.logger.Debug().Err(err).Str(p2putil.LogPeerID, p2putil.ShortForm(meta.ID)).Msg("Failed to handshake") - if rw != nil { - pm.sendGoAway(rw, err.Error()) - } - return meta, false - } - // update peer meta info using sent information from remote peer - receivedMeta := p2pcommon.NewMetaFromStatus(remoteStatus, outbound) - if receivedMeta.ID != peerID { - pm.logger.Debug().Str("received_peer_id", receivedMeta.ID.Pretty()).Str(p2putil.LogPeerID, p2putil.ShortForm(peerID)).Msg("Inconsistent peerID") - pm.sendGoAway(rw, "Inconsistent peerID") - return meta, false - } - _, receivedMeta.Designated = pm.designatedPeers[peerID] - - // adding peer to peer list - newPeer, err := pm.registerPeer(peerID, receivedMeta, remoteStatus, s, rw) - if err != nil { - pm.sendGoAway(rw, err.Error()) - return meta, false - } - newPeer.metric = pm.mm.Add(peerID, rd, wt) - - if pm.logger.IsDebugEnabled() { - addrStrs := pm.nt.GetAddressesOfPeer(peerID) - pm.logger.Debug().Strs("addrs", addrStrs).Str(p2putil.LogPeerID, p2putil.ShortForm(peerID)).Msg("addresses of peer") - } - - pm.doPostHandshake(peerID, remoteStatus) - // notice to p2pmanager that handshaking is finished - pm.NotifyPeerHandshake(peerID) - - return receivedMeta, true -} - -func (pm *peerManager) registerPeer(peerID peer.ID, receivedMeta p2pcommon.PeerMeta, status *types.Status, s inet.Stream, rw p2pcommon.MsgReadWriter) (*remotePeerImpl, error) { - pm.mutex.Lock() - defer pm.mutex.Unlock() +// tryRegister register peer to peer manager, if peer with same peer +func (pm *peerManager) tryRegister(peer p2pcommon.RemotePeer) bool { + peerID := peer.ID() + receivedMeta := peer.Meta() preExistPeer, ok := pm.remotePeers[peerID] if ok { pm.logger.Info().Str(p2putil.LogPeerID, p2putil.ShortForm(peerID)).Msg("Peer add collision. Outbound connection of higher hash will survive.") - iAmLower := p2putil.ComparePeerID(pm.SelfNodeID(), receivedMeta.ID) <= 0 - if iAmLower == receivedMeta.Outbound { + iAmLowerOrEqual := p2putil.ComparePeerID(pm.SelfNodeID(), receivedMeta.ID) <= 0 + if iAmLowerOrEqual == receivedMeta.Outbound { pm.logger.Info().Str("local_peer_id", p2putil.ShortForm(pm.SelfNodeID())).Str(p2putil.LogPeerID, p2putil.ShortForm(peerID)).Bool("outbound", receivedMeta.Outbound).Msg("Close connection and keep earlier handshake connection.") - return nil, fmt.Errorf("Already handshake peer %s ", p2putil.ShortForm(peerID)) + return false } else { pm.logger.Info().Str("local_peer_id", p2putil.ShortForm(pm.SelfNodeID())).Str(p2putil.LogPeerID, p2putil.ShortForm(peerID)).Bool("outbound", receivedMeta.Outbound).Msg("Keep connection and close earlier handshake connection.") // stopping lower valued connection @@ -344,27 +334,12 @@ func (pm *peerManager) registerPeer(peerID peer.ID, receivedMeta p2pcommon.PeerM } } - outboundPeer := newRemotePeer(receivedMeta, pm.GetNextManageNum(), pm, pm.actorService, pm.logger, pm.mf, pm.signer, s, rw) - outboundPeer.UpdateBlkCache(status.GetBestBlockHash(), status.GetBestHeight()) - - // insert Handlers - pm.handlerFactory.InsertHandlers(outboundPeer) - - go outboundPeer.RunPeer() - pm.insertPeer(peerID, outboundPeer) - pm.logger.Info().Bool("outbound", receivedMeta.Outbound).Str(p2putil.LogPeerName, outboundPeer.Name()).Str("addr", net.ParseIP(receivedMeta.IPAddress).String()+":"+strconv.Itoa(int(receivedMeta.Port))).Msg("peer is added to peerService") + go peer.RunPeer() + // FIXME type casting is worse + pm.insertPeer(peerID, peer.(*remotePeerImpl)) + pm.logger.Info().Bool("outbound", receivedMeta.Outbound).Str(p2putil.LogPeerName, peer.Name()).Str("addr", net.ParseIP(receivedMeta.IPAddress).String()+":"+strconv.Itoa(int(receivedMeta.Port))).Msg("peer is added to peerService") - return outboundPeer, nil -} - -// doPostHandshake is additional work after peer is added. -func (pm *peerManager) doPostHandshake(peerID peer.ID, remoteStatus *types.Status) { - - pm.logger.Debug().Uint64("target", remoteStatus.BestHeight).Msg("request new syncer") - pm.actorService.SendRequest(message.SyncerSvc, &message.SyncStart{PeerID: peerID, TargetNo: remoteStatus.BestHeight}) - - // sync mempool tx infos - // TODO add tx handling + return true } func (pm *peerManager) GetNextManageNum() uint32 { @@ -380,22 +355,21 @@ func (pm *peerManager) sendGoAway(rw p2pcommon.MsgReadWriter, msg string) { } func (pm *peerManager) AddNewPeer(meta p2pcommon.PeerMeta) { - pm.addPeerChannel <- meta + sli := []p2pcommon.PeerMeta{meta} + pm.fillPoolChannel <- sli } func (pm *peerManager) RemovePeer(peer p2pcommon.RemotePeer) { pm.removePeerChannel <- peer } -func (pm *peerManager) NotifyPeerHandshake(peerID peer.ID) { -} - func (pm *peerManager) NotifyPeerAddressReceived(metas []p2pcommon.PeerMeta) { pm.fillPoolChannel <- metas } // removePeer unregister managed remote peer connection // It return true if peer is exist and managed by peermanager +// it must called in peermanager goroutine func (pm *peerManager) removePeer(peer p2pcommon.RemotePeer) bool { peerID := peer.ID() pm.mutex.Lock() @@ -422,88 +396,17 @@ func (pm *peerManager) removePeer(peer p2pcommon.RemotePeer) bool { return true } -func (pm *peerManager) onConnect(s inet.Stream) { - peerID := s.Conn().RemotePeer() - tempMeta := p2pcommon.PeerMeta{ID: peerID} - addr := s.Conn().RemoteMultiaddr() - - pm.logger.Debug().Str(p2putil.LogFullID, peerID.Pretty()).Str("multiaddr", addr.String()).Msg("new inbound peer arrived") - completeMeta, added := pm.tryAddPeer(false, tempMeta, s) - if !added { - s.Close() - } else { - if tempMeta.IPAddress != completeMeta.IPAddress { - pm.logger.Debug().Str("after", completeMeta.IPAddress).Msg("Update IP address of inbound remote peer") - } - } -} - -// tryConnectPeers should be called in runManagePeers() only -func (pm *peerManager) tryFillPool(metas *[]p2pcommon.PeerMeta) { - added := make([]p2pcommon.PeerMeta, 0, len(*metas)) - invalid := make([]string, 0) - for _, meta := range *metas { - if string(meta.ID) == "" { - invalid = append(invalid, p2putil.ShortMetaForm(meta)) - continue - } - _, found := pm.waitingPeers[meta.ID] - if !found { - // change some properties - meta.Outbound = true - meta.Designated = false - pm.waitingPeers[meta.ID] = &p2pcommon.WaitingPeer{Meta: meta, NextTrial: time.Now()} - added = append(added, meta) - } - } - if len(invalid) > 0 { - pm.logger.Warn().Strs("metas", invalid).Msg("invalid meta list was come") - } - pm.logger.Debug().Int("added_cnt", len(added)).Msg("Filled unknown peer addresses to peerpool") - pm.tryConnectPeers() -} - -// tryConnectPeers should be called in runManagePeers() only -func (pm *peerManager) tryConnectPeers() { - remained := pm.conf.NPMaxPeers - len(pm.remotePeers) - now := time.Now() - for ID, wp := range pm.waitingPeers { - if _, found := pm.GetPeer(ID); found { - delete(pm.waitingPeers, ID) - continue - } - if wp.NextTrial.After(now) { - // cool time is not over. try connect later - continue - } - meta := wp.Meta - if meta.IPAddress == "" || meta.Port == 0 { - pm.logger.Warn().Str(p2putil.LogPeerID, p2putil.ShortForm(meta.ID)).Str("addr", meta.IPAddress). - Uint32("port", meta.Port).Msg("Invalid peer meta informations") - // remove invalid peer - delete(pm.waitingPeers, ID) - continue - } - // TODO - // in same go rountine. - pm.addOutboundPeer(meta) - remained-- - if remained <= 0 { - break - } - } -} func (pm *peerManager) GetPeer(ID peer.ID) (p2pcommon.RemotePeer, bool) { - pm.mutex.Lock() - defer pm.mutex.Unlock() + gc := getPeerChan{id:ID, ret:make(chan p2pcommon.RemotePeer)} // vs code's lint does not allow direct return of map operation - ptr, ok := pm.remotePeers[ID] - if !ok { + pm.getPeerChannel <- gc + ptr := <-gc.ret + if ptr ==nil { return nil, false } - return ptr, ok + return ptr, true } func (pm *peerManager) GetPeers() []p2pcommon.RemotePeer { @@ -572,45 +475,3 @@ func (pm *peerManager) updatePeerCache() { } pm.peerCache = newSlice } - -func (pm *peerManager) addAwait(meta p2pcommon.PeerMeta) { - pm.awaitMutex.Lock() - defer pm.awaitMutex.Unlock() - if _, exist := pm.awaitPeers[meta.ID]; exist { - return - } - if atomic.LoadInt32(&pm.status) != running { - return - } - job := newReconnectRunner(meta, pm, pm.logger) - pm.awaitPeers[meta.ID] = job - go job.runJob() -} - -func (pm *peerManager) cancelAwait(id peer.ID) { - pm.awaitMutex.Lock() - defer pm.awaitMutex.Unlock() - defer func() { - if atomic.LoadInt32(&pm.status) == stopping && - len(pm.awaitPeers) == 0 { - pm.awaitDone <- struct{}{} - } - }() - job, exist := pm.awaitPeers[id] - if !exist { - return - } - delete(pm.awaitPeers, id) - job.cancel <- struct{}{} -} - -func (pm *peerManager) cancelAllAwait() { - cancelCnt := 0 - for id, _ := range pm.awaitPeers { - go pm.cancelAwait(id) - cancelCnt++ - } - if cancelCnt > 0 { - <-pm.awaitDone - } -} diff --git a/p2p/peermanager_test.go b/p2p/peermanager_test.go index 48821b78f..ebc48f6a1 100644 --- a/p2p/peermanager_test.go +++ b/p2p/peermanager_test.go @@ -179,6 +179,53 @@ func TestPeerManager_init(t *testing.T) { } } +func Test_peerManager_runManagePeers_fillAddr(t *testing.T) { + // Test if polaris or other peer send addresses informations. + ctrl := gomock.NewController(t) + logger := log.NewLogger("p2p.test") + tests := []struct { + name string + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mockPeerFinder := p2pmock.NewMockPeerFinder(ctrl) + mockWPManager := p2pmock.NewMockWaitingPeerManager(ctrl) + dummyCfg := &cfg.P2PConfig{} + pm := &peerManager{ + peerFinder: mockPeerFinder, + wpManager: mockWPManager, + remotePeers: make(map[peer.ID]p2pcommon.RemotePeer, 10), + waitingPeers: make(map[peer.ID]*p2pcommon.WaitingPeer, 10), + conf: dummyCfg, + + getPeerChannel: make(chan getPeerChan), + peerHandshaked: make(chan p2pcommon.RemotePeer), + removePeerChannel: make(chan p2pcommon.RemotePeer), + fillPoolChannel: make(chan []p2pcommon.PeerMeta, 2), + inboundConnChan: make(chan inboundConnEvent), + workDoneChannel: make(chan p2pcommon.ConnWorkResult), + eventListeners: make([]PeerEventListener, 0, 4), + finishChannel: make(chan struct{}), + + logger: logger, + } + + go pm.runManagePeers() + + metas := []p2pcommon.PeerMeta{} + pm.NotifyPeerAddressReceived(metas) + + pm.Stop() + + for atomic.LoadInt32(&pm.status) != stopped { + time.Sleep(time.Millisecond << 6) + } + }) + } +} + func Test_peerManager_Stop(t *testing.T) { // check if Stop is working. tests := []struct { @@ -199,7 +246,7 @@ func Test_peerManager_Stop(t *testing.T) { t.Run(tt.name, func(t *testing.T) { pm := &peerManager{ logger: logger, - finishChannel: make(chan struct{},1 ), + finishChannel: make(chan struct{}, 1), } atomic.StoreInt32(&pm.status, tt.prevStatus) @@ -210,12 +257,12 @@ func Test_peerManager_Stop(t *testing.T) { toMStatusName(tt.wantStatus)) } var sent bool - timeout := time.NewTimer(time.Millisecond<<6) + timeout := time.NewTimer(time.Millisecond << 6) select { - case <-pm.finishChannel: - sent = true - case <-timeout.C: - sent = false + case <-pm.finishChannel: + sent = true + case <-timeout.C: + sent = false } if sent != tt.wantSentChannel { t.Errorf("signal sent %v, want %v ", sent, tt.wantSentChannel) @@ -244,11 +291,17 @@ func Test_peerManager_StopInRun(t *testing.T) { mockNT := p2pmock.NewMockNetworkTransport(ctrl) mockNT.EXPECT().AddStreamHandler(gomock.Any(), gomock.Any()).AnyTimes() mockNT.EXPECT().RemoveStreamHandler(gomock.Any()).AnyTimes() + + mockPeerFinder := p2pmock.NewMockPeerFinder(ctrl) + mockWPManager := p2pmock.NewMockWaitingPeerManager(ctrl) + pm := &peerManager{ - logger: logger, - nt: mockNT, + logger: logger, + nt: mockNT, + peerFinder: mockPeerFinder, + wpManager: mockWPManager, + mutex: &sync.Mutex{}, - awaitDone: make(chan struct{}), finishChannel: make(chan struct{}), } go pm.runManagePeers() diff --git a/p2p/reconnect.go b/p2p/reconnect.go index 7e8f1a5da..25253117f 100644 --- a/p2p/reconnect.go +++ b/p2p/reconnect.go @@ -7,11 +7,6 @@ package p2p import ( "math" "time" - - "github.com/aergoio/aergo/p2p/p2pcommon" - "github.com/aergoio/aergo/p2p/p2putil" - - "github.com/aergoio/aergo-lib/log" ) var ( @@ -24,40 +19,6 @@ func init() { durations = generateExpDuration(20, 0.6, maxTrial) } -type reconnectJob struct { - meta p2pcommon.PeerMeta - trial int - pm p2pcommon.PeerManager - logger *log.Logger - - cancel chan struct{} -} - -func newReconnectRunner(meta p2pcommon.PeerMeta, pm p2pcommon.PeerManager, logger *log.Logger) *reconnectJob { - return &reconnectJob{meta: meta, trial: 0, pm: pm, cancel: make(chan struct{}, 1), logger: logger} -} -func (rj *reconnectJob) runJob() { - timer := time.NewTimer(getNextInterval(rj.trial)) -RETRYLOOP: - for { - // wait for duration - select { - case <-timer.C: - _, found := rj.pm.GetPeer(rj.meta.ID) - if found { - break RETRYLOOP - } - rj.logger.Debug().Str("peer_meta", p2putil.ShortMetaForm(rj.meta)).Int("trial", rj.trial).Msg("Trying to connect") - rj.pm.AddNewPeer(rj.meta) - rj.trial++ - timer.Reset(getNextInterval(rj.trial)) - case <-rj.cancel: - break RETRYLOOP - } - } - //rj.rm.jobFinished(rj.meta.ID) -} - func getNextInterval(trial int) time.Duration { if trial < maxTrial { return durations[trial] diff --git a/p2p/remotepeer.go b/p2p/remotepeer.go index 8dadf6ced..d01b50ad3 100644 --- a/p2p/remotepeer.go +++ b/p2p/remotepeer.go @@ -8,6 +8,7 @@ package p2p import ( "fmt" "runtime/debug" + "github.com/pkg/errors" "sync" "time" @@ -26,11 +27,8 @@ import ( peer "github.com/libp2p/go-libp2p-peer" ) -var TimeoutError error - -func init() { - TimeoutError = fmt.Errorf("timeout") -} +var TimeoutError = errors.New("timeout") +var CancelError = errors.New("canceled") type requestInfo struct { cTime time.Time diff --git a/p2p/waitpeermanager.go b/p2p/waitpeermanager.go new file mode 100644 index 000000000..c1235177e --- /dev/null +++ b/p2p/waitpeermanager.go @@ -0,0 +1,317 @@ +/* + * @file + * @copyright defined in aergo/LICENSE.txt + */ + +package p2p + +import ( + "errors" + "github.com/aergoio/aergo-lib/log" + "github.com/aergoio/aergo/p2p/metric" + "github.com/aergoio/aergo/p2p/p2pcommon" + "github.com/aergoio/aergo/p2p/p2putil" + net "github.com/libp2p/go-libp2p-net" + "github.com/libp2p/go-libp2p-peer" + "sort" + "time" +) + +func NewWaitingPeerManager(logger *log.Logger, pm *peerManager, actorService p2pcommon.ActorService, maxCap int, useDiscover, usePolaris bool) p2pcommon.WaitingPeerManager { + var wpm p2pcommon.WaitingPeerManager + if !useDiscover { + sp := &staticWPManager{basePeerManager{pm: pm, logger: logger,workingJobs:make(map[peer.ID]ConnWork)}} + wpm = sp + } else { + dp := &dynamicWPManager{basePeerManager:basePeerManager{pm: pm, logger: logger, workingJobs:make(map[peer.ID]ConnWork)}, maxPeers: maxCap} + wpm = dp + } + + return wpm +} + +type basePeerManager struct { + pm *peerManager + logger *log.Logger + workingJobs map[peer.ID]ConnWork +} + + +func (dpm *basePeerManager) OnInboundConn(s net.Stream) { + peerID := s.Conn().RemotePeer() + tempMeta := p2pcommon.PeerMeta{ID: peerID} + addr := s.Conn().RemoteMultiaddr() + + dpm.logger.Debug().Str(p2putil.LogFullID, peerID.Pretty()).Str("multiaddr", addr.String()).Msg("new inbound peer arrived") + query := inboundConnEvent{meta: tempMeta, p2pVer: p2pcommon.P2PVersion030, foundC: make(chan bool)} + dpm.pm.inboundConnChan <- query + if exist := <-query.foundC; exist { + dpm.logger.Debug().Str(p2putil.LogPeerID, p2putil.ShortForm(peerID)).Msg("same peer as inbound peer already exists.") + // TODO send already exist message + s.Close() + } + + // check if remote peer is connected (already handshaked) + completeMeta, added := dpm.tryAddPeer(false, tempMeta, s) + if !added { + s.Close() + } else { + if tempMeta.IPAddress != completeMeta.IPAddress { + dpm.logger.Debug().Str("after", completeMeta.IPAddress).Msg("Update IP address of inbound remote peer") + } + } +} + +func (dpm *basePeerManager) CheckAndConnect() { + dpm.logger.Debug().Msg("checking space to connect more peers") + maxJobs := dpm.getRemainingSpaces() + if maxJobs == 0 { + return + } + dpm.connectWaitingPeers(maxJobs) +} + +func (dpm *basePeerManager) connectWaitingPeers(maxJob int) { + // do try to connection at most maxJobs cnt, + peers := make([]*p2pcommon.WaitingPeer, 0, len(dpm.pm.waitingPeers)) + for _, wp := range dpm.pm.waitingPeers { + peers = append(peers,wp) + } + sort.Sort(byNextTrial(peers)) + + added := 0 + now := time.Now() + for _, wp := range peers { + if added >= maxJob { + break + } + if wp.NextTrial.Before(now) { + // check if peer is currently working now + if _, exist := dpm.workingJobs[wp.Meta.ID]; exist { + continue + } + dpm.workingJobs[wp.Meta.ID] = ConnWork{Meta: wp.Meta, PeerID:wp.Meta.ID, StartTime:time.Now()} + go dpm.runTryOutboundConnect(wp) + added++ + } else { + break + } + } +} + +func (dpm *basePeerManager) getRemainingSpaces() int { + // simpler version. just check total count + // has space to add more connection + if len(dpm.pm.waitingPeers) <= 0 { + return 0 + } + affordWorker := p2pcommon.MaxConcurrentHandshake - len(dpm.workingJobs) + if affordWorker <= 0 { + return 0 + } + return affordWorker +} + + +func (dpm *basePeerManager) runTryOutboundConnect(wp *p2pcommon.WaitingPeer) { + workResult := p2pcommon.ConnWorkResult{Meta: wp.Meta, TargetPeer: wp} + defer func() { + dpm.pm.workDoneChannel <- workResult + }() + + meta := wp.Meta + s, err := dpm.pm.nt.GetOrCreateStream(meta, p2pcommon.AergoP2PSub) + if err != nil { + dpm.logger.Info().Err(err).Str(p2putil.LogPeerID, p2putil.ShortForm(meta.ID)).Msg("Failed to get stream.") + workResult.Result = err + return + } + + // handshake + completeMeta, added := dpm.tryAddPeer(true, meta, s) + if !added { + s.Close() + workResult.Result = errors.New("handshake failed") + return + } else { + if meta.IPAddress != completeMeta.IPAddress { + dpm.logger.Debug().Str(p2putil.LogPeerID, p2putil.ShortForm(completeMeta.ID)).Str("before", meta.IPAddress).Str("after", completeMeta.IPAddress).Msg("IP address of remote peer is changed to ") + } + } +} + +// tryAddPeer will do check connecting peer and add. it will return peer meta information received from +// remote peer. stream s will be owned to remotePeer if succeed to add perr. +func (dpm *basePeerManager) tryAddPeer(outbound bool, meta p2pcommon.PeerMeta, s net.Stream) (p2pcommon.PeerMeta, bool) { + var peerID = meta.ID + rd := metric.NewReader(s) + wt := metric.NewWriter(s) + h := dpm.pm.hsFactory.CreateHSHandler(outbound, dpm.pm, dpm.pm.actorService, dpm.logger, peerID) + rw, remoteStatus, err := h.Handle(rd, wt, defaultHandshakeTTL) + if err != nil { + dpm.logger.Debug().Err(err).Str(p2putil.LogPeerID, p2putil.ShortForm(meta.ID)).Msg("Failed to handshake") + if rw != nil { + dpm.pm.sendGoAway(rw, err.Error()) + } + return meta, false + } + // update peer meta info using sent information from remote peer + receivedMeta := p2pcommon.NewMetaFromStatus(remoteStatus, outbound) + if receivedMeta.ID != peerID { + dpm.logger.Debug().Str("received_peer_id", receivedMeta.ID.Pretty()).Str(p2putil.LogPeerID, p2putil.ShortForm(peerID)).Msg("Inconsistent peerID") + dpm.pm.sendGoAway(rw, "Inconsistent peerID") + return meta, false + } + _, receivedMeta.Designated = dpm.pm.designatedPeers[peerID] + + newPeer := newRemotePeer(receivedMeta, dpm.pm.GetNextManageNum(), dpm.pm, dpm.pm.actorService, dpm.logger, dpm.pm.mf, dpm.pm.signer, s, rw) + newPeer.UpdateBlkCache(remoteStatus.GetBestBlockHash(), remoteStatus.GetBestHeight()) + + // insert Handlers + dpm.pm.handlerFactory.InsertHandlers(newPeer) + + dpm.pm.peerHandshaked <- newPeer + return receivedMeta, true +} + +func (dpm *basePeerManager) OnWorkDone(result p2pcommon.ConnWorkResult) { + meta := result.Meta + delete(dpm.workingJobs, meta.ID) + wp, ok := dpm.pm.waitingPeers[meta.ID] + if !ok { + dpm.logger.Debug().Str(p2putil.LogPeerName, p2putil.ShortMetaForm(meta)).Err(result.Result).Msg("Connection job finished") + return + } else { + dpm.logger.Debug().Str(p2putil.LogPeerName, p2putil.ShortMetaForm(meta)).Int("trial",wp.TrialCnt).Err(result.Result).Msg("Connection job finished") + } + wp.LastResult = result.Result + // success to connect + if result.Result == nil { + dpm.logger.Debug().Str(p2putil.LogPeerName, p2putil.ShortMetaForm(meta)).Msg("Deleting unimportant failed peer.") + delete(dpm.pm.waitingPeers,meta.ID) + } else { + // leave waitingpeer if needed to reconnect + if !setNextTrial(wp) { + dpm.logger.Debug().Str(p2putil.LogPeerName, p2putil.ShortMetaForm(meta)).Time("next_time",wp.NextTrial).Msg("Failed Connection will restart.") + delete(dpm.pm.waitingPeers,meta.ID) + } + } + +} + +type staticWPManager struct { + basePeerManager +} + + +func (spm *staticWPManager) OnPeerConnect(pid peer.ID) { + delete(spm.pm.waitingPeers, pid) +} + +func (spm *staticWPManager) OnPeerDisconnect(peer p2pcommon.RemotePeer) { + // if peer is designated peer , try reconnect by add peermeta to waiting peer + if _, ok := spm.pm.designatedPeers[peer.ID()]; ok { + spm.logger.Debug().Str(p2putil.LogPeerID, peer.Name()).Msg("server will try to reconnect designated peer after cooltime") + // These peers must have cool time. + spm.pm.waitingPeers[peer.ID()] = &p2pcommon.WaitingPeer{Meta: peer.Meta(), NextTrial: time.Now().Add(firstReconnectColltime)} + } +} + + +func (spm *staticWPManager) OnDiscoveredPeers(metas []p2pcommon.PeerMeta) int { + // static manager don't need to discovered peer. + return 0 +} + +type dynamicWPManager struct { + basePeerManager + + maxPeers int +} + +func (dpm *dynamicWPManager) OnPeerConnect(pid peer.ID) { + // remove peer from wait pool + delete(dpm.pm.waitingPeers, pid) +} + +func (dpm *dynamicWPManager) OnPeerDisconnect(peer p2pcommon.RemotePeer) { + // if peer is designated peer or trusted enough , try reconnect by add peermeta to waiting peer + // TODO check by trust level is not implemented yet. + if _, ok := dpm.pm.designatedPeers[peer.ID()]; ok { + dpm.logger.Debug().Str(p2putil.LogPeerID, peer.Name()).Msg("server will try to reconnect designated peer after cooltime") + // These peers must have cool time. + dpm.pm.waitingPeers[peer.ID()] = &p2pcommon.WaitingPeer{Meta: peer.Meta(), NextTrial: time.Now().Add(firstReconnectColltime)} + //dpm.pm.addAwait(peer.Meta()) + } +} + +func (dpm *dynamicWPManager) OnDiscoveredPeers(metas []p2pcommon.PeerMeta) int { + addedWP := 0 + for _, meta := range metas { + if _, ok := dpm.pm.remotePeers[meta.ID]; ok { + // skip connected peer + continue + } else if _, ok := dpm.pm.waitingPeers[meta.ID]; ok { + // skip already waiting peer + continue + } + // TODO check blacklist later. + dpm.pm.waitingPeers[meta.ID] = &p2pcommon.WaitingPeer{Meta: meta, NextTrial: time.Now()} + addedWP++ + } + return addedWP +} + +func (dpm *dynamicWPManager) CheckAndConnect() { + dpm.logger.Debug().Msg("checking space to connect more peers") + maxJobs := dpm.getRemainingSpaces() + if maxJobs == 0 { + return + } + dpm.connectWaitingPeers(maxJobs) +} + +func (dpm *dynamicWPManager) getRemainingSpaces() int { + // simpler version. just check total count + // has space to add more connection + affordCnt := dpm.maxPeers - len(dpm.pm.remotePeers) - len(dpm.workingJobs) + if affordCnt <= 0 { + return 0 + } + affordWorker := dpm.basePeerManager.getRemainingSpaces() + if affordCnt < affordWorker { + return affordCnt + } else { + return affordWorker + } +} + +type inboundConnEvent struct { + meta p2pcommon.PeerMeta + p2pVer uint32 + foundC chan bool +} + +type byNextTrial []*p2pcommon.WaitingPeer + +func (a byNextTrial) Len() int { return len(a) } +func (a byNextTrial) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a byNextTrial) Less(i, j int) bool { return a[i].NextTrial.Before(a[j].NextTrial) } + +type ConnWork struct { + PeerID peer.ID + Meta p2pcommon.PeerMeta + StartTime time.Time +} + +// setNextTrial check if peer is worthy to connect, and set time when the server try to connect next time. +// It will true if this node is worth to try connect again, or return false if not. +func setNextTrial(wp *p2pcommon.WaitingPeer) bool { + if wp.Meta.Designated { + wp.TrialCnt++ + wp.NextTrial = time.Now().Add(getNextInterval(wp.TrialCnt)) + return true + } else { + return false + } +} \ No newline at end of file diff --git a/p2p/waitpeermanager_test.go b/p2p/waitpeermanager_test.go new file mode 100644 index 000000000..6fec662d7 --- /dev/null +++ b/p2p/waitpeermanager_test.go @@ -0,0 +1,128 @@ +/* + * @file + * @copyright defined in aergo/LICENSE.txt + */ + +package p2p + +import ( + "github.com/aergoio/aergo/p2p/p2pcommon" + "github.com/aergoio/aergo/p2p/p2pmock" + "github.com/golang/mock/gomock" + "github.com/libp2p/go-libp2p-peer" + "testing" + "time" +) + +const ( + OneDay = time.Hour * 24 +) + +func Test_staticWPManager_OnDiscoveredPeers(t *testing.T) { + ctrl := gomock.NewController(t) + + type args struct { + metas []p2pcommon.PeerMeta + } + tests := []struct { + name string + args args + wantCount int + }{ + {"TSingleDesign", args{desigPeers[:1]}, 0}, + {"TAllDesign", args{desigPeers}, 0}, + {"TNewID", args{unknowPeers}, 0}, + {"TMixedIDs", args{append(unknowPeers[:5], desigPeers[:5]...)}, 0}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + dummyPM := createDummyPM() + mockActor := p2pmock.NewMockActorService(ctrl) + dp := NewWaitingPeerManager(logger, dummyPM, mockActor, 10, false, false).(*staticWPManager) + + dp.OnDiscoveredPeers(tt.args.metas) + if len(dummyPM.waitingPeers) != tt.wantCount { + t.Errorf("count waitingPeer %v, want %v", len(dummyPM.waitingPeers), tt.wantCount) + } + }) + } +} + +func Test_dynamicWPManager_OnDiscoveredPeers(t *testing.T) { + ctrl := gomock.NewController(t) + + type args struct { + preConnected []peer.ID + metas []p2pcommon.PeerMeta + } + tests := []struct { + name string + args args + wantCount int + }{ + {"TAllNew", args{nil, desigPeers[:1]}, 1}, + {"TAllExist", args{desigIDs, desigPeers[:5]}, 0}, + {"TMixedIDs", args{desigIDs, append(unknowPeers[:5], desigPeers[:5]...)}, 5}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + dummyPM := createDummyPM() + mockActor := p2pmock.NewMockActorService(ctrl) + dp := NewWaitingPeerManager(logger, dummyPM, mockActor, 10, true, false) + for _, id := range tt.args.preConnected { + dummyPM.remotePeers[id] = &remotePeerImpl{} + dp.OnPeerConnect(id) + } + + dp.OnDiscoveredPeers(tt.args.metas) + if len(dummyPM.waitingPeers) != tt.wantCount { + t.Errorf("count waitingPeer %v, want %v", len(dummyPM.waitingPeers), tt.wantCount) + } + }) + } +} + +func Test_setNextTrial(t *testing.T) { + dummyDesignated := p2pcommon.PeerMeta{Designated:true} + + type args struct { + wp *p2pcommon.WaitingPeer + setCnt int + } + tests := []struct { + name string + args args + want bool + }{ + {"TDesig1", args{&p2pcommon.WaitingPeer{Meta:dummyDesignated}, 1}, true }, + {"TDesigSome", args{&p2pcommon.WaitingPeer{Meta:dummyDesignated}, 5}, true }, + {"TDesigMany", args{&p2pcommon.WaitingPeer{Meta:dummyDesignated}, 30}, true}, + + {"TUnknown1", args{&p2pcommon.WaitingPeer{Meta:dummyMeta}, 1}, false }, + {"TUnknownSome", args{&p2pcommon.WaitingPeer{Meta:dummyMeta}, 5}, false }, + {"TUnknownMany", args{&p2pcommon.WaitingPeer{Meta:dummyMeta}, 30}, false}, + + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + lastResult := false + prevDuration := time.Duration(0) + for i := 0 ; i Date: Fri, 19 Apr 2019 15:37:28 +0900 Subject: [PATCH 034/148] [P2P] Restore behavior of syncing after connection --- p2p/peermanager.go | 60 +++++++++----------------- p2p/peermanager_test.go | 26 +++++++++--- p2p/waitpeermanager.go | 21 +++++++++- p2p/waitpeermanager_test.go | 84 +++++++++++++++++++++++++++++++------ 4 files changed, 130 insertions(+), 61 deletions(-) diff --git a/p2p/peermanager.go b/p2p/peermanager.go index e95e2cd19..32ea803a4 100644 --- a/p2p/peermanager.go +++ b/p2p/peermanager.go @@ -9,13 +9,11 @@ import ( "sync/atomic" "time" + "github.com/aergoio/aergo-lib/log" + "github.com/aergoio/aergo/message" "github.com/aergoio/aergo/p2p/metric" "github.com/aergoio/aergo/p2p/p2pcommon" "github.com/aergoio/aergo/p2p/p2putil" - "github.com/aergoio/aergo/p2p/subproto" - - "github.com/aergoio/aergo-lib/log" - "github.com/aergoio/aergo/message" "github.com/aergoio/aergo/types" cfg "github.com/aergoio/aergo/config" @@ -64,9 +62,9 @@ type peerManager struct { inboundConnChan chan inboundConnEvent workDoneChannel chan p2pcommon.ConnWorkResult - finishChannel chan struct{} + finishChannel chan struct{} - eventListeners []PeerEventListener + eventListeners []PeerEventListener // designatedPeers map[peer.ID]p2pcommon.PeerMeta @@ -76,7 +74,7 @@ type peerManager struct { // getPeerChan is struct to get peer for concurrent use type getPeerChan struct { - id peer.ID + id peer.ID ret chan p2pcommon.RemotePeer } @@ -165,21 +163,6 @@ func (pm *peerManager) init() { func (pm *peerManager) Start() error { go pm.runManagePeers() - // need to start listen after chainservice is read to init - // FIXME: adhoc code - //go func() { - //time.Sleep(time.Second * 3) - //pm.logger.Info().Str("version", string(p2pcommon.AergoP2PSub)).Msg("Starting p2p listening") - //pm.nt.AddStreamHandler(p2pcommon.AergoP2PSub, pm.onConnect) - - // addition should start after all modules are started - //time.Sleep(time.Second * 2) - //dPeers := make([]p2pcommon.PeerMeta, len(pm.designatedPeers)) - //for _, meta := range pm.designatedPeers { - // dPeers = append(dPeers, meta) - //} - //pm.fillPoolChannel <- dPeers - //}() return nil } @@ -226,7 +209,7 @@ func (pm *peerManager) runManagePeers() { MANLOOP: for { select { - case req := <- pm.getPeerChannel: + case req := <-pm.getPeerChannel: peer, exist := pm.remotePeers[req.id] if exist { req.ret <- peer @@ -237,6 +220,8 @@ MANLOOP: if pm.tryRegister(peer) { pm.peerFinder.OnPeerConnect(peer.ID()) pm.wpManager.OnPeerConnect(peer.ID()) + + pm.checkSync(peer) } case peer := <-pm.removePeerChannel: if pm.removePeer(peer) { @@ -292,7 +277,7 @@ MANLOOP: } }() timer := time.NewTimer(time.Second * 30) - finishPoll := time.NewTicker(time.Millisecond << 6 ) + finishPoll := time.NewTicker(time.Millisecond << 6) CLEANUPLOOP: for { select { @@ -336,23 +321,17 @@ func (pm *peerManager) tryRegister(peer p2pcommon.RemotePeer) bool { go peer.RunPeer() // FIXME type casting is worse - pm.insertPeer(peerID, peer.(*remotePeerImpl)) + pm.insertPeer(peerID, peer) pm.logger.Info().Bool("outbound", receivedMeta.Outbound).Str(p2putil.LogPeerName, peer.Name()).Str("addr", net.ParseIP(receivedMeta.IPAddress).String()+":"+strconv.Itoa(int(receivedMeta.Port))).Msg("peer is added to peerService") + // TODO add triggering sync. + return true } func (pm *peerManager) GetNextManageNum() uint32 { return atomic.AddUint32(&pm.manageNumber, 1) } -func (pm *peerManager) sendGoAway(rw p2pcommon.MsgReadWriter, msg string) { - goMsg := &types.GoAwayNotice{Message: msg} - // TODO code smell. non safe casting. - mo := pm.mf.NewMsgRequestOrder(false, subproto.GoAway, goMsg).(*pbRequestOrder) - container := mo.message - - rw.WriteMsg(container) -} func (pm *peerManager) AddNewPeer(meta p2pcommon.PeerMeta) { sli := []p2pcommon.PeerMeta{meta} @@ -396,14 +375,13 @@ func (pm *peerManager) removePeer(peer p2pcommon.RemotePeer) bool { return true } - func (pm *peerManager) GetPeer(ID peer.ID) (p2pcommon.RemotePeer, bool) { - gc := getPeerChan{id:ID, ret:make(chan p2pcommon.RemotePeer)} + gc := getPeerChan{id: ID, ret: make(chan p2pcommon.RemotePeer)} // vs code's lint does not allow direct return of map operation pm.getPeerChannel <- gc ptr := <-gc.ret - if ptr ==nil { + if ptr == nil { return nil, false } return ptr, true @@ -453,10 +431,7 @@ func (pm *peerManager) GetPeerAddresses(noHidden bool, showSelf bool) []*message } // this method should be called inside pm.mutex -func (pm *peerManager) insertPeer(ID peer.ID, peer *remotePeerImpl) { - if _, exist := pm.hiddenPeerSet[ID]; exist { - peer.meta.Hidden = true - } +func (pm *peerManager) insertPeer(ID peer.ID, peer p2pcommon.RemotePeer) { pm.remotePeers[ID] = peer pm.updatePeerCache() } @@ -475,3 +450,8 @@ func (pm *peerManager) updatePeerCache() { } pm.peerCache = newSlice } + +func (pm *peerManager) checkSync(peer p2pcommon.RemotePeer) { + pm.logger.Debug().Uint64("target", peer.LastStatus().BlockNumber).Msg("request new syncer") + pm.actorService.SendRequest(message.SyncerSvc, &message.SyncStart{PeerID: peer.ID(), TargetNo: peer.LastStatus().BlockNumber}) +} diff --git a/p2p/peermanager_test.go b/p2p/peermanager_test.go index ebc48f6a1..3c1e654c4 100644 --- a/p2p/peermanager_test.go +++ b/p2p/peermanager_test.go @@ -2,6 +2,7 @@ package p2p import ( "fmt" + crypto "github.com/libp2p/go-libp2p-crypto" "strconv" "sync" "sync/atomic" @@ -110,15 +111,27 @@ func TestPeerManager_GetPeers(t *testing.T) { } func TestPeerManager_GetPeerAddresses(t *testing.T) { - peersLen := 3 + peersLen := 6 + hiddenCnt := 3 samplePeers := make([]*remotePeerImpl, peersLen) - samplePeers[0] = &remotePeerImpl{meta: p2pcommon.PeerMeta{ID: dummyPeerID}, lastStatus: &types.LastBlockStatus{}} - samplePeers[1] = &remotePeerImpl{meta: p2pcommon.PeerMeta{ID: dummyPeerID2}, lastStatus: &types.LastBlockStatus{}} - samplePeers[2] = &remotePeerImpl{meta: p2pcommon.PeerMeta{ID: dummyPeerID3}, lastStatus: &types.LastBlockStatus{}} + for i:=0; i