diff --git a/.github/workflows/full_test.yml b/.github/workflows/full_test.yml index 3d2d0c49b..45e36c7e2 100644 --- a/.github/workflows/full_test.yml +++ b/.github/workflows/full_test.yml @@ -55,7 +55,7 @@ jobs: coverageLocations: ${{github.workspace}}/build/c.out:gocov debug: true - # run unit test only in other cases + # run unit test only in other cases - name: Unit Tests if: github.event_name != 'push' || github.ref_name != 'master' || github.ref_type != 'branch' run: go test -timeout 999s ./... @@ -81,7 +81,8 @@ jobs: run: cd tests && ./run_tests.sh raft - name: Upload Logs on Failure - if: failure() + # only upload logs if any of the integration tests failed (even with continue-on-error) + if: steps.sbp_test.outcome == 'failure' || steps.dpos_test.outcome == 'failure' || steps.raft_test.outcome == 'failure' uses: actions/upload-artifact@v4 with: name: integration-test-logs @@ -91,3 +92,9 @@ jobs: tests/error.txt tests/output.json tests/receipt*.json + + - name: Mark Job as Failed + if: steps.sbp_test.outcome == 'failure' || steps.dpos_test.outcome == 'failure' || steps.raft_test.outcome == 'failure' + run: | + echo "One or more integration tests failed!" + exit 1 diff --git a/Makefile b/Makefile index b23750fe1..6aaab7b94 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,7 @@ release: $(BUILD_DIR) debug: $(BUILD_DIR) @cd $(BUILD_DIR) && $(CMAKE_CMD) -G "Unix Makefiles" -D CMAKE_BUILD_TYPE="Debug" $(MAKE_FLAG) .. - @$(MAKE) --no-print-directory -C $(BUILD_DIR) + @$(MAKE) --no-print-directory -C $(BUILD_DIR) CGO_CFLAGS="-DDEBUG" clean: @$(MAKE) --no-print-directory -C $(BUILD_DIR) distclean diff --git a/account/accountservice_test.go b/account/accountservice_test.go index a5d78cbf6..4e6b05f4e 100644 --- a/account/accountservice_test.go +++ b/account/accountservice_test.go @@ -32,7 +32,7 @@ func initTest() { sdb = state.NewChainStateDB() testmode := true - sdb.Init(string(db.BadgerImpl), conf.DataDir, nil, testmode) + sdb.Init(string(db.BadgerImpl), conf.DataDir, nil, testmode, nil) as = NewAccountService(conf, sdb) as.testConfig = true diff --git a/aergo-protobuf b/aergo-protobuf index f0b2b8a6a..70eae4345 160000 --- a/aergo-protobuf +++ b/aergo-protobuf @@ -1 +1 @@ -Subproject commit f0b2b8a6a9347c5b9c44c5bb9e2a30f13a47235b +Subproject commit 70eae4345ecbff37f3b0529f4fb69d3e5d911223 diff --git a/chain/chaindb.go b/chain/chaindb.go index b48c11bb1..779f20b16 100644 --- a/chain/chaindb.go +++ b/chain/chaindb.go @@ -10,6 +10,7 @@ import ( "encoding/json" "errors" "fmt" + "strconv" "sync/atomic" "github.com/aergoio/aergo-lib/db" @@ -77,11 +78,23 @@ func (cdb *ChainDB) NewTx() db.Transaction { return cdb.store.NewTx() } -func (cdb *ChainDB) Init(dbType string, dataDir string) error { +func (cdb *ChainDB) Init(dbType string, dataDir string, opts []db.Option) error { if cdb.store == nil { logger.Info().Str("datadir", dataDir).Msg("chain database initialized") dbPath := common.PathMkdirAll(dataDir, dbkey.ChainDBName) - cdb.store = db.NewDB(db.ImplType(dbType), dbPath) + opts = append(opts, db.Option{ + Name: db.OptCompactionEventHandler, + Value: func(event db.CompactionEvent) { + if event.Start { + logger.Info().Str("reason", event.Reason).Int("fromlevel", event.Level). + Int("nextlevel", event.Level).Int("splits", event.NumSplits).Msg("cdb compaction started") + } else { + logger.Info().Str("reason", event.Reason).Int("fromlevel", event.Level). + Int("nextlevel", event.Level).Int("splits", event.NumSplits).Msg("cdb compaction complete") + } + }, + }) + cdb.store = db.NewDB(db.ImplType(dbType), dbPath, opts...) } // load data @@ -520,7 +533,7 @@ func (cdb *ChainDB) dropBlock(dropNo types.BlockNo) error { } // remove receipt - cdb.deleteReceipts(&dbTx, dropBlock.BlockHash(), dropBlock.BlockNo()) + cdb.deleteReceiptsAndOperations(&dbTx, dropBlock.BlockHash(), dropBlock.BlockNo()) // remove (hash/block) dbTx.Delete(dropBlock.BlockHash()) @@ -665,6 +678,11 @@ func (cdb *ChainDB) checkExistReceipts(blockHash []byte, blockNo types.BlockNo) return true } +func (cdb *ChainDB) getInternalOperations(blockNo types.BlockNo) string { + data := cdb.store.Get(dbkey.InternalOps(blockNo)) + return string(data) +} + type ChainTree struct { Tree []ChainInfo } @@ -691,18 +709,35 @@ func (cdb *ChainDB) GetChainTree() ([]byte, error) { return jsonBytes, nil } -func (cdb *ChainDB) writeReceipts(blockHash []byte, blockNo types.BlockNo, receipts *types.Receipts) { +func (cdb *ChainDB) writeReceiptsAndOperations(block *types.Block, receipts *types.Receipts, internalOps string) { + hasReceipts := len(receipts.Get()) != 0 + hasInternalOps := len(internalOps) != 0 + + if !hasReceipts && !hasInternalOps { + return + } + dbTx := cdb.store.NewTx() defer dbTx.Discard() - val, _ := gob.Encode(receipts) - dbTx.Set(dbkey.Receipts(blockHash, blockNo), val) + blockHash := block.BlockHash() + blockNo := block.BlockNo() + + if hasReceipts { + val, _ := gob.Encode(receipts) + dbTx.Set(dbkey.Receipts(blockHash, blockNo), val) + } + + if hasInternalOps { + dbTx.Set(dbkey.InternalOps(blockNo), []byte(internalOps)) + } dbTx.Commit() } -func (cdb *ChainDB) deleteReceipts(dbTx *db.Transaction, blockHash []byte, blockNo types.BlockNo) { +func (cdb *ChainDB) deleteReceiptsAndOperations(dbTx *db.Transaction, blockHash []byte, blockNo types.BlockNo) { (*dbTx).Delete(dbkey.Receipts(blockHash, blockNo)) + (*dbTx).Delete(dbkey.InternalOps(blockNo)) } func (cdb *ChainDB) writeReorgMarker(marker *ReorgMarker) error { @@ -757,12 +792,42 @@ func (cdb *ChainDB) Hardfork(hConfig config.HardforkConfig) config.HardforkDbCon if err := json.Unmarshal(data, &c); err != nil { return nil } - // When a new hardkfork height is added, the hardfork config from DB (HardforkDBConfig) + // When a new hardfork height is added, the hardfork config from DB (HardforkDBConfig) // must be modified by using the height from HardforkConfig. Without this, aergosvr fails - // to start, since a harfork heght value not stored on DB is evaluated as 0. + // to start, since a hardfork height value not stored on DB is evaluated as 0. return c.FixDbConfig(hConfig) } +func (cdb *ChainDB) hardforkHeights() config.HardforkDbConfig { + var c config.HardforkDbConfig + data := cdb.store.Get(dbkey.HardFork()) + if len(data) == 0 { + return c + } + // TODO Hardfork status is not changed during the lifetime of server process. + // We can optimize this + if err := json.Unmarshal(data, &c); err != nil { + logger.Error().Msg("Failed to read hardfork from cdb") + return c + } + returned := make(map[string]uint64, len(c)) + for key, value := range c { + newKey := key[1:] + if key[0] != 'V' || !IsInteger(newKey) { + return make(map[string]uint64, 0) + } + returned[newKey] = value + } + + return returned +} + +// IsInteger check the parameter is integer form or not +func IsInteger(s string) bool { + _, err := strconv.Atoi(s) + return err == nil +} + func (cdb *ChainDB) WriteHardfork(c *config.HardforkConfig) error { data, err := json.Marshal(c) if err != nil { diff --git a/chain/chaindbForRaft.go b/chain/chaindbForRaft.go index 5f18f18ed..7ca2dba35 100644 --- a/chain/chaindbForRaft.go +++ b/chain/chaindbForRaft.go @@ -74,7 +74,7 @@ func (cdb *ChainDB) ResetWAL(hardStateInfo *types.HardStateInfo) error { return nil } -// ClearWal() removes all data used by raft +// ClearWAL removes all data used by raft func (cdb *ChainDB) ClearWAL() { logger.Info().Msg("clear all data used by raft") @@ -286,7 +286,7 @@ var ( // HasWal checks chaindb has valid status of Raft WAL. // 1. compare identity with config // 2. check if hardstate exists -// 3. check if last raft entiry index exists +// 3. check if last raft entry index exists // last entry index can be 0 if first sync has failed func (cdb *ChainDB) HasWal(identity consensus.RaftIdentity) (bool, error) { var ( diff --git a/chain/chaindb_test.go b/chain/chaindb_test.go new file mode 100644 index 000000000..b43d723ce --- /dev/null +++ b/chain/chaindb_test.go @@ -0,0 +1,97 @@ +package chain + +import ( + "github.com/aergoio/aergo-lib/db" + "github.com/aergoio/aergo/v2/consensus" + "github.com/stretchr/testify/assert" + "sync/atomic" + "testing" +) + +func TestChainDB_hardforkHeights(t *testing.T) { + type fields struct { + cc consensus.ChainConsensus + latest atomic.Value + bestBlock atomic.Value + store db.DB + } + tests := []struct { + name string + hardfork string + wantSuccess bool + }{ + { "normal", `{"V2":2000,"V3":30000,"V4":400000}`, true}, + { "wrong", `{"A":2000,"B3A":30000,"V4":400000}`, false}, + { "wrong2", `{"A2":2000,"B3":30000,"V4":400000}`, false}, + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cdb := &ChainDB{ + store: DBStub{tt.hardfork}, + } + actual := cdb.hardforkHeights() + if tt.wantSuccess { + assert.Equal(t, 3,len(actual), "hardforkHeights()") + assert.Equal(t, uint64(2000), actual["2"], "hardforkHeights() : 2") + assert.Equal(t, uint64(30000), actual["3"], "hardforkHeights() : 3") + assert.Equal(t, uint64(400000), actual["4"], "hardforkHeights() : 4") + assert.Equal(t, uint64(0), actual["5"], "hardforkHeights() : 5") + } else { + assert.Equal(t, 0, len(actual), "hardforkHeights()") + } + }) + } +} + +type DBStub struct { + hardfork string +} + +func (m DBStub) Type() string { + //TODO implement me + panic("implement me") +} + +func (m DBStub) Set(key, value []byte) { + //TODO implement me + panic("implement me") +} + +func (m DBStub) Delete(key []byte) { + //TODO implement me + panic("implement me") +} + +func (m DBStub) Get(key []byte) []byte { + if string(key) == "hardfork" { + return []byte(m.hardfork) + } + //TODO implement me + panic("implement me") +} + +func (m DBStub) Exist(key []byte) bool { + //TODO implement me + panic("implement me") +} + +func (m DBStub) Iterator(start, end []byte) db.Iterator { + //TODO implement me + panic("implement me") +} + +func (m DBStub) NewTx() db.Transaction { + //TODO implement me + panic("implement me") +} + +func (m DBStub) NewBulk() db.Bulk { + //TODO implement me + panic("implement me") +} + +func (m DBStub) Close() { + //TODO implement me + panic("implement me") +} diff --git a/chain/chainhandle.go b/chain/chainhandle.go index d28e4e742..e2a1bcac5 100644 --- a/chain/chainhandle.go +++ b/chain/chainhandle.go @@ -278,6 +278,20 @@ func (cs *ChainService) listEvents(filter *types.FilterInfo) ([]*types.Event, er return events, nil } +func (cs *ChainService) getInternalOperations(blockNo types.BlockNo) (string, error) { + blockInMainChain, err := cs.cdb.GetBlockByNo(blockNo) + if err != nil { + return "", &ErrNoBlock{blockNo} + } + + block, err := cs.cdb.getBlock(blockInMainChain.BlockHash()) + if !bytes.Equal(block.BlockHash(), blockInMainChain.BlockHash()) { + return "", errors.New("internal operations not found") + } + + return cs.cdb.getInternalOperations(blockNo), nil +} + type chainProcessor struct { *ChainService block *types.Block // starting block @@ -811,9 +825,7 @@ func (cs *ChainService) executeBlock(bstate *state.BlockState, block *types.Bloc return err } - if len(ex.BlockState.Receipts().Get()) != 0 { - cs.cdb.writeReceipts(block.BlockHash(), block.BlockNo(), ex.BlockState.Receipts()) - } + cs.cdb.writeReceiptsAndOperations(block, ex.BlockState.Receipts(), ex.BlockState.InternalOps()) cs.notifyEvents(block, ex.BlockState) @@ -1007,11 +1019,12 @@ func executeTx(execCtx context.Context, ccc consensus.ChainConsensusCluster, cdb var txFee *big.Int var rv string + var internalOps string var events []*types.Event switch txBody.Type { case types.TxType_NORMAL, types.TxType_TRANSFER, types.TxType_CALL, types.TxType_MULTICALL, types.TxType_DEPLOY, types.TxType_REDEPLOY: - rv, events, txFee, err = contract.Execute(execCtx, bs, cdb, tx.GetTx(), sender, receiver, bi, executionMode, false) + rv, events, internalOps, txFee, err = contract.Execute(execCtx, bs, cdb, tx.GetTx(), sender, receiver, bi, executionMode, false) sender.SubBalance(txFee) case types.TxType_GOVERNANCE: txFee = new(big.Int).SetUint64(0) @@ -1039,7 +1052,7 @@ func executeTx(execCtx context.Context, ccc consensus.ChainConsensusCluster, cdb } return types.ErrNotAllowedFeeDelegation } - rv, events, txFee, err = contract.Execute(execCtx, bs, cdb, tx.GetTx(), sender, receiver, bi, executionMode, true) + rv, events, internalOps, txFee, err = contract.Execute(execCtx, bs, cdb, tx.GetTx(), sender, receiver, bi, executionMode, true) receiver.SubBalance(txFee) } @@ -1094,6 +1107,10 @@ func executeTx(execCtx context.Context, ccc consensus.ChainConsensusCluster, cdb } bs.BpReward.Add(&bs.BpReward, txFee) + if len(internalOps) > 0 { + bs.AddInternalOps(internalOps) + } + receipt := types.NewReceipt(receiver.ID(), status, rv) receipt.FeeUsed = txFee.Bytes() receipt.TxHash = tx.GetHash() diff --git a/chain/chainhandle_test.go b/chain/chainhandle_test.go index a71e1c1bc..a5573572a 100644 --- a/chain/chainhandle_test.go +++ b/chain/chainhandle_test.go @@ -27,7 +27,7 @@ func initTest(t *testing.T, testmode bool) { sdb = state.NewChainStateDB() tmpdir, _ := ioutil.TempDir("", "test") keystore = key.NewStore(tmpdir, 0) - sdb.Init(string(db.BadgerImpl), tmpdir, nil, testmode) + sdb.Init(string(db.BadgerImpl), tmpdir, nil, testmode, nil) genesis := types.GetTestGenesis() chainID = genesis.Block().GetHeader().ChainID diff --git a/chain/chainservice.go b/chain/chainservice.go index e1a579f25..7c14d5bb8 100644 --- a/chain/chainservice.go +++ b/chain/chainservice.go @@ -6,11 +6,12 @@ package chain import ( - "os" "errors" "fmt" + "github.com/aergoio/aergo-lib/db" "math" "math/big" + "os" "reflect" "runtime" "strings" @@ -54,13 +55,13 @@ type Core struct { } // NewCore returns an instance of Core. -func NewCore(dbType string, dataDir string, testModeOn bool, forceResetHeight types.BlockNo) (*Core, error) { +func NewCore(dbType string, dataDir string, testModeOn bool, forceResetHeight types.BlockNo, dbConfig *cfg.DBConfig) (*Core, error) { core := &Core{ cdb: NewChainDB(), sdb: state.NewChainStateDB(), } - err := core.init(dbType, dataDir, testModeOn, forceResetHeight) + err := core.init(dbType, dataDir, testModeOn, forceResetHeight, dbConfig) if err != nil { return nil, err } @@ -69,9 +70,11 @@ func NewCore(dbType string, dataDir string, testModeOn bool, forceResetHeight ty } // Init prepares Core (chain & state DB). -func (core *Core) init(dbType string, dataDir string, testModeOn bool, forceResetHeight types.BlockNo) error { +func (core *Core) init(dbType string, dataDir string, testModeOn bool, forceResetHeight types.BlockNo, config *cfg.DBConfig) error { // init chaindb - if err := core.cdb.Init(dbType, dataDir); err != nil { + // Compaction option currently only supported by BadgerDB + optionsForChainDB := db.WithControlCompaction(config.ControlCompaction, config.ChainDBPort); + if err := core.cdb.Init(dbType, dataDir, optionsForChainDB); err != nil { logger.Fatal().Err(err).Msg("failed to initialize chaindb") return err } @@ -91,7 +94,8 @@ func (core *Core) init(dbType string, dataDir string, testModeOn bool, forceRese return err } - if err := core.sdb.Init(dbType, dataDir, bestBlock, testModeOn); err != nil { + optionsForStateDB := db.WithControlCompaction(config.ControlCompaction, config.StateDBPort); + if err := core.sdb.Init(dbType, dataDir, bestBlock, testModeOn, optionsForStateDB); err != nil { logger.Fatal().Err(err).Msg("failed to initialize statedb") return err } @@ -185,6 +189,7 @@ type IChainHandler interface { getReceipt(txHash []byte) (*types.Receipt, error) getReceipts(blockHash []byte) (*types.Receipts, error) getReceiptsByNo(blockNo types.BlockNo) (*types.Receipts, error) + getInternalOperations(blockNo types.BlockNo) (string, error) getAccountVote(addr []byte) (*types.AccountVoteInfo, error) getVotes(id string, n uint32) (*types.VoteList, error) getStaking(addr []byte) (*types.Staking, error) @@ -233,7 +238,7 @@ func NewChainService(cfg *cfg.Config) *ChainService { cs.setRecovered(false) var err error - if cs.Core, err = NewCore(cfg.DbType, cfg.DataDir, cfg.EnableTestmode, types.BlockNo(cfg.Blockchain.ForceResetHeight)); err != nil { + if cs.Core, err = NewCore(cfg.DbType, cfg.DataDir, cfg.EnableTestmode, types.BlockNo(cfg.Blockchain.ForceResetHeight), cfg.DB); err != nil { logger.Panic().Err(err).Msg("failed to initialize DB") } @@ -299,7 +304,7 @@ func NewChainService(cfg *cfg.Config) *ChainService { contract.TraceBlockNo = cfg.Blockchain.StateTrace contract.SetStateSQLMaxDBSize(cfg.SQL.MaxDbSize) contract.StartLStateFactory((cfg.Blockchain.NumWorkers+2)*(int(contract.MaxCallDepth(cfg.Hardfork.Version(math.MaxUint64)))+2), cfg.Blockchain.NumLStateClosers, cfg.Blockchain.CloseLimit) - contract.InitContext(cfg.Blockchain.NumWorkers + 2) + contract.InitContext(cfg.Blockchain.NumWorkers + 2, cfg.RPC.LogInternalOperations) // For a strict governance transaction validation. types.InitGovernance(cs.ConsensusType(), cs.IsPublic()) @@ -447,6 +452,7 @@ func (cs *ChainService) Receive(context actor.Context) { *message.GetReceipt, *message.GetReceipts, *message.GetReceiptsByNo, + *message.GetInternalOperations, *message.GetABI, *message.GetQuery, *message.GetStateQuery, @@ -815,6 +821,12 @@ func (cw *ChainWorker) Receive(context actor.Context) { Receipts: receipts, Err: err, }) + case *message.GetInternalOperations: + operations, err := cw.getInternalOperations(msg.BlockNo) + context.Respond(message.GetInternalOperationsRsp{ + Operations: operations, + Err: err, + }) case *message.GetABI: sdb = cw.sdb.OpenNewStateDB(cw.sdb.GetRoot()) address, err := getAddressNameResolved(sdb, msg.Contract) @@ -990,3 +1002,7 @@ func (cs *ChainService) ChainID(bno types.BlockNo) *types.ChainID { cid.Version = cs.cfg.Hardfork.Version(bno) return cid } + +func (cs *ChainService) HardforkHeights() map[string]types.BlockNo { + return cs.cdb.hardforkHeights() +} diff --git a/chain/reorg.go b/chain/reorg.go index 41babf9b4..d0e27c803 100644 --- a/chain/reorg.go +++ b/chain/reorg.go @@ -491,7 +491,7 @@ func (reorg *reorganizer) rollback() error { func (reorg *reorganizer) deleteOldReceipts() { dbTx := reorg.cs.cdb.NewTx() for _, blk := range reorg.oldBlocks { - reorg.cs.cdb.deleteReceipts(&dbTx, blk.GetHash(), blk.BlockNo()) + reorg.cs.cdb.deleteReceiptsAndOperations(&dbTx, blk.GetHash(), blk.BlockNo()) } dbTx.Commit() } diff --git a/chain/stubchain.go b/chain/stubchain.go index 587a508bd..02023aebc 100644 --- a/chain/stubchain.go +++ b/chain/stubchain.go @@ -218,6 +218,11 @@ func (tchain *StubBlockChain) ChainID(bno types.BlockNo) *types.ChainID { return nil } +func (tchain *StubBlockChain) HardforkHeights() map[string]types.BlockNo { + // FIXME: maybe it should return at least latest hardfork + return nil +} + func (tchain *StubBlockChain) Rollback(ancestor *types.BlockInfo) { prevBest := tchain.Best tchain.Best = int(ancestor.No) diff --git a/cmd/aergocli/cmd/contract.go b/cmd/aergocli/cmd/contract.go index 709e26336..41c9dd7f8 100644 --- a/cmd/aergocli/cmd/contract.go +++ b/cmd/aergocli/cmd/contract.go @@ -10,8 +10,7 @@ import ( "strconv" luacEncoding "github.com/aergoio/aergo/v2/cmd/aergoluac/encoding" - luac "github.com/aergoio/aergo/v2/cmd/aergoluac/util" - "github.com/aergoio/aergo/v2/cmd/brick/pack" + luaUtil "github.com/aergoio/aergo/v2/cmd/aergoluac/util" "github.com/aergoio/aergo/v2/internal/common" "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/internal/enc/hex" @@ -31,6 +30,7 @@ var ( feeDelegation bool contractID string gas uint64 + fullProof bool ) func intListToString(ns []int, word string) string { @@ -123,6 +123,7 @@ func init() { } stateQueryCmd.Flags().StringVar(&stateroot, "root", "", "Query the state at a specified state root") stateQueryCmd.Flags().BoolVar(&compressed, "compressed", false, "Get a compressed proof for the state") + stateQueryCmd.Flags().BoolVar(&fullProof, "fullproof", false, "Print the full proof instead of just the value") contractCmd.AddCommand( deployCmd, @@ -180,7 +181,7 @@ func runDeployCmd(cmd *cobra.Command, args []string) error { cmd.SilenceUsage = false return errors.New("not enough arguments") } - codeString, err := pack.ReadContract(args[1]) + codeString, err := luaUtil.ReadContract(args[1]) if err != nil { return fmt.Errorf("failed to read code file: %v", err.Error()) } @@ -193,7 +194,7 @@ func runDeployCmd(cmd *cobra.Command, args []string) error { } deployArgs = []byte(args[2]) } - payload = luac.NewLuaCodePayload(luac.LuaCode(code), deployArgs) + payload = luaUtil.NewLuaCodePayload(luaUtil.LuaCode(code), deployArgs) } else { if chainInfo.Id.Version >= 4 { cmd.SilenceUsage = false @@ -222,7 +223,7 @@ func runDeployCmd(cmd *cobra.Command, args []string) error { if err != nil { return fmt.Errorf("failed to decode code: %v", err.Error()) } - payload = luac.NewLuaCodePayload(luac.LuaCode(code), deployArgs) + payload = luaUtil.NewLuaCodePayload(luaUtil.LuaCode(code), deployArgs) } } @@ -486,7 +487,35 @@ func runQueryStateCmd(cmd *cobra.Command, args []string) error { if err != nil { return fmt.Errorf("failed to query contract state: %v", err.Error()) } - cmd.Println(ret) + if ret == nil { + return fmt.Errorf("no proof generated") + } + + // Format the response as JSON + if len(ret.GetVarProofs()) > 0 && !fullProof { + for _, proof := range ret.GetVarProofs() { + // Try to parse the value as JSON first + var parsedValue interface{} + if err := json.Unmarshal([]byte(proof.Value), &parsedValue); err == nil { + // If it's valid JSON, print it nicely formatted + jsonBytes, err := json.MarshalIndent(parsedValue, "", " ") + if err == nil { + cmd.Println(string(jsonBytes)) + return nil + } + } + // If not valid JSON or couldn't format, just print the value + cmd.Println(proof.Value) + } + } else { + // If fullProof is true or we can't extract a specific value, format the entire response as JSON + jsonBytes, err := json.MarshalIndent(ret, "", " ") + if err != nil { + return fmt.Errorf("failed to marshal response to JSON: %v", err) + } + cmd.Println(string(jsonBytes)) + } + return nil } diff --git a/cmd/aergocli/cmd/internal_operations.go b/cmd/aergocli/cmd/internal_operations.go new file mode 100644 index 000000000..d1b9ea1af --- /dev/null +++ b/cmd/aergocli/cmd/internal_operations.go @@ -0,0 +1,73 @@ +/** + * @file + * @copyright defined in aergo/LICENSE.txt + */ + +package cmd + +import ( + "context" + "encoding/json" + "log" + + "github.com/aergoio/aergo/v2/internal/enc/base58" + aergorpc "github.com/aergoio/aergo/v2/types" + "github.com/spf13/cobra" +) + +func init() { + operationsCmd := &cobra.Command{ + Use: "operations tx_hash", + Short: "Get internal operations for a transaction", + Args: cobra.MinimumNArgs(1), + Run: func(cmd *cobra.Command, args []string) { + // Decode the transaction hash + txHash, err := base58.Decode(args[0]) + if err != nil { + log.Fatal(err) + } + + // Retrieve the receipt to get the block height + receipt, err := client.GetReceipt(context.Background(), &aergorpc.SingleBytes{Value: txHash}) + if err != nil { + log.Fatal(err) + } + + // Extract block height from the receipt + blockHeight := receipt.BlockNo + + // Use block height to get internal operations + msg, err := client.GetInternalOperations(context.Background(), &aergorpc.BlockNumberParam{BlockNo: blockHeight}) + if err != nil { + log.Fatal(err) + } + + // Extract the internal operations for the specific transaction + var operations []map[string]interface{} + if err := json.Unmarshal([]byte(msg.Value), &operations); err != nil { + log.Fatal(err) + } + + // Print the internal operations for the specific transaction + var ops string + for _, op := range operations { + if op["txhash"] == args[0] { + // Remove the txhash field + delete(op, "txhash") + // Marshal the operation to JSON for better readability + opJSON, err := json.MarshalIndent(op, "", " ") + if err != nil { + log.Fatal(err) + } + ops = string(opJSON) + } + } + if ops == "" { + cmd.Println("No internal operations found for this transaction.") + } else { + cmd.Println(ops) + } + }, + } + rootCmd.AddCommand(operationsCmd) +} diff --git a/cmd/aergocli/cmd/mock_types/mock_types.go b/cmd/aergocli/cmd/mock_types/mock_types.go index 0aeefc753..2c5372568 100644 --- a/cmd/aergocli/cmd/mock_types/mock_types.go +++ b/cmd/aergocli/cmd/mock_types/mock_types.go @@ -895,3 +895,23 @@ func (mr *MockAergoRPCServiceClientMockRecorder) VerifyTX(arg0, arg1 interface{} varargs := append([]interface{}{arg0, arg1}, arg2...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyTX", reflect.TypeOf((*MockAergoRPCServiceClient)(nil).VerifyTX), varargs...) } + +// GetInternalOperations mocks base method +func (m *MockAergoRPCServiceClient) GetInternalOperations(arg0 context.Context, arg1 *types.BlockNumberParam, arg2 ...grpc.CallOption) (*types.SingleBytes, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetInternalOperations", varargs...) + ret0, _ := ret[0].(*types.SingleBytes) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetInternalOperations indicates an expected call of GetInternalOperations +func (mr *MockAergoRPCServiceClientMockRecorder) GetInternalOperations(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetInternalOperations", reflect.TypeOf((*MockAergoRPCServiceClient)(nil).GetInternalOperations), varargs...) +} diff --git a/cmd/aergoluac/util/compile.c b/cmd/aergoluac/luac/compile.c similarity index 88% rename from cmd/aergoluac/util/compile.c rename to cmd/aergoluac/luac/compile.c index 0f645b0b0..c2d9ed410 100644 --- a/cmd/aergoluac/util/compile.c +++ b/cmd/aergoluac/luac/compile.c @@ -56,7 +56,7 @@ const char *vm_compile(lua_State *L, const char *code, const char *byte, const c if (f == NULL) { return "cannot open a bytecode file"; } - if (lua_dump(L, kpt_lua_Writer, f) != 0) { + if (lua_dump(L, kpt_lua_Writer, f, 1) != 0) { fclose(f); return lua_tostring(L, -1); } @@ -97,9 +97,14 @@ const char *vm_loadstring(lua_State *L, const char *code) { const char *vm_stringdump(lua_State *L) { luaL_Buffer b; + int strip = 1; // default: strip debug info + +#ifdef DEBUG + strip = 0; // if DEBUG is defined, do not strip debug info +#endif luaL_buffinit(L, &b); - if (lua_dump(L, writer_buf, &b) != 0) { + if (lua_dump(L, writer_buf, &b, strip) != 0) { return lua_tostring(L, -1); } luaL_pushresult(&b); /* code dump */ @@ -107,8 +112,7 @@ const char *vm_stringdump(lua_State *L) { return "empty bytecode"; } lua_pushvalue(L, -2); /* code dump code */ - GEN_ABI(); /* code dump code abi */ - lua_remove(L, -2); /* code dump abi */ + GEN_ABI(); /* code dump code abi */ + lua_remove(L, -2); /* code dump abi */ return NULL; } - diff --git a/cmd/aergoluac/util/compile.h b/cmd/aergoluac/luac/compile.h similarity index 100% rename from cmd/aergoluac/util/compile.h rename to cmd/aergoluac/luac/compile.h diff --git a/cmd/aergoluac/luac/luac.go b/cmd/aergoluac/luac/luac.go new file mode 100644 index 000000000..1482992e1 --- /dev/null +++ b/cmd/aergoluac/luac/luac.go @@ -0,0 +1,131 @@ +package luac + +/* +#cgo CFLAGS: -I${SRCDIR}/../../../libtool/include/luajit-2.1 +#cgo LDFLAGS: ${SRCDIR}/../../../libtool/lib/libluajit-5.1.a -lm + +#include +#include +#include "compile.h" +*/ +import "C" +import ( + "bufio" + "bytes" + "errors" + "fmt" + "io/ioutil" + "os" + "runtime" + "unsafe" + + "github.com/aergoio/aergo/v2/cmd/aergoluac/encoding" + "github.com/aergoio/aergo/v2/cmd/aergoluac/util" +) + +func NewLState() *C.lua_State { + L := C.luac_vm_newstate() + if L == nil { + runtime.GC() + L = C.luac_vm_newstate() + } + return L +} + +func CloseLState(L *C.lua_State) { + if L != nil { + C.luac_vm_close(L) + } +} + +func Compile(L *C.lua_State, code string) (util.LuaCode, error) { + cStr := C.CString(code) + defer C.free(unsafe.Pointer(cStr)) + if errMsg := C.vm_loadstring(L, cStr); errMsg != nil { + return nil, errors.New(C.GoString(errMsg)) + } + if errMsg := C.vm_stringdump(L); errMsg != nil { + return nil, errors.New(C.GoString(errMsg)) + } + return dumpToBytes(L), nil +} + +func CompileFromFile(srcFileName, outFileName, abiFileName string) error { + cSrcFileName := C.CString(srcFileName) + cOutFileName := C.CString(outFileName) + cAbiFileName := C.CString(abiFileName) + L := C.luac_vm_newstate() + defer C.free(unsafe.Pointer(cSrcFileName)) + defer C.free(unsafe.Pointer(cOutFileName)) + defer C.free(unsafe.Pointer(cAbiFileName)) + defer C.luac_vm_close(L) + + if errMsg := C.vm_compile(L, cSrcFileName, cOutFileName, cAbiFileName); errMsg != nil { + return errors.New(C.GoString(errMsg)) + } + return nil +} + +func DumpFromFile(srcFileName string) error { + cSrcFileName := C.CString(srcFileName) + L := C.luac_vm_newstate() + defer C.free(unsafe.Pointer(cSrcFileName)) + defer C.luac_vm_close(L) + + if errMsg := C.vm_loadfile(L, cSrcFileName); errMsg != nil { + return errors.New(C.GoString(errMsg)) + } + if errMsg := C.vm_stringdump(L); errMsg != nil { + return errors.New(C.GoString(errMsg)) + } + + fmt.Println(encoding.EncodeCode(dumpToBytes(L))) + return nil +} + +func DumpFromStdin() error { + fi, err := os.Stdin.Stat() + if err != nil { + return err + } + var buf []byte + if (fi.Mode() & os.ModeCharDevice) == 0 { + buf, err = ioutil.ReadAll(os.Stdin) + if err != nil { + return err + } + } else { + var bBuf bytes.Buffer + scanner := bufio.NewScanner(os.Stdin) + for scanner.Scan() { + bBuf.WriteString(scanner.Text() + "\n") + } + if err = scanner.Err(); err != nil { + return err + } + buf = bBuf.Bytes() + } + srcCode := C.CString(string(buf)) + L := C.luac_vm_newstate() + defer C.free(unsafe.Pointer(srcCode)) + defer C.luac_vm_close(L) + + if errMsg := C.vm_loadstring(L, srcCode); errMsg != nil { + return errors.New(C.GoString(errMsg)) + } + if errMsg := C.vm_stringdump(L); errMsg != nil { + return errors.New(C.GoString(errMsg)) + } + fmt.Println(encoding.EncodeCode(dumpToBytes(L))) + return nil +} + +func dumpToBytes(L *C.lua_State) util.LuaCode { + var ( + c, a *C.char + lc, la C.size_t + ) + c = C.lua_tolstring(L, -2, &lc) + a = C.lua_tolstring(L, -1, &la) + return util.NewLuaCode(C.GoBytes(unsafe.Pointer(c), C.int(lc)), C.GoBytes(unsafe.Pointer(a), C.int(la))) +} diff --git a/cmd/aergoluac/util/state_module.c b/cmd/aergoluac/luac/state_module.c similarity index 100% rename from cmd/aergoluac/util/state_module.c rename to cmd/aergoluac/luac/state_module.c diff --git a/cmd/aergoluac/util/state_module.h b/cmd/aergoluac/luac/state_module.h similarity index 100% rename from cmd/aergoluac/util/state_module.h rename to cmd/aergoluac/luac/state_module.h diff --git a/cmd/aergoluac/main.go b/cmd/aergoluac/main.go index 1c4c120b3..a0ca3e818 100644 --- a/cmd/aergoluac/main.go +++ b/cmd/aergoluac/main.go @@ -10,6 +10,7 @@ import ( "os" "github.com/aergoio/aergo/v2/cmd/aergoluac/util" + "github.com/aergoio/aergo/v2/cmd/aergoluac/luac" "github.com/spf13/cobra" ) @@ -44,15 +45,15 @@ func init() { } } else if payload { if len(args) == 0 { - err = util.DumpFromStdin() + err = luac.DumpFromStdin() } else { - err = util.DumpFromFile(args[0]) + err = luac.DumpFromFile(args[0]) } } else { if len(args) < 2 { return errors.New("2 arguments required: ") } - err = util.CompileFromFile(args[0], args[1], abiFile) + err = luac.CompileFromFile(args[0], args[1], abiFile) } return err diff --git a/cmd/aergoluac/util/luac_util.go b/cmd/aergoluac/util/luac_util.go deleted file mode 100644 index 9fc9daa89..000000000 --- a/cmd/aergoluac/util/luac_util.go +++ /dev/null @@ -1,327 +0,0 @@ -package util - -/* -#cgo CFLAGS: -I${SRCDIR}/../../../libtool/include/luajit-2.1 -#cgo LDFLAGS: ${SRCDIR}/../../../libtool/lib/libluajit-5.1.a -lm - -#include -#include -#include "compile.h" -*/ -import "C" -import ( - "bufio" - "bytes" - "encoding/binary" - "errors" - "fmt" - "io/ioutil" - "os" - "runtime" - "unsafe" - - "github.com/aergoio/aergo/v2/internal/enc/hex" - "github.com/aergoio/aergo/v2/internal/enc/base58" - "github.com/aergoio/aergo/v2/cmd/aergoluac/encoding" -) - -func NewLState() *C.lua_State { - L := C.luac_vm_newstate() - if L == nil { - runtime.GC() - L = C.luac_vm_newstate() - } - return L -} - -func CloseLState(L *C.lua_State) { - if L != nil { - C.luac_vm_close(L) - } -} - -func Compile(L *C.lua_State, code string) (LuaCode, error) { - cStr := C.CString(code) - defer C.free(unsafe.Pointer(cStr)) - if errMsg := C.vm_loadstring(L, cStr); errMsg != nil { - return nil, errors.New(C.GoString(errMsg)) - } - if errMsg := C.vm_stringdump(L); errMsg != nil { - return nil, errors.New(C.GoString(errMsg)) - } - return dumpToBytes(L), nil -} - -func CompileFromFile(srcFileName, outFileName, abiFileName string) error { - cSrcFileName := C.CString(srcFileName) - cOutFileName := C.CString(outFileName) - cAbiFileName := C.CString(abiFileName) - L := C.luac_vm_newstate() - defer C.free(unsafe.Pointer(cSrcFileName)) - defer C.free(unsafe.Pointer(cOutFileName)) - defer C.free(unsafe.Pointer(cAbiFileName)) - defer C.luac_vm_close(L) - - if errMsg := C.vm_compile(L, cSrcFileName, cOutFileName, cAbiFileName); errMsg != nil { - return errors.New(C.GoString(errMsg)) - } - return nil -} - -func DumpFromFile(srcFileName string) error { - cSrcFileName := C.CString(srcFileName) - L := C.luac_vm_newstate() - defer C.free(unsafe.Pointer(cSrcFileName)) - defer C.luac_vm_close(L) - - if errMsg := C.vm_loadfile(L, cSrcFileName); errMsg != nil { - return errors.New(C.GoString(errMsg)) - } - if errMsg := C.vm_stringdump(L); errMsg != nil { - return errors.New(C.GoString(errMsg)) - } - - fmt.Println(encoding.EncodeCode(dumpToBytes(L))) - return nil -} - -func DumpFromStdin() error { - fi, err := os.Stdin.Stat() - if err != nil { - return err - } - var buf []byte - if (fi.Mode() & os.ModeCharDevice) == 0 { - buf, err = ioutil.ReadAll(os.Stdin) - if err != nil { - return err - } - } else { - var bBuf bytes.Buffer - scanner := bufio.NewScanner(os.Stdin) - for scanner.Scan() { - bBuf.WriteString(scanner.Text() + "\n") - } - if err = scanner.Err(); err != nil { - return err - } - buf = bBuf.Bytes() - } - srcCode := C.CString(string(buf)) - L := C.luac_vm_newstate() - defer C.free(unsafe.Pointer(srcCode)) - defer C.luac_vm_close(L) - - if errMsg := C.vm_loadstring(L, srcCode); errMsg != nil { - return errors.New(C.GoString(errMsg)) - } - if errMsg := C.vm_stringdump(L); errMsg != nil { - return errors.New(C.GoString(errMsg)) - } - fmt.Println(encoding.EncodeCode(dumpToBytes(L))) - return nil -} - -func dumpToBytes(L *C.lua_State) LuaCode { - var ( - c, a *C.char - lc, la C.size_t - ) - c = C.lua_tolstring(L, -2, &lc) - a = C.lua_tolstring(L, -1, &la) - return NewLuaCode(C.GoBytes(unsafe.Pointer(c), C.int(lc)), C.GoBytes(unsafe.Pointer(a), C.int(la))) -} - -func Decode(srcFileName string, payload string) error { - var decoded []byte - var err error - - // check if the payload is in hex format - if hex.IsHexString(payload) { - // the data is expected to be copied from aergoscan view of - // the transaction that deployed the contract - decoded, err = hex.Decode(payload) - } else { - // the data is the output of aergoluac - decoded, err = encoding.DecodeCode(payload) - if err != nil { - // the data is extracted from JSON transaction from aergocli - decoded, err = base58.Decode(payload) - } - } - if err != nil { - return fmt.Errorf("failed to decode payload 1: %v", err.Error()) - } - - data := LuaCodePayload(decoded) - _, err = data.IsValidFormat() - if err != nil { - return fmt.Errorf("failed to decode payload 2: %v", err.Error()) - } - - contract := data.Code() - if !contract.IsValidFormat() { - // the data is the output of aergoluac, so it does not contain deploy arguments - contract = LuaCode(decoded) - data = NewLuaCodePayload(contract, []byte{}) - } - - err = os.WriteFile(srcFileName + "-bytecode", contract.ByteCode(), 0644); - if err != nil { - return fmt.Errorf("failed to write bytecode file: %v", err.Error()) - } - - err = os.WriteFile(srcFileName + "-abi", contract.ABI(), 0644); - if err != nil { - return fmt.Errorf("failed to write ABI file: %v", err.Error()) - } - - var deployArgs []byte - if data.HasArgs() { - deployArgs = data.Args() - } - err = os.WriteFile(srcFileName + "-deploy-arguments", deployArgs, 0644); - if err != nil { - return fmt.Errorf("failed to write deploy-arguments file: %v", err.Error()) - } - - fmt.Println("done.") - return nil -} - -func DecodeFromFile(srcFileName string) error { - payload, err := os.ReadFile(srcFileName) - if err != nil { - return fmt.Errorf("failed to read payload file: %v", err.Error()) - } - return Decode(srcFileName, string(payload)) -} - -func DecodeFromStdin() error { - fi, err := os.Stdin.Stat() - if err != nil { - return err - } - var buf []byte - if (fi.Mode() & os.ModeCharDevice) == 0 { - buf, err = ioutil.ReadAll(os.Stdin) - if err != nil { - return err - } - } else { - var bBuf bytes.Buffer - scanner := bufio.NewScanner(os.Stdin) - for scanner.Scan() { - bBuf.WriteString(scanner.Text() + "\n") - } - if err = scanner.Err(); err != nil { - return err - } - buf = bBuf.Bytes() - } - return Decode("contract", string(buf)) -} - - -type LuaCode []byte - -const byteCodeLenLen = 4 - -func NewLuaCode(byteCode, abi []byte) LuaCode { - byteCodeLen := len(byteCode) - code := make(LuaCode, byteCodeLenLen+byteCodeLen+len(abi)) - binary.LittleEndian.PutUint32(code, uint32(byteCodeLen)) - copy(code[byteCodeLenLen:], byteCode) - copy(code[byteCodeLenLen+byteCodeLen:], abi) - return code -} - -func (c LuaCode) ByteCode() []byte { - if !c.IsValidFormat() { - return nil - } - return c[byteCodeLenLen : byteCodeLenLen+c.byteCodeLen()] -} - -func (c LuaCode) byteCodeLen() int { - if c.Len() < byteCodeLenLen { - return 0 - } - return int(binary.LittleEndian.Uint32(c[:byteCodeLenLen])) -} - -func (c LuaCode) ABI() []byte { - if !c.IsValidFormat() { - return nil - } - return c[byteCodeLenLen+c.byteCodeLen():] -} - -func (c LuaCode) Len() int { - return len(c) -} - -func (c LuaCode) IsValidFormat() bool { - if c.Len() <= byteCodeLenLen { - return false - } - return byteCodeLenLen+c.byteCodeLen() < c.Len() -} - -func (c LuaCode) Bytes() []byte { - return c -} - -type LuaCodePayload []byte - -const codeLenLen = 4 - -func NewLuaCodePayload(code LuaCode, args []byte) LuaCodePayload { - payload := make([]byte, codeLenLen+code.Len()+len(args)) - binary.LittleEndian.PutUint32(payload[0:], uint32(code.Len()+codeLenLen)) - copy(payload[codeLenLen:], code.Bytes()) - copy(payload[codeLenLen+code.Len():], args) - return payload -} - -func (p LuaCodePayload) headLen() int { - if p.Len() < codeLenLen { - return 0 - } - return int(binary.LittleEndian.Uint32(p[:codeLenLen])) -} - -func (p LuaCodePayload) Code() LuaCode { - if v, _ := p.IsValidFormat(); !v { - return nil - } - return LuaCode(p[codeLenLen:p.headLen()]) -} - -func (p LuaCodePayload) HasArgs() bool { - if v, _ := p.IsValidFormat(); !v { - return false - } - return len(p) > p.headLen() -} - -func (p LuaCodePayload) Args() []byte { - if v, _ := p.IsValidFormat(); !v { - return nil - } - return p[p.headLen():] -} - -func (p LuaCodePayload) Len() int { - return len(p) -} - -func (p LuaCodePayload) IsValidFormat() (bool, error) { - if p.Len() <= codeLenLen { - return false, fmt.Errorf("invalid code (%d bytes is too short)", p.Len()) - } - if p.Len() < p.headLen() { - return false, fmt.Errorf("invalid code (expected %d bytes, actual %d bytes)", p.headLen(), p.Len()) - } - return true, nil -} diff --git a/cmd/aergoluac/util/util.go b/cmd/aergoluac/util/util.go new file mode 100644 index 000000000..5e0d1c261 --- /dev/null +++ b/cmd/aergoluac/util/util.go @@ -0,0 +1,375 @@ +package util + +import ( + "bufio" + "bytes" + "encoding/binary" + "fmt" + "io/ioutil" + "os" + "net/http" + "path/filepath" + "strings" + + "github.com/aergoio/aergo/v2/internal/enc/hex" + "github.com/aergoio/aergo/v2/internal/enc/base58" + "github.com/aergoio/aergo/v2/cmd/aergoluac/encoding" +) + + +//////////////////////////////////////////////////////////////////////////////// +// Pack/Bundle +//////////////////////////////////////////////////////////////////////////////// + +// Set to track imported files +var importedFiles = make(map[string]bool) + +// ProcessLines processes a string containing contract code, handling imports +func processLines(input string, currentDir string) (string, error) { + + // Create a string builder for the output + var output strings.Builder + + // Process each line + scanner := bufio.NewScanner(strings.NewReader(input)) + for scanner.Scan() { + line := scanner.Text() + + // Check if line starts with "import " + if strings.HasPrefix(line, "import ") { + // Extract the file name from import statement + importLine := strings.TrimSpace(line[6:]) // Remove "import " prefix + + // Check if it has minimum length for a valid import + if len(importLine) < 3 { + return "", fmt.Errorf("invalid import format: %s", line) + } + + // Check if it starts with a valid quote character + quoteChar := importLine[0] + if quoteChar != '"' && quoteChar != '\'' { + return "", fmt.Errorf("import statement must use quotes: %s", line) + } + + // Check if it ends with the same quote character + if importLine[len(importLine)-1] != quoteChar { + return "", fmt.Errorf("mismatched quotes in import: %s", line) + } + + // Extract the file path between quotes + importFile := importLine[1 : len(importLine)-1] + + // If it's not a URL and not an absolute path, make it relative to the current file's directory + if !strings.HasPrefix(importFile, "http") && !filepath.IsAbs(importFile) { + importFile = filepath.Join(currentDir, importFile) + } + + // Get absolute path to check for circular imports + absImportPath, err := filepath.Abs(importFile) + if err != nil { + return "", fmt.Errorf("error getting absolute path: %w", err) + } + + // Skip if already imported + if importedFiles[absImportPath] { + continue + } + + // Mark as imported + importedFiles[absImportPath] = true + + // Read the imported file + importContent, err := readContractFile(importFile) + if err != nil { + return "", fmt.Errorf("error importing file '%s': %w", importFile, err) + } + + // Get the directory of the imported file for nested imports + importedFileDir := filepath.Dir(importFile) + + // Process the imported content recursively + processedImport, err := processLines(importContent, importedFileDir) + if err != nil { + return "", err + } + + // Add the processed import to output + output.WriteString(processedImport) + output.WriteString("\n") + } else { + // Regular line, add to output + output.WriteString(line) + output.WriteString("\n") + } + } + + if err := scanner.Err(); err != nil { + return "", fmt.Errorf("error scanning input: %w", err) + } + + return output.String(), nil +} + +func readContractFile(filePath string) (string, error) { + // if the file path is a url, read it from the web + if strings.HasPrefix(filePath, "http") { + // search in the web + req, err := http.NewRequest("GET", filePath, nil) + if err != nil { + return "", err + } + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return "", err + } + defer resp.Body.Close() + fileBytes, _ := ioutil.ReadAll(resp.Body) + return string(fileBytes), nil + } + + // search in the local file system + if _, err := os.Stat(filePath); os.IsNotExist(err) { + return "", err + } + fileBytes, err := ioutil.ReadFile(filePath) + if err != nil { + return "", err + } + return string(fileBytes), nil +} + +// ReadContract reads a contract file and bundles the imports +func ReadContract(filePath string) (string, error) { + // Reset imported files tracking for each new processing + importedFiles = make(map[string]bool) + + // Get the absolute path of the main file + absPath, err := filepath.Abs(filePath) + if err != nil { + return "", fmt.Errorf("error getting absolute path: %w", err) + } + + // Get the directory of the main file + mainFileDir := filepath.Dir(absPath) + + // Mark the main file as imported + importedFiles[absPath] = true + + // read the contract file + output, err := readContractFile(filePath) + if err != nil { + return "", err + } + + // process the contract file for import statements, passing the main file's directory + return processLines(output, mainFileDir) +} + +//////////////////////////////////////////////////////////////////////////////// +// Decode +//////////////////////////////////////////////////////////////////////////////// + +// Decode decodes the payload from a hex string or a base58 string or a JSON string +// and writes the bytecode, abi and deploy arguments to files +func Decode(srcFileName string, payload string) error { + var decoded []byte + var err error + + // check if the payload is in hex format + if hex.IsHexString(payload) { + // the data is expected to be copied from aergoscan view of + // the transaction that deployed the contract + decoded, err = hex.Decode(payload) + } else { + // the data is the output of aergoluac + decoded, err = encoding.DecodeCode(payload) + if err != nil { + // the data is extracted from JSON transaction from aergocli + decoded, err = base58.Decode(payload) + } + } + if err != nil { + return fmt.Errorf("failed to decode payload 1: %v", err.Error()) + } + + err = os.WriteFile(srcFileName + "-raw", decoded, 0644); + if err != nil { + return fmt.Errorf("failed to write raw file: %v", err.Error()) + } + + data := LuaCodePayload(decoded) + _, err = data.IsValidFormat() + if err != nil { + return fmt.Errorf("failed to decode payload 2: %v", err.Error()) + } + + contract := data.Code() + if !contract.IsValidFormat() { + // the data is the output of aergoluac, so it does not contain deploy arguments + contract = LuaCode(decoded) + data = NewLuaCodePayload(contract, []byte{}) + } + + err = os.WriteFile(srcFileName + "-bytecode", contract.ByteCode(), 0644); + if err != nil { + return fmt.Errorf("failed to write bytecode file: %v", err.Error()) + } + + err = os.WriteFile(srcFileName + "-abi", contract.ABI(), 0644); + if err != nil { + return fmt.Errorf("failed to write ABI file: %v", err.Error()) + } + + var deployArgs []byte + if data.HasArgs() { + deployArgs = data.Args() + } + err = os.WriteFile(srcFileName + "-deploy-arguments", deployArgs, 0644); + if err != nil { + return fmt.Errorf("failed to write deploy-arguments file: %v", err.Error()) + } + + fmt.Println("done.") + return nil +} + +func DecodeFromFile(srcFileName string) error { + payload, err := os.ReadFile(srcFileName) + if err != nil { + return fmt.Errorf("failed to read payload file: %v", err.Error()) + } + return Decode(srcFileName, string(payload)) +} + +func DecodeFromStdin() error { + fi, err := os.Stdin.Stat() + if err != nil { + return err + } + var buf []byte + if (fi.Mode() & os.ModeCharDevice) == 0 { + buf, err = ioutil.ReadAll(os.Stdin) + if err != nil { + return err + } + } else { + var bBuf bytes.Buffer + scanner := bufio.NewScanner(os.Stdin) + for scanner.Scan() { + bBuf.WriteString(scanner.Text() + "\n") + } + if err = scanner.Err(); err != nil { + return err + } + buf = bBuf.Bytes() + } + return Decode("contract", string(buf)) +} + + +//////////////////////////////////////////////////////////////////////////////// +// LuaCode and LuaCodePayload +// used to store bytecode, abi and deploy arguments +//////////////////////////////////////////////////////////////////////////////// + +type LuaCode []byte + +func NewLuaCode(byteCode, abi []byte) LuaCode { + byteCodeLen := len(byteCode) + code := make(LuaCode, 4+byteCodeLen+len(abi)) + binary.LittleEndian.PutUint32(code, uint32(byteCodeLen)) + copy(code[4:], byteCode) + copy(code[4+byteCodeLen:], abi) + return code +} + +func (c LuaCode) ByteCode() []byte { + if !c.IsValidFormat() { + return nil + } + return c[4:4+c.byteCodeLen()] +} + +func (c LuaCode) byteCodeLen() int { + if c.Len() < 4 { + return 0 + } + return int(binary.LittleEndian.Uint32(c[:4])) +} + +func (c LuaCode) ABI() []byte { + if !c.IsValidFormat() { + return nil + } + return c[4+c.byteCodeLen():] +} + +func (c LuaCode) Len() int { + return len(c) +} + +func (c LuaCode) IsValidFormat() bool { + if c.Len() <= 4 { + return false + } + return 4 + c.byteCodeLen() < c.Len() +} + +func (c LuaCode) Bytes() []byte { + return c +} + +//------------------------------------------------------------------------------ + +type LuaCodePayload []byte + +func NewLuaCodePayload(code LuaCode, args []byte) LuaCodePayload { + payload := make([]byte, 4+code.Len()+len(args)) + binary.LittleEndian.PutUint32(payload[0:], uint32(4+code.Len())) + copy(payload[4:], code.Bytes()) + copy(payload[4+code.Len():], args) + return payload +} + +func (p LuaCodePayload) headLen() int { + if p.Len() < 4 { + return 0 + } + return int(binary.LittleEndian.Uint32(p[:4])) +} + +func (p LuaCodePayload) Code() LuaCode { + if v, _ := p.IsValidFormat(); !v { + return nil + } + return LuaCode(p[4:p.headLen()]) +} + +func (p LuaCodePayload) HasArgs() bool { + if v, _ := p.IsValidFormat(); !v { + return false + } + return len(p) > p.headLen() +} + +func (p LuaCodePayload) Args() []byte { + if v, _ := p.IsValidFormat(); !v { + return nil + } + return p[p.headLen():] +} + +func (p LuaCodePayload) Len() int { + return len(p) +} + +func (p LuaCodePayload) IsValidFormat() (bool, error) { + if p.Len() <= 4 { + return false, fmt.Errorf("invalid code (%d bytes is too short)", p.Len()) + } + if p.Len() < p.headLen() { + return false, fmt.Errorf("invalid code (expected %d bytes, actual %d bytes)", p.headLen(), p.Len()) + } + return true, nil +} diff --git a/cmd/aergosvr/aergosvr.go b/cmd/aergosvr/aergosvr.go index 45ed8a3eb..3457a321b 100644 --- a/cmd/aergosvr/aergosvr.go +++ b/cmd/aergosvr/aergosvr.go @@ -6,8 +6,6 @@ package main import ( "fmt" - "os" - "github.com/aergoio/aergo-lib/log" "github.com/aergoio/aergo/v2/account" "github.com/aergoio/aergo/v2/chain" @@ -24,6 +22,7 @@ import ( "github.com/aergoio/aergo/v2/rpc/web3" "github.com/aergoio/aergo/v2/syncer" "github.com/spf13/cobra" + "os" ) var ( @@ -95,6 +94,9 @@ func initConfig() { } func rootRun(cmd *cobra.Command, args []string) { + // Set caller info to relative file path + log.SetRelativeLogPathForProject() + svrlog = log.NewLogger("asvr") svrlog.Info().Str("revision", gitRevision).Str("branch", gitBranch).Msg("AERGO SVR STARTED") diff --git a/cmd/aergosvr/init.go b/cmd/aergosvr/init.go index d9026f177..844b28162 100644 --- a/cmd/aergosvr/init.go +++ b/cmd/aergosvr/init.go @@ -3,6 +3,7 @@ package main import ( "encoding/json" "fmt" + "github.com/aergoio/aergo/v2/config" "os" "github.com/aergoio/aergo/v2/chain" @@ -72,6 +73,8 @@ var initGenesis = &cobra.Command{ g := core.GetGenesisInfo() fmt.Printf("genesis block[%s] is created in (%s)\n", base58.Encode(g.Block().GetHash()), cfg.DataDir) + + core.Close() } }, } @@ -92,7 +95,7 @@ func getGenesis(path string) *types.Genesis { } func getCore(dataDir string) *chain.Core { - // if initpath is feeded, gaurantee initpath is accessible directory + // Ensure that the provided dataDir exists and is accessible fi, err := os.Stat(dataDir) if err == nil && !fi.IsDir() { fmt.Printf("%s is not a directory\n", dataDir) @@ -111,7 +114,9 @@ func getCore(dataDir string) *chain.Core { } } - core, err := chain.NewCore(cfg.DbType, dataDir, false, 0) + dummyDbConfig := &config.DBConfig{} + + core, err := chain.NewCore(cfg.DbType, dataDir, false, 0, dummyDbConfig) if err != nil { fmt.Printf("fail to init a blockchain core (error:%s)\n", err) return nil diff --git a/cmd/brick/exec/deployContract.go b/cmd/brick/exec/deployContract.go index 0bcdcd947..4d8479ae7 100644 --- a/cmd/brick/exec/deployContract.go +++ b/cmd/brick/exec/deployContract.go @@ -7,7 +7,7 @@ import ( "strings" "github.com/aergoio/aergo/v2/cmd/brick/context" - "github.com/aergoio/aergo/v2/cmd/brick/pack" + "github.com/aergoio/aergo/v2/cmd/aergoluac/util" "github.com/aergoio/aergo/v2/contract/vm_dummy" "github.com/aergoio/aergo/v2/types" ) @@ -60,7 +60,7 @@ func (c *deployContract) parse(args string) (string, *big.Int, string, string, s } defPath := splitArgs[3].Text - if _, err := pack.ReadContract(defPath); err != nil { + if _, err := util.ReadContract(defPath); err != nil { return "", nil, "", "", "", fmt.Errorf("fail to read a contract def file %s: %s", splitArgs[3].Text, err.Error()) } @@ -82,7 +82,7 @@ func (c *deployContract) parse(args string) (string, *big.Int, string, string, s func (c *deployContract) Run(args string) (string, uint64, []*types.Event, error) { accountName, amount, contractName, defPath, constuctorArg, _ := c.parse(args) - defByte, err := pack.ReadContract(defPath) + defByte, err := util.ReadContract(defPath) if err != nil { return "", 0, nil, err } diff --git a/cmd/brick/exec/pack.go b/cmd/brick/exec/pack.go index a38d46d40..6ed793810 100644 --- a/cmd/brick/exec/pack.go +++ b/cmd/brick/exec/pack.go @@ -5,14 +5,14 @@ import ( "io/ioutil" "os" - pack "github.com/aergoio/aergo/v2/cmd/brick/pack" + "github.com/aergoio/aergo/v2/cmd/aergoluac/util" ) // ExecutePack reads a contract from inputFile and packs it, optionally writing to outputFile func ExecutePack(inputFile, outputFile string) int { // Read the contract from the input file - packedCode, err := pack.ReadContract(inputFile) + packedCode, err := util.ReadContract(inputFile) if err != nil { fmt.Fprintf(os.Stderr, "Error reading contract: %s\n", err) return 1 diff --git a/cmd/brick/pack/pack.go b/cmd/brick/pack/pack.go deleted file mode 100644 index e6436a88f..000000000 --- a/cmd/brick/pack/pack.go +++ /dev/null @@ -1,155 +0,0 @@ -package pack - -import ( - "bufio" - "fmt" - "io/ioutil" - "net/http" - "os" - "path/filepath" - "strings" -) - -// Set to track imported files -var importedFiles = make(map[string]bool) - -// ProcessLines processes a string containing contract code, handling imports -func processLines(input string, currentDir string) (string, error) { - - // Create a string builder for the output - var output strings.Builder - - // Process each line - scanner := bufio.NewScanner(strings.NewReader(input)) - for scanner.Scan() { - line := scanner.Text() - - // Check if line starts with "import " - if strings.HasPrefix(line, "import ") { - // Extract the file name from import statement - importLine := strings.TrimSpace(line[6:]) // Remove "import " prefix - - // Check if it has minimum length for a valid import - if len(importLine) < 3 { - return "", fmt.Errorf("invalid import format: %s", line) - } - - // Check if it starts with a valid quote character - quoteChar := importLine[0] - if quoteChar != '"' && quoteChar != '\'' { - return "", fmt.Errorf("import statement must use quotes: %s", line) - } - - // Check if it ends with the same quote character - if importLine[len(importLine)-1] != quoteChar { - return "", fmt.Errorf("mismatched quotes in import: %s", line) - } - - // Extract the file path between quotes - importFile := importLine[1 : len(importLine)-1] - - // If it's not a URL and not an absolute path, make it relative to the current file's directory - if !strings.HasPrefix(importFile, "http") && !filepath.IsAbs(importFile) { - importFile = filepath.Join(currentDir, importFile) - } - - // Get absolute path to check for circular imports - absImportPath, err := filepath.Abs(importFile) - if err != nil { - return "", fmt.Errorf("error getting absolute path: %w", err) - } - - // Skip if already imported - if importedFiles[absImportPath] { - continue - } - - // Mark as imported - importedFiles[absImportPath] = true - - // Read the imported file - importContent, err := readContractFile(importFile) - if err != nil { - return "", fmt.Errorf("error importing file '%s': %w", importFile, err) - } - - // Get the directory of the imported file for nested imports - importedFileDir := filepath.Dir(importFile) - - // Process the imported content recursively - processedImport, err := processLines(importContent, importedFileDir) - if err != nil { - return "", err - } - - // Add the processed import to output - output.WriteString(processedImport) - output.WriteString("\n") - } else { - // Regular line, add to output - output.WriteString(line) - output.WriteString("\n") - } - } - - if err := scanner.Err(); err != nil { - return "", fmt.Errorf("error scanning input: %w", err) - } - - return output.String(), nil -} - -func readContractFile(filePath string) (string, error) { - // if the file path is a url, read it from the web - if strings.HasPrefix(filePath, "http") { - // search in the web - req, err := http.NewRequest("GET", filePath, nil) - if err != nil { - return "", err - } - client := &http.Client{} - resp, err := client.Do(req) - if err != nil { - return "", err - } - defer resp.Body.Close() - fileBytes, _ := ioutil.ReadAll(resp.Body) - return string(fileBytes), nil - } - - // search in the local file system - if _, err := os.Stat(filePath); os.IsNotExist(err) { - return "", err - } - fileBytes, err := ioutil.ReadFile(filePath) - if err != nil { - return "", err - } - return string(fileBytes), nil -} - -func ReadContract(filePath string) (string, error) { - // Reset imported files tracking for each new processing - importedFiles = make(map[string]bool) - - // Get the absolute path of the main file - absPath, err := filepath.Abs(filePath) - if err != nil { - return "", fmt.Errorf("error getting absolute path: %w", err) - } - - // Get the directory of the main file - mainFileDir := filepath.Dir(absPath) - - // Mark the main file as imported - importedFiles[absPath] = true - - // read the contract file - output, err := readContractFile(filePath) - if err != nil { - return "", err - } - - // process the contract file for import statements, passing the main file's directory - return processLines(output, mainFileDir) -} diff --git a/config/config.go b/config/config.go index 8c23b2d0b..3bc072bd3 100644 --- a/config/config.go +++ b/config/config.go @@ -45,6 +45,7 @@ func (ctx *ServerContext) GetDefaultConfig() interface{} { Web3: ctx.GetDefaultWeb3Config(), P2P: ctx.GetDefaultP2PConfig(), Blockchain: ctx.GetDefaultBlockchainConfig(), + DB: ctx.GetDefaultDBConfig(), Mempool: ctx.GetDefaultMempoolConfig(), Consensus: ctx.GetDefaultConsensusConfig(), Monitor: ctx.GetDefaultMonitorConfig(), @@ -150,6 +151,14 @@ func (ctx *ServerContext) GetDefaultBlockchainConfig() *BlockchainConfig { } } +func (ctx *ServerContext) GetDefaultDBConfig() *DBConfig { + return &DBConfig{ + ControlCompaction: false, + StateDBPort: 7851, + ChainDBPort: 7852, + } +} + func (ctx *ServerContext) GetDefaultMempoolConfig() *MempoolConfig { return &MempoolConfig{ ShowMetrics: false, @@ -157,6 +166,7 @@ func (ctx *ServerContext) GetDefaultMempoolConfig() *MempoolConfig { FadeoutPeriod: types.DefaultEvictPeriod, VerifierNumber: runtime.NumCPU(), DumpFilePath: ctx.ExpandPathEnv("$HOME/mempool.dump"), + BlockMulticall: false, BlockDeploy: false, Blacklist: nil, } diff --git a/config/hardfork.json b/config/hardfork.json index a1ab454e9..53a83bf30 100644 --- a/config/hardfork.json +++ b/config/hardfork.json @@ -11,7 +11,12 @@ }, { "Version": 4, - "MainNetHeight": 1000000000, - "TestNetHeight": 1000000000 + "MainNetHeight": 173677571, + "TestNetHeight": 140020000 + }, + { + "Version": 5, + "MainNetHeight": 196150000, + "TestNetHeight": 155300000 } ] diff --git a/config/hardfork_gen.go b/config/hardfork_gen.go index a934ed7d2..85db9094b 100644 --- a/config/hardfork_gen.go +++ b/config/hardfork_gen.go @@ -1,4 +1,4 @@ -// Code generated by go run main.go hardfork.json hardfork_gen.go; DO NOT EDIT. +// Code generated by go run ./hardfork_gen/main.go hardfork.json hardfork_gen.go; DO NOT EDIT. package config @@ -14,16 +14,19 @@ var ( V2: types.BlockNo(19611555), V3: types.BlockNo(111499715), V4: types.BlockNo(173677571), + V5: types.BlockNo(196150000), } TestNetHardforkConfig = &HardforkConfig{ V2: types.BlockNo(18714241), V3: types.BlockNo(100360545), V4: types.BlockNo(140020000), + V5: types.BlockNo(155300000), } AllEnabledHardforkConfig = &HardforkConfig{ V2: types.BlockNo(0), V3: types.BlockNo(0), V4: types.BlockNo(0), + V5: types.BlockNo(0), } ) @@ -31,12 +34,14 @@ const hardforkConfigTmpl = `[hardfork] v2 = "{{.Hardfork.V2}}" v3 = "{{.Hardfork.V3}}" v4 = "{{.Hardfork.V4}}" +v5 = "{{.Hardfork.V5}}" ` type HardforkConfig struct { V2 types.BlockNo `mapstructure:"v2" description:"a block number of the hardfork version 2"` V3 types.BlockNo `mapstructure:"v3" description:"a block number of the hardfork version 3"` V4 types.BlockNo `mapstructure:"v4" description:"a block number of the hardfork version 4"` + V5 types.BlockNo `mapstructure:"v5" description:"a block number of the hardfork version 5"` } type HardforkDbConfig map[string]types.BlockNo @@ -52,6 +57,7 @@ func (dc HardforkDbConfig) FixDbConfig(hConfig HardforkConfig) HardforkDbConfig return dc } + func (c *HardforkConfig) IsV2Fork(h types.BlockNo) bool { return isFork(c.V2, h) } @@ -64,6 +70,10 @@ func (c *HardforkConfig) IsV4Fork(h types.BlockNo) bool { return isFork(c.V4, h) } +func (c *HardforkConfig) IsV5Fork(h types.BlockNo) bool { + return isFork(c.V5, h) +} + func (c *HardforkConfig) CheckCompatibility(dbCfg HardforkDbConfig, h types.BlockNo) error { if err := c.validate(); err != nil { return err @@ -77,7 +87,10 @@ func (c *HardforkConfig) CheckCompatibility(dbCfg HardforkDbConfig, h types.Bloc if (isFork(c.V4, h) || isFork(dbCfg["V4"], h)) && c.V4 != dbCfg["V4"] { return newForkError("V4", h, c.V4, dbCfg["V4"]) } - return checkOlderNode(4, h, dbCfg) + if (isFork(c.V5, h) || isFork(dbCfg["V5"], h)) && c.V5 != dbCfg["V5"] { + return newForkError("V5", h, c.V5, dbCfg["V5"]) + } + return checkOlderNode(5, h, dbCfg) } func (c *HardforkConfig) Version(h types.BlockNo) int32 { diff --git a/config/hardfork_gen/main.go b/config/hardfork_gen/main.go index 5f7c8e07e..b4ff23bde 100644 --- a/config/hardfork_gen/main.go +++ b/config/hardfork_gen/main.go @@ -15,7 +15,7 @@ import ( "github.com/aergoio/aergo/v2/types" ) -var tpl = `// Code generated by go run main.go {{.Input}} {{.Output}}; DO NOT EDIT. +var tpl = `// Code generated by go run ./hardfork_gen/main.go {{.Input}} {{.Output}}; DO NOT EDIT. package {{.Package}} @@ -98,7 +98,7 @@ func (c *HardforkConfig) Version(h types.BlockNo) int32 { func (c *HardforkConfig) Height(verStr string) types.BlockNo { v := reflect.ValueOf(c) - f := reflect.Indirect(v).FieldByName(verStr) + f := reflect.Indirect(v).FieldByName(verStr) return types.BlockNo(f.Uint()) } @@ -164,6 +164,9 @@ func main() { func validate(v *hardforkData) error { v.Package = os.Getenv("GOPACKAGE") + if v.Package == "" { + v.Package = "config" // Default to "config" if GOPACKAGE env var is not set + } v.MaxVersion = uint64(len(v.Hardforks) + 1) MainNetMax, TestNetMax := types.BlockNo(0), types.BlockNo(0) for i := versionStartNo; i <= v.MaxVersion; i++ { diff --git a/config/hardfork_test.go b/config/hardfork_test.go index 47ca19adb..2d2803f38 100644 --- a/config/hardfork_test.go +++ b/config/hardfork_test.go @@ -64,6 +64,7 @@ func TestConfigFromToml(t *testing.T) { v2 = "9223" v3 = "13000" v4 = "14000" +v5 = "15000" `, ) if cfg.V2 != 9223 { @@ -75,6 +76,9 @@ v4 = "14000" if cfg.V4 != 14000 { t.Errorf("V4 = %d, want %d", cfg.V4, 14000) } + if cfg.V5 != 15000 { + t.Errorf("V5 = %d, want %d", cfg.V5, 15000) + } } func TestCompatibility(t *testing.T) { @@ -83,13 +87,15 @@ func TestCompatibility(t *testing.T) { v2 = "9223" v3 = "11000" v4 = "14000" +v5 = "15000" `, ) dbCfg, _ := readDbConfig(` { - "V2": 18446744073709551415, - "V3": 18446744073709551515, - "V4": 18446744073709551615 + "V2": 18446744073709551315, + "V3": 18446744073709551415, + "V4": 18446744073709551515, + "V5": 18446744073709551615 }`, ) err := cfg.CheckCompatibility(dbCfg, 10) @@ -101,7 +107,8 @@ v4 = "14000" { "V2": 9223, "V3": 10000, - "V4": 14000 + "V4": 14000, + "V5": 15000 }`, ) err = cfg.CheckCompatibility(dbCfg, 10) @@ -113,7 +120,8 @@ v4 = "14000" { "V2": 9223, "V3": 10000, - "V4": 14000 + "V4": 14000, + "V5": 15000 }`, ) err = cfg.CheckCompatibility(dbCfg, 9500) @@ -125,7 +133,8 @@ v4 = "14000" { "V2": 9221, "V3": 10000, - "V4": 14000 + "V4": 14000, + "V5": 15000 }`, ) err = cfg.CheckCompatibility(dbCfg, 9500) @@ -136,7 +145,9 @@ v4 = "14000" dbCfg, _ = readDbConfig(` { "V2": 9223, - "V3": 10000 + "V3": 10000, + "V4": 14000, + "V5": 15000 }`, ) err = cfg.CheckCompatibility(dbCfg, 10000) @@ -160,7 +171,8 @@ v4 = "14000" "V2": 9223, "VV": 10000, "V3": 11000, - "V4": 12000 + "V4": 12000, + "V5": 15000 }`, ) err = cfg.CheckCompatibility(dbCfg, 9000) @@ -178,6 +190,7 @@ func TestVersion(t *testing.T) { v2 = "9223" v3 = "10000" v4 = "14000" +v5 = "20000" `, ) tests := []struct { @@ -232,9 +245,24 @@ v4 = "14000" }, { "greater v4", - 21001, + 14001, + 4, + }, + { + "before v5", + 19999, 4, }, + { + "equal v5", + 20000, + 5, + }, + { + "greater v5", + 21001, + 5, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -251,6 +279,7 @@ func TestFixDbConfig(t *testing.T) { v2 = "9223" v3 = "10000" v4 = "14000" +v5 = "20000" `, ) dbConfig, _ := readDbConfig(` diff --git a/config/types.go b/config/types.go index f5e6944e6..cee7a9133 100644 --- a/config/types.go +++ b/config/types.go @@ -19,6 +19,7 @@ type Config struct { P2P *P2PConfig `mapstructure:"p2p"` Polaris *PolarisConfig `mapstructure:"polaris"` Blockchain *BlockchainConfig `mapstructure:"blockchain"` + DB *DBConfig `mapstructure:"db"` Mempool *MempoolConfig `mapstructure:"mempool"` Consensus *ConsensusConfig `mapstructure:"consensus"` Monitor *MonitorConfig `mapstructure:"monitor"` @@ -53,6 +54,8 @@ type RPCConfig struct { NSKey string `mapstructure:"nskey" description:"Private Key file for RPC or REST API"` NSCACert string `mapstructure:"nscacert" description:"CA Certificate file for RPC or REST API"` NSAllowCORS bool `mapstructure:"nsallowcors" description:"Allow CORS to RPC or REST API"` + // Internal operations + LogInternalOperations bool `mapstructure:"log_internal_operations" description:"Log internal operations"` } // Web3Config defines configurations for web3 service @@ -90,6 +93,7 @@ type P2PConfig struct { InternalZones []string `mapstructure:"internalzones" description:"List of address ranges that are recognised as inner zone of agent. defined by CIDR notation."` Agent string `mapstructure:"agent" description:"Peer id of agent that delegates this producer, only available when local peer is producer"` AllowLegacy bool `mapstructure:"allowlegacy" description:"Whether to allow legacy security protocols"` + MsgBufSize int `mapstructure:"msgbufsize" description:"Size of message buffer for each peer"` } // AuthConfig defines configuration for auditing @@ -120,14 +124,22 @@ type BlockchainConfig struct { CloseLimit int `mapstructure:"closelimit" description:"number of LuaVM states which a LuaVM state closer closes at one time"` } +// DBConfig defines configurations for db modnitoring +type DBConfig struct { + ControlCompaction bool `mapstructure:"controlcompaction" description:"enable control compaction"` + StateDBPort int `mapstructure:"statedbport" description:"StateDB control port"` + ChainDBPort int `mapstructure:"chaindbport" description:"ChainDB control port"` +} + // MempoolConfig defines configurations for mempool service type MempoolConfig struct { - ShowMetrics bool `mapstructure:"showmetrics" description:"show mempool metric periodically"` - EnableFadeout bool `mapstructure:"enablefadeout" description:"Enable transaction fadeout over timeout period"` - FadeoutPeriod int `mapstructure:"fadeoutperiod" description:"time period for evict transactions(in hour)"` - VerifierNumber int `mapstructure:"verifiers" description:"number of concurrent verifier"` - DumpFilePath string `mapstructure:"dumpfilepath" description:"file path for recording mempool at process termintation"` - BlockDeploy bool `mapstructure:"blockdeploy" description:"block the deployment of new contracts"` + ShowMetrics bool `mapstructure:"showmetrics" description:"show mempool metric periodically"` + EnableFadeout bool `mapstructure:"enablefadeout" description:"Enable transaction fadeout over timeout period"` + FadeoutPeriod int `mapstructure:"fadeoutperiod" description:"time period for evict transactions(in hour)"` + VerifierNumber int `mapstructure:"verifiers" description:"number of concurrent verifier"` + DumpFilePath string `mapstructure:"dumpfilepath" description:"file path for recording mempool at process termintation"` + BlockMulticall bool `mapstructure:"blockmulticall" description:"block the multicall transaction"` + BlockDeploy bool `mapstructure:"blockdeploy" description:"block the deployment of new contracts"` Blacklist []string `mapstructure:"blacklist" description:"List of account addresses or ids to be blocked"` } @@ -206,6 +218,7 @@ nscert = "{{.RPC.NSCert}}" nskey = "{{.RPC.NSKey}}" nscacert = "{{.RPC.NSCACert}}" nsallowcors = {{.RPC.NSAllowCORS}} +log_internal_operations = {{.RPC.LogInternalOperations}} [p2p] # Set address and port to which the inbound peers connect, and don't set loopback address or private network unless used in local network @@ -254,12 +267,18 @@ numworkers = "{{.Blockchain.NumWorkers}}" numclosers = "{{.Blockchain.NumLStateClosers}}" closelimit = "{{.Blockchain.CloseLimit}}" +[db] +controlcompaction = "{{.DB.ControlCompaction}}" +statedbport = {{.DB.StateDBPort}} +chaindbport = {{.DB.ChainDBPort}} + [mempool] showmetrics = {{.Mempool.ShowMetrics}} enablefadeout = {{.Mempool.EnableFadeout}} fadeoutperiod = {{.Mempool.FadeoutPeriod}} verifiers = {{.Mempool.VerifierNumber}} dumpfilepath = "{{.Mempool.DumpFilePath}}" +blockmulticall = {{.Mempool.BlockMulticall}} blockdeploy = {{.Mempool.BlockDeploy}} blacklist = [{{range .Mempool.Blacklist}} "{{.}}", {{end}} diff --git a/consensus/impl/raftv2/blockfactory.go b/consensus/impl/raftv2/blockfactory.go index b66e8d01f..9daf5190f 100644 --- a/consensus/impl/raftv2/blockfactory.go +++ b/consensus/impl/raftv2/blockfactory.go @@ -443,7 +443,7 @@ func (bf *BlockFactory) worker() { } case cEntry, ok := <-bf.commitC(): - logger.Debug().Msg("received block to connect from raft") + logger.Trace().Msg("received block to connect from raft") if !ok { logger.Fatal().Msg("commit channel for raft is closed") @@ -770,7 +770,7 @@ func (bf *BlockFactory) getHardStateOfBlock(bestBlockHash []byte) (*types.HardSt entry, err := bf.ChainWAL.GetRaftEntryOfBlock(bestBlockHash) if err == nil { - logger.Debug().Uint64("term", entry.Term).Uint64("comit", entry.Index).Msg("get hardstate of block") + logger.Debug().Uint64("term", entry.Term).Uint64("commit", entry.Index).Msg("get hardstate of block") return &types.HardStateInfo{Term: entry.Term, Commit: entry.Index}, nil } diff --git a/consensus/impl/raftv2/p2p.go b/consensus/impl/raftv2/p2p.go index 515135c51..47c08dab0 100644 --- a/consensus/impl/raftv2/p2p.go +++ b/consensus/impl/raftv2/p2p.go @@ -19,7 +19,7 @@ var ( ErrGetClusterFail = errors.New("failed to get cluster info") ) -// GetBestBlock returns the current best block from chainservice +// GetClusterInfo collects cluster info from remote peers via p2p module func GetClusterInfo(hs *component.ComponentHub, bestHash []byte) (*Cluster, *types.HardStateInfo, error) { logger.Info().Msg("try getclusterinfo to p2p") diff --git a/consensus/impl/raftv2/raftlogger.go b/consensus/impl/raftv2/raftlogger.go index 91f21f99e..d5b1c3086 100644 --- a/consensus/impl/raftv2/raftlogger.go +++ b/consensus/impl/raftv2/raftlogger.go @@ -5,13 +5,12 @@ import ( "strings" "github.com/aergoio/aergo-lib/log" - "github.com/rs/zerolog" ) // Logger is a logging unit. It controls the flow of messages to a given // (swappable) backend. type RaftLogger struct { - logger zerolog.Logger + logger *log.Logger } func NewRaftLogger(logger *log.Logger) *RaftLogger { @@ -19,7 +18,7 @@ func NewRaftLogger(logger *log.Logger) *RaftLogger { panic("base logger of raft is nil") } - return &RaftLogger{logger: logger.With().CallerWithSkipFrameCount(3).Logger()} + return &RaftLogger{logger: logger.WithSkipFrameCount(3)} } func (l RaftLogger) Fatal(args ...interface{}) { s := fmt.Sprint(args...) diff --git a/consensus/impl/raftv2/raftserver.go b/consensus/impl/raftv2/raftserver.go index b859ee3be..84e25e492 100644 --- a/consensus/impl/raftv2/raftserver.go +++ b/consensus/impl/raftv2/raftserver.go @@ -602,7 +602,7 @@ func (rs *raftServer) stopHTTP() { } func (rs *raftServer) writeError(err error) { - logger.Error().Err(err).Msg("write err has occurend raft server. ") + logger.Error().Err(err).Msg("write err has occurred raft server. ") } // TODO timeout handling with context @@ -610,7 +610,7 @@ func (rs *raftServer) Propose(block *types.Block) error { if block == nil { return ErrProposeNilBlock } - logger.Debug().Msg("propose block") + logger.Trace().Msg("propose block") if data, err := marshalEntryData(block); err == nil { // blocks until accepted by raft state machine @@ -619,8 +619,9 @@ func (rs *raftServer) Propose(block *types.Block) error { } logger.Debug().Int("len", len(data)).Msg("proposed data to raft node") + logger.Trace().Bytes("data", data).Msg("proposed data") } else { - logger.Fatal().Err(err).Msg("poposed data is invalid") + logger.Fatal().Err(err).Msg("proposed data is invalid") } return nil @@ -1480,7 +1481,7 @@ func (rs *raftServer) GetClusterProgress() (*ClusterProgress, error) { } // GetExistingCluster returns information of existing cluster. -// It request member info to all of peers. +// It requests member info to all peers. func (rs *raftServer) GetExistingCluster() (*Cluster, *types.HardStateInfo, error) { var ( cl *Cluster diff --git a/consensus/raftCommon.go b/consensus/raftCommon.go index eefd26d5b..754eefecb 100644 --- a/consensus/raftCommon.go +++ b/consensus/raftCommon.go @@ -76,6 +76,10 @@ type RaftIdentity struct { PeerID string // base58 encoded format } +func (rid *RaftIdentity) String() string { + return rid.ToString() +} + func (rid *RaftIdentity) ToString() string { if rid == nil { return "raft identity is nil" @@ -86,6 +90,7 @@ func (rid *RaftIdentity) ToString() string { type ChainWAL interface { ChainDB + // ClearWAL removes all data used by raft ClearWAL() ResetWAL(hardStateInfo *types.HardStateInfo) error WriteRaftEntry([]*WalEntry, []*types.Block, []*raftpb.ConfChange) error diff --git a/contract/contract.go b/contract/contract.go index 0002018f4..e24bf03fe 100644 --- a/contract/contract.go +++ b/contract/contract.go @@ -47,7 +47,7 @@ func Execute( bi *types.BlockHeaderInfo, executionMode int, isFeeDelegation bool, -) (rv string, events []*types.Event, usedFee *big.Int, err error) { +) (rv string, events []*types.Event, internalOps string, usedFee *big.Int, err error) { var ( txBody = tx.GetBody() @@ -106,9 +106,9 @@ func Execute( // execute the transaction if receiver.IsDeploy() { - rv, events, ctrFee, err = Create(contractState, txPayload, receiver.ID(), ctx) + rv, events, internalOps, ctrFee, err = Create(contractState, txPayload, receiver.ID(), ctx) } else { - rv, events, ctrFee, err = Call(contractState, txPayload, receiver.ID(), ctx) + rv, events, internalOps, ctrFee, err = Call(contractState, txPayload, receiver.ID(), ctx) } // close the trace file @@ -118,7 +118,7 @@ func Execute( // check if the execution fee is negative if ctrFee != nil && ctrFee.Sign() < 0 { - return "", events, usedFee, ErrVmStart + return "", events, internalOps, usedFee, ErrVmStart } // add the execution fee to the total fee usedFee.Add(usedFee, ctrFee) @@ -126,19 +126,19 @@ func Execute( // check if the execution failed if err != nil { if isSystemError(err) { - return "", events, usedFee, err + return "", events, internalOps, usedFee, err } - return "", events, usedFee, newVmError(err) + return "", events, internalOps, usedFee, newVmError(err) } // check for sufficient balance for fee if isFeeDelegation { if receiver.Balance().Cmp(usedFee) < 0 { - return "", events, usedFee, newVmError(types.ErrInsufficientBalance) + return "", events, internalOps, usedFee, newVmError(types.ErrInsufficientBalance) } } else { if sender.Balance().Cmp(usedFee) < 0 { - return "", events, usedFee, newVmError(types.ErrInsufficientBalance) + return "", events, internalOps, usedFee, newVmError(types.ErrInsufficientBalance) } } @@ -146,12 +146,12 @@ func Execute( // save the contract state err = statedb.StageContractState(contractState, bs.StateDB) if err != nil { - return "", events, usedFee, err + return "", events, internalOps, usedFee, err } } // return the result - return rv, events, usedFee, nil + return rv, events, internalOps, usedFee, nil } // check if the tx is valid and if the code should be executed diff --git a/contract/enterprise/config_test.go b/contract/enterprise/config_test.go index f5d8c2253..b5721af94 100644 --- a/contract/enterprise/config_test.go +++ b/contract/enterprise/config_test.go @@ -16,7 +16,7 @@ var sdb *statedb.StateDB func initTest(t *testing.T) (*statedb.ContractState, *state.AccountState, *state.AccountState) { cdb = state.NewChainStateDB() - cdb.Init(string(db.BadgerImpl), "test", nil, false) + cdb.Init(string(db.BadgerImpl), "test", nil, false, nil) genesis := types.GetTestGenesis() sdb = cdb.OpenNewStateDB(cdb.GetRoot()) err := cdb.SetGenesis(genesis, nil) diff --git a/contract/internal_operations.go b/contract/internal_operations.go new file mode 100644 index 000000000..d05bc5fc6 --- /dev/null +++ b/contract/internal_operations.go @@ -0,0 +1,212 @@ +package contract + +import ( + "encoding/json" + "sync" + + "github.com/aergoio/aergo/v2/internal/enc/base58" +) + +type InternalOperation struct { + Id int64 `json:"-"` + Operation string `json:"op"` + Amount string `json:"amount,omitempty"` + Args []string `json:"args"` + Result string `json:"result,omitempty"` + Call *InternalCall `json:"call,omitempty"` + Reverted bool `json:"reverted,omitempty"` +} + +type InternalCall struct { + Contract string `json:"contract,omitempty"` + Function string `json:"function,omitempty"` + Args []interface{} `json:"args,omitempty"` + Amount string `json:"amount,omitempty"` + Operations []InternalOperation `json:"operations,omitempty"` +} + +type InternalOperations struct { + TxHash string `json:"txhash"` + Call InternalCall `json:"call"` +} + +var ( + opsLock sync.Mutex + nextOpId int64 +) + +func doNotLog(ctx *vmContext) bool { + if logInternalOperations == false { + return true + } + return ctx.isQuery +} + +func getCurrentCall(ctx *vmContext, callDepth int32) *InternalCall { + var depth int32 = 1 + opCall := &ctx.internalOpsCall + for { + if opCall == nil { + ctrLgr.Printf("no call found at depth %d", depth) + break + } + if depth == callDepth { + return opCall + } + if len(opCall.Operations) == 0 { + ctrLgr.Printf("no operations found at depth %d", depth) + break + } + opCall = opCall.Operations[len(opCall.Operations)-1].Call + depth++ + } + return nil +} + +func logOperation(ctx *vmContext, amount string, operation string, args ...string) int64 { + if doNotLog(ctx) { + return 0 + } + + ctrLgr.Printf("logOperation: depth: %d, amount: %s, operation: %s, args: %v", ctx.callDepth, amount, operation, args) + + opsLock.Lock() + defer opsLock.Unlock() + + nextOpId++ + if nextOpId > 1000000000000000000 { + nextOpId = 1 + } + + op := InternalOperation{ + Id: nextOpId, + Operation: operation, + Amount: amount, + Args: args, + } + + opCall := getCurrentCall(ctx, ctx.callDepth) + if opCall == nil { + ctrLgr.Printf("no call found") + return 0 + } + // add the operation to the list + opCall.Operations = append(opCall.Operations, op) + + return op.Id +} + +func logOperationResult(ctx *vmContext, operationId int64, result string) { + if doNotLog(ctx) { + return + } + + ctrLgr.Printf("logOperationResult: depth: %d, operationId: %d, result: %s", ctx.callDepth, operationId, result) + + opsLock.Lock() + defer opsLock.Unlock() + + // try with the last and the previous call depth + for callDepth := ctx.callDepth; callDepth >= ctx.callDepth - 1; callDepth-- { + opCall := getCurrentCall(ctx, callDepth) + if opCall == nil { + continue + } + for i := range opCall.Operations { + if opCall.Operations[i].Id == operationId { + opCall.Operations[i].Result = result + return + } + } + } + + ctrLgr.Printf("no operation found with ID %d to store result", operationId) +} + +func markOperationsAsReverted(opCall *InternalCall, startOp int) { + for i := startOp; i < len(opCall.Operations); i++ { + opCall.Operations[i].Reverted = true + } +} + +func logInternalCall(ctx *vmContext, contract string, function string, args []interface{}, amount string) error { + if doNotLog(ctx) { + return nil + } + + ctrLgr.Printf("logInternalCall: depth: %d, contract: %s, function: %s, args: %s, amount: %s", ctx.callDepth, contract, function, argsToJson(args), amount) + + opCall := getCurrentCall(ctx, ctx.callDepth-1) + if opCall == nil { + ctrLgr.Printf("no call found") + return nil + } + + // get the last operation + op := &opCall.Operations[len(opCall.Operations)-1] + + // add this call to the last operation + op.Call = &InternalCall{ + Contract: contract, + Function: function, + Args: args, + Amount: amount, + } + + return nil +} + +func logFirstCall(ctx *vmContext, contract string, function string, args []interface{}, amount string) { + ctrLgr.Printf("logFirstCall: depth: %d, contract: %s, function: %s, args: %s, amount: %s", ctx.callDepth, contract, function, argsToJson(args), amount) + ctx.internalOpsCall.Contract = contract + ctx.internalOpsCall.Function = function + ctx.internalOpsCall.Args = args + ctx.internalOpsCall.Amount = amount +} + +func logCall(ctx *vmContext, contract string, function string, args []interface{}, amount string) { + if amount == "0" { + amount = "" + } + if ctx.internalOpsCall.Contract == "" { + logFirstCall(ctx, contract, function, args, amount) + } else { + logInternalCall(ctx, contract, function, args, amount) + } +} + +func argsToJson(argsList []interface{}) (string) { + if argsList == nil { + return "" + } + args, err := json.Marshal(argsList) + if err != nil { + return "" + } + return string(args) +} + +func getInternalOperations(ctx *vmContext) string { + if doNotLog(ctx) { + return "" + } + if ctx.internalOpsCall.Contract == "" { + return "" + } + + opsLock.Lock() + defer opsLock.Unlock() + + internalOps := InternalOperations{ + TxHash: base58.Encode(ctx.txHash), + Call: ctx.internalOpsCall, + } + + data, err := json.Marshal(internalOps) + if err != nil { + ctrLgr.Fatal().Err(err).Msg("Failed to marshal operations") + return "" + } + + return string(data) +} diff --git a/contract/name/name_test.go b/contract/name/name_test.go index 49cd93353..8c59bc0a9 100644 --- a/contract/name/name_test.go +++ b/contract/name/name_test.go @@ -19,7 +19,7 @@ var block *types.Block func initTest(t *testing.T) { genesis := types.GetTestGenesis() sdb = state.NewChainStateDB() - sdb.Init(string(db.BadgerImpl), "test", genesis.Block(), false) + sdb.Init(string(db.BadgerImpl), "test", genesis.Block(), false, nil) err := sdb.SetGenesis(genesis, nil) if err != nil { t.Fatalf("failed init : %s", err.Error()) diff --git a/contract/system/vote_test.go b/contract/system/vote_test.go index 7596a95af..a4f0c75ab 100644 --- a/contract/system/vote_test.go +++ b/contract/system/vote_test.go @@ -27,7 +27,7 @@ var bs *state.BlockState func initTest(t *testing.T) (*statedb.ContractState, *state.AccountState, *state.AccountState) { cdb = state.NewChainStateDB() - cdb.Init(string(db.BadgerImpl), "test", nil, false) + cdb.Init(string(db.BadgerImpl), "test", nil, false, nil) genesis := types.GetTestGenesis() err := cdb.SetGenesis(genesis, nil) diff --git a/contract/system/vprt_test.go b/contract/system/vprt_test.go index 107ad5ee0..09460d72c 100644 --- a/contract/system/vprt_test.go +++ b/contract/system/vprt_test.go @@ -136,7 +136,7 @@ func initVprtTestWithSc(t *testing.T, initTable func(*statedb.ContractState)) { func initDB(t *testing.T) { vprChainStateDB = state.NewChainStateDB() - _ = vprChainStateDB.Init(string(db.BadgerImpl), "test", nil, false) + _ = vprChainStateDB.Init(string(db.BadgerImpl), "test", nil, false, nil) vprStateDB = vprChainStateDB.GetStateDB() genesis := types.GetTestGenesis() diff --git a/contract/vm.c b/contract/vm.c index bbdc1aa9b..88b59e7ec 100644 --- a/contract/vm.c +++ b/contract/vm.c @@ -57,6 +57,7 @@ static void preloadModules(lua_State *L) { luaopen_db(L); } +#ifndef DEBUG if (vm_is_hardfork(L, 4)) { lua_getglobal(L, "_G"); // disable getmetatable @@ -81,6 +82,7 @@ static void preloadModules(lua_State *L) { lua_setfield(L, -2, "dump"); lua_pop(L, 1); } +#endif #ifdef MEASURE lua_register(L, "nsec", nsec); @@ -415,9 +417,29 @@ void vm_set_timeout_count_hook(lua_State *L, int limit) { lua_sethook(L, timeout_count_hook, LUA_MASKCOUNT, VM_TIMEOUT_INST_COUNT); } +static int stacktrace(lua_State *L) { + if (!lua_isstring(L, 1)) /* 'message' not a string? */ + return 1; /* keep it intact */ + lua_getfield(L, LUA_GLOBALSINDEX, "debug"); + if (!lua_istable(L, -1)) { + lua_pop(L, 1); + return 1; + } + lua_getfield(L, -1, "traceback"); + if (!lua_isfunction(L, -1)) { + lua_pop(L, 2); + return 1; + } + lua_pushvalue(L, 1); /* pass error message */ + lua_pushinteger(L, 2); /* skip this function and traceback */ + lua_call(L, 2, 1); /* call debug.traceback */ + return 1; +} + const char *vm_pcall(lua_State *L, int argc, int *nresult) { int err; - int nr = lua_gettop(L) - argc - 1; + int base = lua_gettop(L) - argc; // position of function in the stack + int error_handler = 0; if (lua_usegas(L)) { lua_enablegas(L); @@ -425,7 +447,21 @@ const char *vm_pcall(lua_State *L, int argc, int *nresult) { luaL_enablemaxmem(L); } - err = lua_pcall(L, argc, LUA_MULTRET, 0); +#ifdef DEBUG + // push the error handler before the function and arguments + lua_pushcfunction(L, stacktrace); + // insert the error handler at the position of the function + lua_insert(L, base); + // now the stack is: [other stuff] [stacktrace] [function] [args...] + error_handler = base; +#endif + + err = lua_pcall(L, argc, LUA_MULTRET, error_handler); + +#ifdef DEBUG + // remove the stacktrace function + lua_remove(L, error_handler); +#endif if (lua_usegas(L)) { lua_disablegas(L); @@ -441,7 +477,8 @@ const char *vm_pcall(lua_State *L, int argc, int *nresult) { if (err != 0) { return lua_tostring(L, -1); } - *nresult = lua_gettop(L) - nr; + + *nresult = lua_gettop(L) - base + 1; return NULL; } diff --git a/contract/vm.go b/contract/vm.go index 8fdb5e1ae..a19a8cf16 100644 --- a/contract/vm.go +++ b/contract/vm.go @@ -36,7 +36,8 @@ import ( "unsafe" "github.com/aergoio/aergo-lib/log" - luacUtil "github.com/aergoio/aergo/v2/cmd/aergoluac/util" + "github.com/aergoio/aergo/v2/cmd/aergoluac/luac" + "github.com/aergoio/aergo/v2/cmd/aergoluac/util" "github.com/aergoio/aergo/v2/fee" "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/internal/enc/hex" @@ -67,6 +68,7 @@ var ( lastQueryIndex int querySync sync.Mutex currentForkVersion int32 + logInternalOperations bool ) type ChainAccessor interface { @@ -92,7 +94,7 @@ type vmContext struct { isMultiCall bool service C.int callState map[types.AccountID]*callState - lastRecoveryEntry *recoveryEntry + lastRecoveryPoint *recoveryPoint dbUpdateTotalSize int64 seed *rand.Rand events []*types.Event @@ -102,6 +104,7 @@ type vmContext struct { gasLimit uint64 remainedGas uint64 execCtx context.Context + internalOpsCall InternalCall } type executor struct { @@ -111,6 +114,7 @@ type executor struct { numArgs C.int ci *types.CallInfo fname string + amount *big.Int ctx *vmContext jsonRet string isView bool @@ -130,9 +134,10 @@ func init() { lastQueryIndex = ChainService } -func InitContext(numCtx int) { +func InitContext(numCtx int, logInternalOps bool) { maxContext = numCtx contexts = make([]*vmContext, maxContext) + logInternalOperations = logInternalOps } func NewVmContext( @@ -282,6 +287,10 @@ func resolveFunction(contractState *statedb.ContractState, bs *state.BlockState, if len(name) == 0 && defaultFunc != nil { return defaultFunc, nil } + // the function was not found + if currentForkVersion >= 5 && len(name) == 0 { + return nil, errors.New("the contract does not have a payable default function") + } return nil, errors.New("not found function: " + name) } @@ -404,6 +413,7 @@ func newExecutor( ce.numArgs = C.int(len(ci.Args) + 1) } ce.ci = ci + ce.amount = amount return ce } @@ -522,11 +532,11 @@ func toLuaTable(L *LState, tab map[string]interface{}) error { return nil } -func checkPayable(callee *types.Function, amount *big.Int) error { - if amount.Cmp(big.NewInt(0)) <= 0 || callee.Payable { - return nil +func checkPayable(function *types.Function, amount *big.Int) error { + if amount.Sign() > 0 && !function.Payable { + return fmt.Errorf("'%s' is not payable", function.Name) } - return fmt.Errorf("'%s' is not payable", callee.Name) + return nil } func (ce *executor) call(instLimit C.int, target *LState) (ret C.int) { @@ -558,11 +568,11 @@ func (ce *executor) call(instLimit C.int, target *LState) (ret C.int) { ce.err = ce.preErr return 0 } + contract := types.EncodeAddress(ce.ctx.curContract.contractId) if ce.isAutoload { if loaded := vmAutoload(ce.L, ce.fname); !loaded { if ce.fname != constructor { - ce.err = errors.New(fmt.Sprintf("contract autoload failed %s : %s", - types.EncodeAddress(ce.ctx.curContract.contractId), ce.fname)) + ce.err = errors.New(fmt.Sprintf("contract autoload failed %s : %s", contract, ce.fname)) } return 0 } @@ -574,10 +584,10 @@ func (ce *executor) call(instLimit C.int, target *LState) (ret C.int) { } ce.processArgs() if ce.err != nil { - ctrLgr.Debug().Err(ce.err).Stringer("contract", - types.LogAddr(ce.ctx.curContract.contractId)).Msg("invalid argument") + ctrLgr.Debug().Err(ce.err).Str("contract", contract).Msg("invalid argument") return 0 } + logCall(ce.ctx, contract, ce.fname, ce.ci.Args, ce.amount.String()) ce.setCountHook(instLimit) nRet := C.int(0) cErrMsg := C.vm_pcall(ce.L, ce.numArgs, &nRet) @@ -593,10 +603,7 @@ func (ce *executor) call(instLimit C.int, target *LState) (ret C.int) { ce.err = errors.New(errMsg) } } - ctrLgr.Debug().Err(ce.err).Stringer( - "contract", - types.LogAddr(ce.ctx.curContract.contractId), - ).Msg("contract is failed") + ctrLgr.Debug().Err(ce.err).Str("contract", contract).Msg("contract is failed") return 0 } if target == nil { @@ -611,15 +618,11 @@ func (ce *executor) call(instLimit C.int, target *LState) (ret C.int) { if c2ErrMsg := C.vm_copy_result(ce.L, target, nRet); c2ErrMsg != nil { errMsg := C.GoString(c2ErrMsg) ce.err = errors.New(errMsg) - ctrLgr.Debug().Err(ce.err).Stringer( - "contract", - types.LogAddr(ce.ctx.curContract.contractId), - ).Msg("failed to move results") + ctrLgr.Debug().Err(ce.err).Str("contract", contract).Msg("failed to move results") } } if ce.ctx.traceFile != nil { - address := types.EncodeAddress(ce.ctx.curContract.contractId) - codeFile := fmt.Sprintf("%s%s%s.code", os.TempDir(), string(os.PathSeparator), address) + codeFile := fmt.Sprintf("%s%s%s.code", os.TempDir(), string(os.PathSeparator), contract) if _, err := os.Stat(codeFile); os.IsNotExist(err) { f, err := os.OpenFile(codeFile, os.O_WRONLY|os.O_CREATE, 0644) if err == nil { @@ -628,7 +631,7 @@ func (ce *executor) call(instLimit C.int, target *LState) (ret C.int) { } } _, _ = ce.ctx.traceFile.WriteString(fmt.Sprintf("contract %s used fee: %s\n", - address, ce.ctx.usedFee().String())) + contract, ce.ctx.usedFee().String())) } return nRet } @@ -825,7 +828,7 @@ func Call( contractState *statedb.ContractState, payload, contractAddress []byte, ctx *vmContext, -) (string, []*types.Event, *big.Int, error) { +) (string, []*types.Event, string, *big.Int, error) { var err error var ci types.CallInfo @@ -850,7 +853,7 @@ func Call( err = fmt.Errorf("not found contract %s", addr) } if err != nil { - return "", nil, ctx.usedFee(), err + return "", nil, "", ctx.usedFee(), err } if ctrLgr.IsDebugEnabled() { @@ -870,6 +873,8 @@ func Call( vmLogger.Trace().Int64("execµs", vmExecTime).Stringer("txHash", types.LogBase58(ce.ctx.txHash)).Msg("tx execute time in vm") } + internalOps := getInternalOperations(ctx) + // check if there is an error err = ce.err if err != nil { @@ -894,14 +899,14 @@ func Call( types.EncodeAddress(contractAddress), types.ToAccountID(contractAddress))) } // return the error - return "", ce.getEvents(), ctx.usedFee(), err + return "", ce.getEvents(), internalOps, ctx.usedFee(), err } // save the state of the contract err = ce.commitCalledContract() if err != nil { ctrLgr.Error().Err(err).Str("contract", types.EncodeAddress(contractAddress)).Msg("commit state") - return "", ce.getEvents(), ctx.usedFee(), err + return "", ce.getEvents(), internalOps, ctx.usedFee(), err } // log the result @@ -922,7 +927,7 @@ func Call( } // return the result - return ce.jsonRet, ce.getEvents(), ctx.usedFee(), nil + return ce.jsonRet, ce.getEvents(), internalOps, ctx.usedFee(), nil } func setRandomSeed(ctx *vmContext) { @@ -942,7 +947,7 @@ func setContract(contractState *statedb.ContractState, contractAddress, payload // the payload contains: // on V3: bytecode + ABI + constructor arguments // on V4: lua code + constructor arguments - codePayload := luacUtil.LuaCodePayload(payload) + codePayload := util.LuaCodePayload(payload) if _, err := codePayload.IsValidFormat(); err != nil { ctrLgr.Warn().Err(err).Str("contract", types.EncodeAddress(contractAddress)).Msg("deploy") return nil, nil, err @@ -979,7 +984,7 @@ func setContract(contractState *statedb.ContractState, contractAddress, payload } // extract the bytecode - bytecode := luacUtil.LuaCode(bytecodeABI).ByteCode() + bytecode := util.LuaCode(bytecodeABI).ByteCode() // check if it was properly stored savedBytecode := getContractCode(contractState, nil) @@ -999,10 +1004,10 @@ func Create( contractState *statedb.ContractState, payload, contractAddress []byte, ctx *vmContext, -) (string, []*types.Event, *big.Int, error) { +) (string, []*types.Event, string, *big.Int, error) { if len(payload) == 0 { - return "", nil, ctx.usedFee(), errors.New("contract code is required") + return "", nil, "", ctx.usedFee(), errors.New("contract code is required") } if ctrLgr.IsDebugEnabled() { @@ -1012,13 +1017,13 @@ func Create( // save the contract code bytecode, args, err := setContract(contractState, contractAddress, payload, ctx) if err != nil { - return "", nil, ctx.usedFee(), err + return "", nil, "", ctx.usedFee(), err } // set the creator err = contractState.SetData(dbkey.CreatorMeta(), []byte(types.EncodeAddress(ctx.curContract.sender))) if err != nil { - return "", nil, ctx.usedFee(), err + return "", nil, "", ctx.usedFee(), err } // get the arguments for the constructor @@ -1027,7 +1032,7 @@ func Create( err = getCallInfo(&ci.Args, args, contractAddress) if err != nil { errMsg, _ := json.Marshal("constructor call error:" + err.Error()) - return string(errMsg), nil, ctx.usedFee(), nil + return string(errMsg), nil, "", ctx.usedFee(), nil } } @@ -1036,7 +1041,7 @@ func Create( if ctx.blockInfo.ForkVersion < 2 { // create a sql database for the contract if db := luaGetDbHandle(ctx.service); db == nil { - return "", nil, ctx.usedFee(), newVmError(errors.New("can't open a database connection")) + return "", nil, "", ctx.usedFee(), newVmError(errors.New("can't open a database connection")) } } @@ -1044,11 +1049,13 @@ func Create( ce := newExecutor(bytecode, contractAddress, ctx, &ci, ctx.curContract.amount, true, false, contractState) defer ce.close() - if err == nil { + if ce.err == nil { // call the constructor ce.call(callMaxInstLimit, nil) } + internalOps := getInternalOperations(ctx) + // check if the call failed err = ce.err if err != nil { @@ -1074,7 +1081,7 @@ func Create( types.EncodeAddress(contractAddress), types.ToAccountID(contractAddress))) } // return the error - return "", ce.getEvents(), ctx.usedFee(), err + return "", ce.getEvents(), internalOps, ctx.usedFee(), err } // commit the state @@ -1082,7 +1089,7 @@ func Create( if err != nil { ctrLgr.Debug().Msg("constructor is failed") ctrLgr.Error().Err(err).Msg("commit state") - return "", ce.getEvents(), ctx.usedFee(), err + return "", ce.getEvents(), internalOps, ctx.usedFee(), err } // write the trace @@ -1103,7 +1110,7 @@ func Create( } // return the result - return ce.jsonRet, ce.getEvents(), ctx.usedFee(), nil + return ce.jsonRet, ce.getEvents(), internalOps, ctx.usedFee(), nil } func allocContextSlot(ctx *vmContext) { @@ -1298,7 +1305,7 @@ func getContractCode(contractState *statedb.ContractState, bs *state.BlockState) if err != nil { return nil } - return luacUtil.LuaCode(code).ByteCode() + return util.LuaCode(code).ByteCode() } func getMultiCallContractCode(contractState *statedb.ContractState) []byte { @@ -1306,7 +1313,7 @@ func getMultiCallContractCode(contractState *statedb.ContractState) []byte { if code == nil { return nil } - return luacUtil.LuaCode(code).ByteCode() + return util.LuaCode(code).ByteCode() } func getMultiCallCode(contractState *statedb.ContractState) []byte { @@ -1340,7 +1347,7 @@ func GetABI(contractState *statedb.ContractState, bs *state.BlockState) (*types. if err != nil { return nil, err } - luaCode := luacUtil.LuaCode(code) + luaCode := util.LuaCode(code) if luaCode.Len() == 0 { return nil, errors.New("cannot find contract") } @@ -1362,12 +1369,12 @@ func GetABI(contractState *statedb.ContractState, bs *state.BlockState) (*types. return abi, nil } -func Compile(code string, parent *LState) (luacUtil.LuaCode, error) { - L := luacUtil.NewLState() +func Compile(code string, parent *LState) (util.LuaCode, error) { + L := luac.NewLState() if L == nil { return nil, ErrVmStart } - defer luacUtil.CloseLState(L) + defer luac.CloseLState(L) if parent != nil { var lState = (*LState)(L) if cErrMsg := C.vm_copy_service(lState, parent); cErrMsg != nil { @@ -1380,7 +1387,7 @@ func Compile(code string, parent *LState) (luacUtil.LuaCode, error) { C.luaL_set_hardforkversion(lState, C.luaL_hardforkversion(parent)) C.vm_set_timeout_hook(lState) } - byteCodeAbi, err := luacUtil.Compile(L, code) + byteCodeAbi, err := luac.Compile(L, code) if err != nil { if parent != nil && C.luaL_hasuncatchablerror((*LState)(L)) != C.int(0) { C.luaL_setuncatchablerror(parent) diff --git a/contract/vm_callback.go b/contract/vm_callback.go index f6e8d9726..5bb544454 100644 --- a/contract/vm_callback.go +++ b/contract/vm_callback.go @@ -86,20 +86,29 @@ func luaSetDB(L *LState, service C.int, key unsafe.Pointer, keyLen C.int, value if ctx.isQuery == true || ctx.nestedView > 0 { return C.CString("[System.LuaSetDB] set not permitted in query") } - val := []byte(C.GoString(value)) - if err := ctx.curContract.callState.ctrState.SetData(C.GoBytes(key, keyLen), val); err != nil { + + keyBytes := C.GoBytes(key, keyLen) + keyStr := string(keyBytes) + valueStr := C.GoString(value) + valueBytes := []byte(valueStr) + + // log the operation with the modified key + logOperation(ctx, "", "set_variable", convertKey(keyStr), valueStr) + + // set the state variable + if err := ctx.curContract.callState.ctrState.SetData(keyBytes, valueBytes); err != nil { return C.CString(err.Error()) } - if err := ctx.addUpdateSize(int64(types.HashIDLength + len(val))); err != nil { + if err := ctx.addUpdateSize(int64(types.HashIDLength + len(valueBytes))); err != nil { C.luaL_setuncatchablerror(L) return C.CString(err.Error()) } if ctx.traceFile != nil { _, _ = ctx.traceFile.WriteString("[Set]\n") _, _ = ctx.traceFile.WriteString(fmt.Sprintf("Key=%s Len=%v byte=%v\n", - string(C.GoBytes(key, keyLen)), keyLen, C.GoBytes(key, keyLen))) + string(keyBytes), keyLen, keyBytes)) _, _ = ctx.traceFile.WriteString(fmt.Sprintf("Data=%s Len=%d byte=%v\n", - string(val), len(val), val)) + string(valueBytes), len(valueBytes), valueBytes)) } return nil } @@ -170,7 +179,15 @@ func luaDelDB(L *LState, service C.int, key unsafe.Pointer, keyLen C.int) *C.cha if ctx.isQuery == true || ctx.nestedView > 0 { return C.CString("[System.LuaDelDB] delete not permitted in query") } - if err := ctx.curContract.callState.ctrState.DeleteData(C.GoBytes(key, keyLen)); err != nil { + + keyBytes := C.GoBytes(key, keyLen) + keyStr := string(keyBytes) + + // log the operation with the modified key + logOperation(ctx, "", "del_variable", convertKey(keyStr)) + + // delete the state variable + if err := ctx.curContract.callState.ctrState.DeleteData(keyBytes); err != nil { return C.CString(err.Error()) } if err := ctx.addUpdateSize(int64(32)); err != nil { @@ -180,11 +197,34 @@ func luaDelDB(L *LState, service C.int, key unsafe.Pointer, keyLen C.int) *C.cha if ctx.traceFile != nil { _, _ = ctx.traceFile.WriteString("[Del]\n") _, _ = ctx.traceFile.WriteString(fmt.Sprintf("Key=%s Len=%v byte=%v\n", - string(C.GoBytes(key, keyLen)), keyLen, C.GoBytes(key, keyLen))) + string(keyBytes), keyLen, keyBytes)) } return nil } +func convertKey(keyStr string) string { + // if the key starts with "_sv_meta-len_", remove it and add the ".length" suffix to the key + if strings.HasPrefix(keyStr, "_sv_meta-len_") { + keyStr = keyStr[len("_sv_meta-len_"):] + keyStr = keyStr + ".length" + // if the key starts with "_sv_meta-type_", remove it and add the ".type" suffix to the key + } else if strings.HasPrefix(keyStr, "_sv_meta-type_") { + keyStr = keyStr[len("_sv_meta-type_"):] + keyStr = keyStr + ".type" + // if the key starts with "_sv_", remove it + } else if strings.HasPrefix(keyStr, "_sv_") { + keyStr = keyStr[len("_sv_"):] + // if there is a "-" in the key, get its position, replace it with a `[` and add a `]` to the end + if idx := strings.Index(keyStr, "-"); idx != -1 { + keyStr = keyStr[:idx] + "[" + keyStr[idx+1:] + "]" + } + // if the key starts with "_", remove it + } else if strings.HasPrefix(keyStr, "_") { + keyStr = keyStr[len("_"):] + } + return keyStr +} + func setInstCount(ctx *vmContext, parent *LState, child *LState) { if !ctx.IsGasSystem() { C.vm_setinstcount(parent, C.vm_instcount(child)) @@ -210,25 +250,34 @@ func minusCallCount(ctx *vmContext, curCount, deduc C.int) C.int { //export luaCallContract func luaCallContract(L *LState, service C.int, contractId *C.char, fname *C.char, args *C.char, - amount *C.char, gas uint64) (C.int, *C.char) { + amount *C.char, gas uint64) (ret C.int, errormsg *C.char) { + contractAddress := C.GoString(contractId) fnameStr := C.GoString(fname) argsStr := C.GoString(args) + amountStr := C.GoString(amount) ctx := contexts[service] if ctx == nil { return -1, C.CString("[Contract.LuaCallContract] contract state not found") } + opId := logOperation(ctx, amountStr, "call", contractAddress, fnameStr, argsStr) + defer func() { + if errormsg != nil { + logOperationResult(ctx, opId, C.GoString(errormsg)) + } + }() + // get the contract address - contractAddress := C.GoString(contractId) cid, err := getAddressNameResolved(contractAddress, ctx.bs) if err != nil { return -1, C.CString("[Contract.LuaCallContract] invalid contractId: " + err.Error()) } aid := types.ToAccountID(cid) + contractAddress = types.EncodeAddress(cid) // read the amount for the contract call - amountBig, err := transformAmount(C.GoString(amount), ctx.blockInfo.ForkVersion) + amountBig, err := transformAmount(amountStr, ctx.blockInfo.ForkVersion) if err != nil { return -1, C.CString("[Contract.LuaCallContract] invalid amount: " + err.Error()) } @@ -242,7 +291,7 @@ func luaCallContract(L *LState, service C.int, contractId *C.char, fname *C.char // check if the contract exists bytecode := getContractCode(cs.ctrState, ctx.bs) if bytecode == nil { - return -1, C.CString("[Contract.LuaCallContract] cannot find contract " + C.GoString(contractId)) + return -1, C.CString("[Contract.LuaCallContract] cannot find contract " + contractAddress) } prevContractInfo := ctx.curContract @@ -260,6 +309,10 @@ func luaCallContract(L *LState, service C.int, contractId *C.char, fname *C.char // create a new executor with the remaining gas on the child LState ce := newExecutor(bytecode, cid, ctx, &ci, amountBig, false, false, cs.ctrState) defer func() { + // save the result if the call was successful + if ce.preErr == nil && ce.err == nil { + logOperationResult(ctx, opId, ce.jsonRet) + } // close the executor, closes also the child LState ce.close() // set the remaining gas on the parent LState @@ -282,7 +335,7 @@ func luaCallContract(L *LState, service C.int, contractId *C.char, fname *C.char } } - seq, err := setRecoveryPoint(aid, ctx, senderState, cs, amountBig, false, false) + seq, err := createRecoveryPoint(aid, ctx, senderState, cs, amountBig, false, false) if ctx.traceFile != nil { _, _ = ctx.traceFile.WriteString(fmt.Sprintf("[CALL Contract %v(%v) %v]\n", contractAddress, aid.String(), fnameStr)) @@ -304,11 +357,11 @@ func luaCallContract(L *LState, service C.int, contractId *C.char, fname *C.char // execute the contract call defer setInstCount(ctx, L, ce.L) - ret := ce.call(minusCallCount(ctx, C.vm_instcount(L), luaCallCountDeduc), L) + ret = ce.call(minusCallCount(ctx, C.vm_instcount(L), luaCallCountDeduc), L) // check if the contract call failed if ce.err != nil { - err := clearRecovery(L, ctx, seq, true) + err := clearRecoveryPoint(L, ctx, seq, true) if err != nil { return -1, C.CString("[Contract.LuaCallContract] recovery err: " + err.Error()) } @@ -325,7 +378,7 @@ func luaCallContract(L *LState, service C.int, contractId *C.char, fname *C.char } if seq == 1 { - err := clearRecovery(L, ctx, seq, false) + err := clearRecoveryPoint(L, ctx, seq, false) if err != nil { return -1, C.CString("[Contract.LuaCallContract] recovery err: " + err.Error()) } @@ -336,7 +389,7 @@ func luaCallContract(L *LState, service C.int, contractId *C.char, fname *C.char //export luaDelegateCallContract func luaDelegateCallContract(L *LState, service C.int, contractId *C.char, - fname *C.char, args *C.char, gas uint64) (C.int, *C.char) { + fname *C.char, args *C.char, gas uint64) (ret C.int, errormsg *C.char) { contractIdStr := C.GoString(contractId) fnameStr := C.GoString(fname) argsStr := C.GoString(args) @@ -350,6 +403,13 @@ func luaDelegateCallContract(L *LState, service C.int, contractId *C.char, var cid []byte var err error + opId := logOperation(ctx, "", "delegate-call", contractIdStr, fnameStr, argsStr) + defer func() { + if errormsg != nil { + logOperationResult(ctx, opId, C.GoString(errormsg)) + } + }() + // get the contract address if contractIdStr == "multicall" { isMultiCall = true @@ -361,6 +421,7 @@ func luaDelegateCallContract(L *LState, service C.int, contractId *C.char, if err != nil { return -1, C.CString("[Contract.LuaDelegateCallContract] invalid contractId: " + err.Error()) } + contractIdStr = types.EncodeAddress(cid) } aid := types.ToAccountID(cid) @@ -403,6 +464,10 @@ func luaDelegateCallContract(L *LState, service C.int, contractId *C.char, // create a new executor with the remaining gas on the child LState ce := newExecutor(bytecode, cid, ctx, &ci, zeroBig, false, false, contractState) defer func() { + // save the result if the call was successful + if ce.preErr == nil && ce.err == nil { + logOperationResult(ctx, opId, ce.jsonRet) + } // close the executor, closes also the child LState ce.close() // set the remaining gas on the parent LState @@ -413,7 +478,7 @@ func luaDelegateCallContract(L *LState, service C.int, contractId *C.char, return -1, C.CString("[Contract.LuaDelegateCallContract] newExecutor error: " + ce.err.Error()) } - seq, err := setRecoveryPoint(aid, ctx, nil, ctx.curContract.callState, zeroBig, false, false) + seq, err := createRecoveryPoint(aid, ctx, nil, ctx.curContract.callState, zeroBig, false, false) if err != nil { return -1, C.CString("[System.LuaDelegateCallContract] database error: " + err.Error()) } @@ -424,11 +489,11 @@ func luaDelegateCallContract(L *LState, service C.int, contractId *C.char, // execute the contract call defer setInstCount(ctx, L, ce.L) - ret := ce.call(minusCallCount(ctx, C.vm_instcount(L), luaCallCountDeduc), L) + ret = ce.call(minusCallCount(ctx, C.vm_instcount(L), luaCallCountDeduc), L) // check if the contract call failed if ce.err != nil { - err := clearRecovery(L, ctx, seq, true) + err := clearRecoveryPoint(L, ctx, seq, true) if err != nil { return -1, C.CString("[Contract.LuaDelegateCallContract] recovery error: " + err.Error()) } @@ -444,7 +509,7 @@ func luaDelegateCallContract(L *LState, service C.int, contractId *C.char, } if seq == 1 { - err := clearRecovery(L, ctx, seq, false) + err := clearRecoveryPoint(L, ctx, seq, false) if err != nil { return -1, C.CString("[Contract.LuaDelegateCallContract] recovery error: " + err.Error()) } @@ -471,15 +536,24 @@ func getAddressNameResolved(account string, bs *state.BlockState) ([]byte, error } //export luaSendAmount -func luaSendAmount(L *LState, service C.int, contractId *C.char, amount *C.char) *C.char { +func luaSendAmount(L *LState, service C.int, contractId *C.char, amount *C.char) (errormsg *C.char) { + contractAddress := C.GoString(contractId) + amountStr := C.GoString(amount) ctx := contexts[service] if ctx == nil { return C.CString("[Contract.LuaSendAmount] contract state not found") } + opId := logOperation(ctx, amountStr, "send", contractAddress) + defer func() { + if errormsg != nil { + logOperationResult(ctx, opId, C.GoString(errormsg)) + } + }() + // read the amount to be sent - amountBig, err := transformAmount(C.GoString(amount), ctx.blockInfo.ForkVersion) + amountBig, err := transformAmount(amountStr, ctx.blockInfo.ForkVersion) if err != nil { return C.CString("[Contract.LuaSendAmount] invalid amount: " + err.Error()) } @@ -490,10 +564,11 @@ func luaSendAmount(L *LState, service C.int, contractId *C.char, amount *C.char) } // get the receiver account - cid, err := getAddressNameResolved(C.GoString(contractId), ctx.bs) + cid, err := getAddressNameResolved(contractAddress, ctx.bs) if err != nil { return C.CString("[Contract.LuaSendAmount] invalid contractId: " + err.Error()) } + contractAddress = types.EncodeAddress(cid) // get the receiver state aid := types.ToAccountID(cid) @@ -524,7 +599,7 @@ func luaSendAmount(L *LState, service C.int, contractId *C.char, amount *C.char) // get the contract code bytecode := getContractCode(cs.ctrState, ctx.bs) if bytecode == nil { - return C.CString("[Contract.LuaSendAmount] cannot find contract:" + C.GoString(contractId)) + return C.CString("[Contract.LuaSendAmount] cannot find contract:" + contractAddress) } // get the remaining gas from the parent LState @@ -532,6 +607,10 @@ func luaSendAmount(L *LState, service C.int, contractId *C.char, amount *C.char) // create a new executor with the remaining gas on the child LState ce := newExecutor(bytecode, cid, ctx, &ci, amountBig, false, false, cs.ctrState) defer func() { + // save the result if the call was successful + if ce.preErr == nil && ce.err == nil { + logOperationResult(ctx, opId, ce.jsonRet) + } // close the executor, closes also the child LState ce.close() // set the remaining gas on the parent LState @@ -550,7 +629,7 @@ func luaSendAmount(L *LState, service C.int, contractId *C.char, amount *C.char) } // create a recovery point - seq, err := setRecoveryPoint(aid, ctx, senderState, cs, amountBig, false, false) + seq, err := createRecoveryPoint(aid, ctx, senderState, cs, amountBig, false, false) if err != nil { return C.CString("[System.LuaSendAmount] database error: " + err.Error()) } @@ -579,7 +658,7 @@ func luaSendAmount(L *LState, service C.int, contractId *C.char, amount *C.char) // check if the contract call failed if ce.err != nil { // recover to the previous state - err := clearRecovery(L, ctx, seq, true) + err := clearRecoveryPoint(L, ctx, seq, true) if err != nil { return C.CString("[Contract.LuaSendAmount] recovery err: " + err.Error()) } @@ -592,7 +671,7 @@ func luaSendAmount(L *LState, service C.int, contractId *C.char, amount *C.char) } if seq == 1 { - err := clearRecovery(L, ctx, seq, false) + err := clearRecoveryPoint(L, ctx, seq, false) if err != nil { return C.CString("[Contract.LuaSendAmount] recovery err: " + err.Error()) } @@ -615,8 +694,8 @@ func luaSendAmount(L *LState, service C.int, contractId *C.char, amount *C.char) } // update the recovery point - if ctx.lastRecoveryEntry != nil { - _, _ = setRecoveryPoint(aid, ctx, senderState, cs, amountBig, true, false) + if ctx.lastRecoveryPoint != nil { + _, _ = createRecoveryPoint(aid, ctx, senderState, cs, amountBig, true, false) } // log some info @@ -651,7 +730,7 @@ func luaSetRecoveryPoint(L *LState, service C.int) (C.int, *C.char) { if curContract.callState.ctrState.IsMultiCall() { return 0, nil } - seq, err := setRecoveryPoint(types.ToAccountID(curContract.contractId), ctx, nil, + seq, err := createRecoveryPoint(types.ToAccountID(curContract.contractId), ctx, nil, curContract.callState, zeroBig, false, false) if err != nil { return -1, C.CString("[Contract.pcall] database error: " + err.Error()) @@ -662,17 +741,17 @@ func luaSetRecoveryPoint(L *LState, service C.int) (C.int, *C.char) { return C.int(seq), nil } -func clearRecovery(L *LState, ctx *vmContext, start int, isError bool) error { - item := ctx.lastRecoveryEntry +func clearRecoveryPoint(L *LState, ctx *vmContext, start int, isError bool) error { + item := ctx.lastRecoveryPoint for { if isError { - if item.recovery(ctx.bs) != nil { + if item.revertState(ctx.bs) != nil { return errors.New("database error") } } if item.seq == start { if isError || item.prev == nil { - ctx.lastRecoveryEntry = item.prev + ctx.lastRecoveryPoint = item.prev } return nil } @@ -689,7 +768,7 @@ func luaClearRecovery(L *LState, service C.int, start int, isError bool) *C.char if ctx == nil { return C.CString("[Contract.pcall] contract state not found") } - err := clearRecovery(L, ctx, start, isError) + err := clearRecoveryPoint(L, ctx, start, isError) if err != nil { return C.CString(err.Error()) } @@ -999,6 +1078,12 @@ func transformAmount(amountStr string, forkVersion int32) (*big.Int, error) { if !valid { return nil, errors.New("converting error for BigNum: " + amountStr) } + if forkVersion >= 5 { + // Check for negative amounts + if amount.Cmp(zeroBig) < 0 { + return nil, errors.New("negative amount not allowed") + } + } return amount, nil } } @@ -1117,10 +1202,11 @@ func luaDeployContract( contract *C.char, args *C.char, amount *C.char, -) (C.int, *C.char) { +) (ret C.int, errormsg *C.char) { - argsStr := C.GoString(args) contractStr := C.GoString(contract) + argsStr := C.GoString(args) + amountStr := C.GoString(amount) ctx := contexts[service] if ctx == nil { @@ -1131,6 +1217,13 @@ func luaDeployContract( } bs := ctx.bs + opId := logOperation(ctx, amountStr, "deploy", contractStr, argsStr) + defer func() { + if errormsg != nil { + logOperationResult(ctx, opId, C.GoString(errormsg)) + } + }() + // contract code var codeABI []byte var sourceCode []byte @@ -1202,7 +1295,7 @@ func luaDeployContract( ctx.callState[newContract.AccountID()] = cs // read the amount transferred to the contract - amountBig, err := transformAmount(C.GoString(amount), ctx.blockInfo.ForkVersion) + amountBig, err := transformAmount(amountStr, ctx.blockInfo.ForkVersion) if err != nil { return -1, C.CString("[Contract.LuaDeployContract]value not proper format:" + err.Error()) } @@ -1224,7 +1317,7 @@ func luaDeployContract( } // create a recovery point - seq, err := setRecoveryPoint(newContract.AccountID(), ctx, senderState, cs, amountBig, false, true) + seq, err := createRecoveryPoint(newContract.AccountID(), ctx, senderState, cs, amountBig, false, true) if err != nil { return -1, C.CString("[System.LuaDeployContract] DB err:" + err.Error()) } @@ -1265,6 +1358,10 @@ func luaDeployContract( // create a new executor with the remaining gas on the child LState ce := newExecutor(bytecode, newContract.ID(), ctx, &ci, amountBig, true, false, contractState) defer func() { + // save the result if the call was successful + if ce.preErr == nil && ce.err == nil { + logOperationResult(ctx, opId, ce.jsonRet) + } // close the executor, which will close the child LState ce.close() // set the remaining gas on the parent LState @@ -1286,7 +1383,7 @@ func luaDeployContract( senderState.SetNonce(senderState.Nonce() + 1) addr := C.CString(types.EncodeAddress(newContract.ID())) - ret := C.int(1) + ret = C.int(1) if ce != nil { // run the constructor @@ -1296,7 +1393,7 @@ func luaDeployContract( // check if the execution was successful if ce.err != nil { // rollback the recovery point - err := clearRecovery(L, ctx, seq, true) + err := clearRecoveryPoint(L, ctx, seq, true) if err != nil { return -1, C.CString("[Contract.LuaDeployContract] recovery error: " + err.Error()) } @@ -1310,7 +1407,7 @@ func luaDeployContract( } if seq == 1 { - err := clearRecovery(L, ctx, seq, false) + err := clearRecoveryPoint(L, ctx, seq, false) if err != nil { return -1, C.CString("[Contract.LuaDeployContract] recovery error: " + err.Error()) } @@ -1338,7 +1435,9 @@ func luaRandomInt(min, max, service C.int) C.int { } //export luaEvent -func luaEvent(L *LState, service C.int, eventName *C.char, args *C.char) *C.char { +func luaEvent(L *LState, service C.int, name *C.char, args *C.char) *C.char { + eventName := C.GoString(name) + eventArgs := C.GoString(args) ctx := contexts[service] if ctx.isQuery == true || ctx.nestedView > 0 { return C.CString("[Contract.Event] event not permitted in query") @@ -1346,10 +1445,10 @@ func luaEvent(L *LState, service C.int, eventName *C.char, args *C.char) *C.char if ctx.eventCount >= maxEventCnt(ctx) { return C.CString(fmt.Sprintf("[Contract.Event] exceeded the maximum number of events(%d)", maxEventCnt(ctx))) } - if len(C.GoString(eventName)) > maxEventNameSize { + if len(eventName) > maxEventNameSize { return C.CString(fmt.Sprintf("[Contract.Event] exceeded the maximum length of event name(%d)", maxEventNameSize)) } - if len(C.GoString(args)) > maxEventArgSize { + if len(eventArgs) > maxEventArgSize { return C.CString(fmt.Sprintf("[Contract.Event] exceeded the maximum length of event args(%d)", maxEventArgSize)) } ctx.events = append( @@ -1357,11 +1456,12 @@ func luaEvent(L *LState, service C.int, eventName *C.char, args *C.char) *C.char &types.Event{ ContractAddress: ctx.curContract.contractId, EventIdx: ctx.eventCount, - EventName: C.GoString(eventName), - JsonArgs: C.GoString(args), + EventName: eventName, + JsonArgs: eventArgs, }, ) ctx.eventCount++ + logOperation(ctx, "", "event", eventName, eventArgs) return nil } @@ -1463,7 +1563,7 @@ func luaNameResolve(L *LState, service C.int, name_or_address *C.char) *C.char { } //export luaGovernance -func luaGovernance(L *LState, service C.int, gType C.char, arg *C.char) *C.char { +func luaGovernance(L *LState, service C.int, gType C.char, arg *C.char) (errormsg *C.char) { ctx := contexts[service] if ctx == nil { @@ -1476,6 +1576,7 @@ func luaGovernance(L *LState, service C.int, gType C.char, arg *C.char) *C.char var amountBig *big.Int var payload []byte + var opId int64 switch gType { case 'S', 'U': @@ -1486,17 +1587,27 @@ func luaGovernance(L *LState, service C.int, gType C.char, arg *C.char) *C.char } if gType == 'S' { payload = []byte(fmt.Sprintf(`{"Name":"%s"}`, types.Opstake.Cmd())) + opId = logOperation(ctx, "", "stake", amountBig.String()) } else { payload = []byte(fmt.Sprintf(`{"Name":"%s"}`, types.Opunstake.Cmd())) + opId = logOperation(ctx, "", "unstake", amountBig.String()) } case 'V': amountBig = zeroBig payload = []byte(fmt.Sprintf(`{"Name":"%s","Args":%s}`, types.OpvoteBP.Cmd(), C.GoString(arg))) + opId = logOperation(ctx, "", "vote", C.GoString(arg)) case 'D': amountBig = zeroBig payload = []byte(fmt.Sprintf(`{"Name":"%s","Args":%s}`, types.OpvoteDAO.Cmd(), C.GoString(arg))) + opId = logOperation(ctx, "", "voteDAO", C.GoString(arg)) } + defer func() { + if errormsg != nil { + logOperationResult(ctx, opId, C.GoString(errormsg)) + } + }() + cid := []byte(types.AergoSystem) aid := types.ToAccountID(cid) scsState, err := getContractState(ctx, cid) @@ -1522,14 +1633,14 @@ func luaGovernance(L *LState, service C.int, gType C.char, arg *C.char) *C.char return C.CString("[Contract.LuaGovernance] error: " + err.Error()) } - seq, err := setRecoveryPoint(aid, ctx, senderState, scsState, zeroBig, false, false) + seq, err := createRecoveryPoint(aid, ctx, senderState, scsState, zeroBig, false, false) if err != nil { return C.CString("[Contract.LuaGovernance] database error: " + err.Error()) } events, err := system.ExecuteSystemTx(scsState.ctrState, &txBody, senderState, receiverState, ctx.blockInfo) if err != nil { - rErr := clearRecovery(L, ctx, seq, true) + rErr := clearRecoveryPoint(L, ctx, seq, true) if rErr != nil { return C.CString("[Contract.LuaGovernance] recovery error: " + rErr.Error()) } @@ -1537,7 +1648,7 @@ func luaGovernance(L *LState, service C.int, gType C.char, arg *C.char) *C.char } if seq == 1 { - err := clearRecovery(L, ctx, seq, false) + err := clearRecoveryPoint(L, ctx, seq, false) if err != nil { return C.CString("[Contract.LuaGovernance] recovery error: " + err.Error()) } @@ -1546,9 +1657,9 @@ func luaGovernance(L *LState, service C.int, gType C.char, arg *C.char) *C.char ctx.eventCount += int32(len(events)) ctx.events = append(ctx.events, events...) - if ctx.lastRecoveryEntry != nil { + if ctx.lastRecoveryPoint != nil { if gType == 'S' { - seq, _ = setRecoveryPoint(aid, ctx, senderState, scsState, amountBig, true, false) + seq, _ = createRecoveryPoint(aid, ctx, senderState, scsState, amountBig, true, false) if ctx.traceFile != nil { _, _ = ctx.traceFile.WriteString(fmt.Sprintf("[GOVERNANCE]aid(%s)\n", aid.String())) _, _ = ctx.traceFile.WriteString(fmt.Sprintf("snapshot set %d\n", seq)) @@ -1557,7 +1668,7 @@ func luaGovernance(L *LState, service C.int, gType C.char, arg *C.char) *C.char senderState.Balance().String(), receiverState.Balance().String())) } } else if gType == 'U' { - seq, _ = setRecoveryPoint(aid, ctx, receiverState, ctx.curContract.callState, amountBig, true, false) + seq, _ = createRecoveryPoint(aid, ctx, receiverState, ctx.curContract.callState, amountBig, true, false) if ctx.traceFile != nil { _, _ = ctx.traceFile.WriteString(fmt.Sprintf("[GOVERNANCE]aid(%s)\n", aid.String())) _, _ = ctx.traceFile.WriteString(fmt.Sprintf("snapshot set %d\n", seq)) @@ -1699,6 +1810,11 @@ func luaGetStaking(service C.int, addr *C.char) (*C.char, C.lua_Integer, *C.char } func sendBalance(sender *state.AccountState, receiver *state.AccountState, amount *big.Int) *C.char { + if currentForkVersion >= 5 { + if amount.Cmp(zeroBig) < 0 { + return C.CString("[Contract.sendBalance] negative amount not allowed") + } + } if err := state.SendBalance(sender, receiver, amount); err != nil { return C.CString("[Contract.sendBalance] insufficient balance: " + sender.Balance().String() + " : " + amount.String()) diff --git a/contract/vm_callback_test.go b/contract/vm_callback_test.go index ceeec753e..941c7b12a 100644 --- a/contract/vm_callback_test.go +++ b/contract/vm_callback_test.go @@ -215,6 +215,46 @@ func TestTransformAmount(t *testing.T) { {4, "0.000000000000000000000000001 aergo", nil, errors.New("converting error for BigNum: 0.000000000000000000000000001 aergo")}, {4, "0.000000000000000123000 aergo", nil, errors.New("converting error for BigNum: 0.000000000000000123000 aergo")}, {4, "0.0000000000000000000000 aergo", nil, errors.New("converting error for BigNum: 0.0000000000000000000000 aergo")}, + + // Negative Decimal Amounts + + {5, "-123.456 aergo", nil, errors.New("negative amount not allowed")}, + {5, "-123.4 aergo", nil, errors.New("negative amount not allowed")}, + {5, "-123. aergo", nil, errors.New("negative amount not allowed")}, + {5, "-100. aergo", nil, errors.New("negative amount not allowed")}, + {5, "-10. aergo", nil, errors.New("negative amount not allowed")}, + {5, "-1. aergo", nil, errors.New("negative amount not allowed")}, + {5, "-100.0 aergo", nil, errors.New("negative amount not allowed")}, + {5, "-10.0 aergo", nil, errors.New("negative amount not allowed")}, + {5, "-1.0 aergo", nil, errors.New("negative amount not allowed")}, + {5, "-0.1 aergo", nil, errors.New("negative amount not allowed")}, + {5, "-0.01 aergo", nil, errors.New("negative amount not allowed")}, + {5, "-0.0000000001 aergo", nil, errors.New("negative amount not allowed")}, + {5, "-0.000000000000000001 aergo", nil, errors.New("negative amount not allowed")}, + {5, "-0.000000000000000123 aergo", nil, errors.New("negative amount not allowed")}, + {5, "-0.000000000000123000 aergo", nil, errors.New("negative amount not allowed")}, + {5, "-0.100000000000000123 aergo", nil, errors.New("negative amount not allowed")}, + {5, "-1.000000000000000123 aergo", nil, errors.New("negative amount not allowed")}, + {5, "-123.456000000000000789 aergo", nil, errors.New("negative amount not allowed")}, + + {5, "-123.456aergo", nil, errors.New("negative amount not allowed")}, + {5, "-123.4aergo", nil, errors.New("negative amount not allowed")}, + {5, "-123.aergo", nil, errors.New("negative amount not allowed")}, + {5, "-100.aergo", nil, errors.New("negative amount not allowed")}, + {5, "-10.aergo", nil, errors.New("negative amount not allowed")}, + {5, "-1.aergo", nil, errors.New("negative amount not allowed")}, + {5, "-100.0aergo", nil, errors.New("negative amount not allowed")}, + {5, "-10.0aergo", nil, errors.New("negative amount not allowed")}, + {5, "-1.0aergo", nil, errors.New("negative amount not allowed")}, + {5, "-0.1aergo", nil, errors.New("negative amount not allowed")}, + {5, "-0.01aergo", nil, errors.New("negative amount not allowed")}, + {5, "-0.0000000001aergo", nil, errors.New("negative amount not allowed")}, + {5, "-0.000000000000000001aergo", nil, errors.New("negative amount not allowed")}, + {5, "-0.000000000000000123aergo", nil, errors.New("negative amount not allowed")}, + {5, "-0.000000000000123000aergo", nil, errors.New("negative amount not allowed")}, + {5, "-0.100000000000000123aergo", nil, errors.New("negative amount not allowed")}, + {5, "-1.000000000000000123aergo", nil, errors.New("negative amount not allowed")}, + {5, "-123.456000000000000789aergo", nil, errors.New("negative amount not allowed")}, } for _, tt := range decimal_tests { diff --git a/contract/vm_direct/vm_direct.go b/contract/vm_direct/vm_direct.go index 98cadc329..2ac8b0cc4 100644 --- a/contract/vm_direct/vm_direct.go +++ b/contract/vm_direct/vm_direct.go @@ -102,7 +102,7 @@ func LoadDummyChainEx(chainType ChainType) (*DummyChain, error) { // clear folder if exists _ = os.RemoveAll(dataPath) // initialize the state database - err = bc.sdb.Init(string(dbImpl), dataPath, nil, false) + err = bc.sdb.Init(string(dbImpl), dataPath, nil, false, nil) if err != nil { return nil, err } @@ -135,7 +135,7 @@ func LoadDummyChainEx(chainType ChainType) (*DummyChain, error) { contract.SetStateSQLMaxDBSize(1024) contract.StartLStateFactory(lStateMaxSize, config.GetDefaultNumLStateClosers(), 1) - contract.InitContext(3) + contract.InitContext(3, false) // To pass the governance tests. types.InitGovernance("dpos", true) @@ -482,10 +482,12 @@ func executeTx( var txFee *big.Int var rv string + var internalOps string var events []*types.Event + switch txBody.Type { case types.TxType_NORMAL, types.TxType_REDEPLOY, types.TxType_TRANSFER, types.TxType_CALL, types.TxType_DEPLOY: - rv, events, txFee, err = contract.Execute(execCtx, bs, cdb, tx.GetTx(), sender, receiver, bi, executionMode, false) + rv, events, internalOps, txFee, err = contract.Execute(execCtx, bs, cdb, tx.GetTx(), sender, receiver, bi, executionMode, false) sender.SubBalance(txFee) case types.TxType_GOVERNANCE: txFee = new(big.Int).SetUint64(0) @@ -512,7 +514,7 @@ func executeTx( } return types.ErrNotAllowedFeeDelegation } - rv, events, txFee, err = contract.Execute(execCtx, bs, cdb, tx.GetTx(), sender, receiver, bi, executionMode, true) + rv, events, internalOps, txFee, err = contract.Execute(execCtx, bs, cdb, tx.GetTx(), sender, receiver, bi, executionMode, true) receiver.SubBalance(txFee) } @@ -567,6 +569,10 @@ func executeTx( } bs.BpReward.Add(&bs.BpReward, txFee) + if len(internalOps) > 0 { + bs.AddInternalOps(internalOps) + } + receipt := types.NewReceipt(receiver.ID(), status, rv) receipt.FeeUsed = txFee.Bytes() receipt.TxHash = tx.GetHash() diff --git a/contract/vm_dummy/test_files/all_types.lua b/contract/vm_dummy/test_files/all_types.lua new file mode 100644 index 000000000..124a8e2a0 --- /dev/null +++ b/contract/vm_dummy/test_files/all_types.lua @@ -0,0 +1,52 @@ +state.var { + name = state.value(), + list = state.array(), + values = state.map() +} + +-- value type + +function value_set(new_name) + name:set(new_name) + contract.event("value_set", new_name) +end + +function value_get() + return name:get() +end + +-- map type + +function map_set(key, val) + values[key] = val + contract.event("map_set", key, val) +end + +function map_get(key) + return values[key] +end + +-- array type + +function array_append(val) + list:append(val) + contract.event("array_append", val) +end + +function array_set(idx, val) + list[idx] = val + contract.event("array_set", idx, val) +end + +function array_get(idx) + return list[idx] +end + +function array_length() + return list:length() +end + +-- write functions +abi.register(value_set, map_set, array_append, array_set) +-- read-only functions +abi.register_view(value_get, map_get, array_get, array_length) diff --git a/contract/vm_dummy/vm_dummy.go b/contract/vm_dummy/vm_dummy.go index b867941ad..2b66a7366 100644 --- a/contract/vm_dummy/vm_dummy.go +++ b/contract/vm_dummy/vm_dummy.go @@ -20,8 +20,8 @@ import ( "github.com/aergoio/aergo/v2/contract" "github.com/aergoio/aergo/v2/contract/system" "github.com/aergoio/aergo/v2/fee" - "github.com/aergoio/aergo/v2/internal/enc/hex" "github.com/aergoio/aergo/v2/internal/enc/base58" + "github.com/aergoio/aergo/v2/internal/enc/hex" "github.com/aergoio/aergo/v2/state" "github.com/aergoio/aergo/v2/state/statedb" "github.com/aergoio/aergo/v2/types" @@ -115,7 +115,7 @@ func LoadDummyChain(opts ...DummyChainOptions) (*DummyChain, error) { // reset the transaction id counter luaTxId = 0 - err = bc.sdb.Init(string(db.MemoryImpl), dataPath, nil, false) + err = bc.sdb.Init(string(db.MemoryImpl), dataPath, nil, false, nil) if err != nil { return nil, err } @@ -130,7 +130,7 @@ func LoadDummyChain(opts ...DummyChainOptions) (*DummyChain, error) { contract.LoadTestDatabase(dataPath) // sql database contract.SetStateSQLMaxDBSize(1024) contract.StartLStateFactory(lStateMaxSize, config.GetDefaultNumLStateClosers(), 1) - contract.InitContext(3) + contract.InitContext(3, false) bc.HardforkVersion = 2 @@ -411,7 +411,7 @@ func hash(id uint64) []byte { type luaTxDeploy struct { luaTxContractCommon isCompiled bool - cErr error + cErr error } var _ LuaTxTester = (*luaTxDeploy)(nil) @@ -445,7 +445,7 @@ func NewLuaTxDeployBig(sender, recipient string, amount *big.Int, code string) * txId: newTxId(), }, isCompiled: isCompiled, - cErr: nil, + cErr: nil, } } @@ -485,7 +485,7 @@ func (l *luaTxDeploy) Constructor(args string) *luaTxDeploy { } func contractFrame(l luaTxContract, bs *state.BlockState, cdb contract.ChainAccessor, receiptTx db.Transaction, - run func(s, c *state.AccountState, id types.AccountID, cs *statedb.ContractState) (string, []*types.Event, *big.Int, error)) error { + run func(s, c *state.AccountState, id types.AccountID, cs *statedb.ContractState) (string, []*types.Event, string, *big.Int, error)) error { creatorId := types.ToAccountID(l.sender()) creatorState, err := state.GetAccountState(l.sender(), bs.StateDB) @@ -539,7 +539,7 @@ func contractFrame(l luaTxContract, bs *state.BlockState, cdb contract.ChainAcce return err } - rv, events, cFee, err := run(creatorState, contractState, contractId, eContractState) + rv, events, _, cFee, err := run(creatorState, contractState, contractId, eContractState) if cFee != nil { usedFee.Add(usedFee, cFee) @@ -600,20 +600,20 @@ func (l *luaTxDeploy) run(execCtx context.Context, bs *state.BlockState, bc *Dum l._payload = util.NewLuaCodePayload(byteCode, payload.Args()) } return contractFrame(l, bs, bc, receiptTx, - func(sender, contractV *state.AccountState, contractId types.AccountID, eContractState *statedb.ContractState) (string, []*types.Event, *big.Int, error) { + func(sender, contractV *state.AccountState, contractId types.AccountID, eContractState *statedb.ContractState) (string, []*types.Event, string, *big.Int, error) { contractV.State().SqlRecoveryPoint = 1 ctx := contract.NewVmContext(execCtx, bs, nil, sender, contractV, eContractState, sender.ID(), l.Hash(), bi, "", true, false, contractV.State().SqlRecoveryPoint, contract.BlockFactory, l.amount(), math.MaxUint64, false, false) - rv, events, ctrFee, err := contract.Create(eContractState, l.payload(), l.recipient(), ctx) + rv, events, internalOps, ctrFee, err := contract.Create(eContractState, l.payload(), l.recipient(), ctx) if err != nil { - return "", nil, ctrFee, err + return "", nil, internalOps, ctrFee, err } err = statedb.StageContractState(eContractState, bs.StateDB) if err != nil { - return "", nil, ctrFee, err + return "", nil, internalOps, ctrFee, err } - return rv, events, ctrFee, nil + return rv, events, internalOps, ctrFee, nil }, ) } @@ -657,12 +657,12 @@ func NewLuaTxCallFeeDelegate(sender, recipient string, amount uint64, payload st func NewLuaTxMultiCall(sender, payload string) *luaTxCall { return &luaTxCall{ luaTxContractCommon: luaTxContractCommon{ - _sender: contract.StrHash(sender), - _recipient: contract.StrHash(""), - _amount: new(big.Int).SetUint64(0), - _payload: []byte(payload), - txId: newTxId(), - multiCall: true, + _sender: contract.StrHash(sender), + _recipient: contract.StrHash(""), + _amount: new(big.Int).SetUint64(0), + _payload: []byte(payload), + txId: newTxId(), + multiCall: true, }, } } @@ -674,23 +674,23 @@ func (l *luaTxCall) Fail(expectedErr string) *luaTxCall { func (l *luaTxCall) run(execCtx context.Context, bs *state.BlockState, bc *DummyChain, bi *types.BlockHeaderInfo, receiptTx db.Transaction) error { err := contractFrame(l, bs, bc, receiptTx, - func(sender, contractV *state.AccountState, contractId types.AccountID, eContractState *statedb.ContractState) (string, []*types.Event, *big.Int, error) { + func(sender, contractV *state.AccountState, contractId types.AccountID, eContractState *statedb.ContractState) (string, []*types.Event, string, *big.Int, error) { ctx := contract.NewVmContext(execCtx, bs, bc, sender, contractV, eContractState, sender.ID(), l.Hash(), bi, "", true, false, contractV.State().SqlRecoveryPoint, contract.BlockFactory, l.amount(), math.MaxUint64, l.feeDelegate, l.multiCall) - rv, events, ctrFee, err := contract.Call(eContractState, l.payload(), l.recipient(), ctx) + rv, events, internalOps, ctrFee, err := contract.Call(eContractState, l.payload(), l.recipient(), ctx) if err != nil { - return "", nil, ctrFee, err + return "", nil, internalOps, ctrFee, err } if !ctx.IsMultiCall() { err = statedb.StageContractState(eContractState, bs.StateDB) if err != nil { - return "", nil, ctrFee, err + return "", nil, internalOps, ctrFee, err } } - return rv, events, ctrFee, nil + return rv, events, internalOps, ctrFee, nil }, ) if l.expectedErr != "" { diff --git a/contract/vm_dummy/vm_dummy_test.go b/contract/vm_dummy/vm_dummy_test.go index 5cd69ecca..f9d458aca 100644 --- a/contract/vm_dummy/vm_dummy_test.go +++ b/contract/vm_dummy/vm_dummy_test.go @@ -17,6 +17,7 @@ import ( "github.com/aergoio/aergo/v2/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/aergoio/aergo/v2/cmd/aergoluac/util" ) const min_version int32 = 2 @@ -6276,7 +6277,8 @@ func readLuaCode(t *testing.T, file string) (luaCode string) { if ok != true { return "" } - raw, err := os.ReadFile(filepath.Join(filepath.Dir(filename), "test_files", file)) + filePath := filepath.Join(filepath.Dir(filename), "test_files", file) + raw, err := util.ReadContract(filePath) require.NoErrorf(t, err, "failed to read "+file) require.NotEmpty(t, raw, "failed to read "+file) return string(raw) diff --git a/contract/vm_state.go b/contract/vm_state.go index 27e2bd62f..720654ca1 100644 --- a/contract/vm_state.go +++ b/contract/vm_state.go @@ -72,52 +72,66 @@ func newContractInfo(cs *callState, sender, contractId []byte, rp uint64, amount } } -type recoveryEntry struct { +//////////////////////////////////////////////////////////////////////////////// +// State Recovery +//////////////////////////////////////////////////////////////////////////////// + +// recoveryPoint is a struct that contains the state of the contract at a given point in time +type recoveryPoint struct { seq int amount *big.Int senderState *state.AccountState senderNonce uint64 callState *callState + currentCall *InternalCall + startOp int onlySend bool isDeploy bool sqlSaveName *string stateRevision statedb.Snapshot - prev *recoveryEntry + prev *recoveryPoint } -func (re *recoveryEntry) recovery(bs *state.BlockState) error { +// reverts the state of the contract to a previous state, stored on a recovery point +func (rp *recoveryPoint) revertState(bs *state.BlockState) error { var zero big.Int - cs := re.callState + cs := rp.callState + + // mark the internal operations as reverted + if rp.currentCall != nil { + markOperationsAsReverted(rp.currentCall, rp.startOp) + } // restore the contract balance - if re.amount.Cmp(&zero) > 0 { - if re.senderState != nil { - re.senderState.AddBalance(re.amount) + if rp.amount.Cmp(&zero) > 0 { + if rp.senderState != nil { + rp.senderState.AddBalance(rp.amount) } if cs != nil { - cs.accState.SubBalance(re.amount) + cs.accState.SubBalance(rp.amount) } } - if re.onlySend { + if rp.onlySend { return nil } // restore the contract nonce - if re.senderState != nil { - re.senderState.SetNonce(re.senderNonce) + if rp.senderState != nil { + rp.senderState.SetNonce(rp.senderNonce) } + // if the contract state is not stored, do not restore it if cs == nil { return nil } // restore the contract state - if re.stateRevision != -1 { - err := cs.ctrState.Rollback(re.stateRevision) + if rp.stateRevision != -1 { + err := cs.ctrState.Rollback(rp.stateRevision) if err != nil { return newDbSystemError(err) } - if re.isDeploy { + if rp.isDeploy { err := cs.ctrState.SetCode(nil, nil) if err != nil { return newDbSystemError(err) @@ -128,14 +142,14 @@ func (re *recoveryEntry) recovery(bs *state.BlockState) error { // restore the contract SQL db state if cs.tx != nil { - if re.sqlSaveName == nil { + if rp.sqlSaveName == nil { err := cs.tx.rollbackToSavepoint() if err != nil { return newDbSystemError(err) } cs.tx = nil } else { - err := cs.tx.rollbackToSubSavepoint(*re.sqlSaveName) + err := cs.tx.rollbackToSubSavepoint(*rp.sqlSaveName) if err != nil { return newDbSystemError(err) } @@ -145,45 +159,78 @@ func (re *recoveryEntry) recovery(bs *state.BlockState) error { return nil } -func setRecoveryPoint(aid types.AccountID, ctx *vmContext, senderState *state.AccountState, - cs *callState, amount *big.Int, isSend, isDeploy bool) (int, error) { +// creates a recovery point on the current state of the VM +func createRecoveryPoint( + aid types.AccountID, + ctx *vmContext, + senderState *state.AccountState, + cs *callState, + amount *big.Int, + onlySend, isDeploy bool, +) (int, error) { var seq int - prev := ctx.lastRecoveryEntry + + // get the previous recovery point + prev := ctx.lastRecoveryPoint + + // get the next sequence number if prev != nil { seq = prev.seq + 1 } else { seq = 1 } + + // get the sender nonce var nonce uint64 if senderState != nil { nonce = senderState.Nonce() } - re := &recoveryEntry{ + + currentCall := getCurrentCall(ctx, ctx.callDepth) + var startOp int + if currentCall != nil { + startOp = len(currentCall.Operations) + } + + // create the recovery point + rp := &recoveryPoint{ seq, amount, senderState, nonce, cs, - isSend, + currentCall, + startOp, + onlySend, isDeploy, nil, -1, prev, } - ctx.lastRecoveryEntry = re - if isSend { + + // set this as the last recovery point + ctx.lastRecoveryPoint = rp + + // if it's just aergo transfer, do not store the contract state + if onlySend { return seq, nil } - re.stateRevision = cs.ctrState.Snapshot() + + // get the contract state snapshot + rp.stateRevision = cs.ctrState.Snapshot() + + // get the contract SQL db transaction tx := cs.tx if tx != nil { - saveName := fmt.Sprintf("%s_%p", aid.String(), &re) + saveName := fmt.Sprintf("%s_%p", aid.String(), &rp) err := tx.subSavepoint(saveName) if err != nil { return seq, err } - re.sqlSaveName = &saveName + rp.sqlSaveName = &saveName } + + // return the sequence number return seq, nil } diff --git a/go.mod b/go.mod index fb7ede170..6d98a984e 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,12 @@ module github.com/aergoio/aergo/v2 -go 1.23 +go 1.23.0 -toolchain go1.23.4 +toolchain go1.23.7 require ( github.com/aergoio/aergo-actor v0.0.0-20190219030625-562037d5fec7 - github.com/aergoio/aergo-lib v1.1.0 + github.com/aergoio/aergo-lib v1.3.0 github.com/aergoio/etcd v0.0.0-20190429013412-e8b3f96f6399 github.com/anaskhan96/base58check v0.0.0-20181220122047-b05365d494c4 github.com/bluele/gcache v0.0.0-20190518031135-bc40bd653833 @@ -35,7 +35,7 @@ require ( github.com/opentracing/opentracing-go v1.2.0 github.com/pkg/errors v0.9.1 github.com/rs/cors v1.7.0 - github.com/rs/zerolog v1.29.1 + github.com/rs/zerolog v1.31.0 github.com/sanity-io/litter v1.5.5 github.com/soheilhy/cmux v0.1.4 github.com/spf13/cobra v0.0.5 @@ -52,9 +52,13 @@ require ( github.com/Workiva/go-datastructures v1.0.50 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/bytedance/sonic v1.11.6 // indirect + github.com/bytedance/sonic/loader v0.1.1 // indirect github.com/cenkalti/backoff/v4 v4.1.1 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect @@ -62,26 +66,33 @@ require ( github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect - github.com/dgraph-io/badger/v3 v3.2103.2 // indirect - github.com/dgraph-io/ristretto v0.1.0 // indirect + github.com/dgraph-io/badger/v3 v3.2104.5 // indirect + github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/docker/go-units v0.5.0 // indirect - github.com/dustin/go-humanize v1.0.0 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect github.com/elastic/gosigar v0.14.3 // indirect github.com/flynn/noise v1.1.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect github.com/funkygao/assert v0.0.0-20160929004900-4a267e33bc79 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/gin-gonic/gin v1.10.1 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.20.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect + github.com/goccy/go-json v0.10.2 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/glog v1.1.2 // indirect + github.com/golang/glog v1.2.4 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/snappy v0.0.3 // indirect - github.com/google/flatbuffers v1.12.1 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/flatbuffers v23.5.26+incompatible // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.3 // indirect - github.com/hashicorp/hcl v1.0.1-0.20180906183839-65a6292f0157 // indirect + github.com/hashicorp/hcl v1.0.1-vault-5 // indirect github.com/huin/goupnp v1.3.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect @@ -91,6 +102,7 @@ require ( github.com/klauspost/compress v1.17.11 // indirect github.com/klauspost/cpuid/v2 v2.2.9 // indirect github.com/koron/go-ssdp v0.0.4 // indirect + github.com/leodido/go-urn v1.4.0 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-flow-metrics v0.2.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect @@ -122,7 +134,7 @@ require ( github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/orcaman/concurrent-map v0.0.0-20190314100340-2693aad1ed75 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect - github.com/pelletier/go-toml/v2 v2.1.0 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pion/datachannel v1.5.10 // indirect github.com/pion/dtls/v2 v2.2.12 // indirect github.com/pion/ice/v2 v2.3.37 // indirect @@ -161,6 +173,8 @@ require ( github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/syndtr/goleveldb v1.0.0 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.3.0 // indirect github.com/willf/bitset v1.1.10 // indirect github.com/wlynxg/anet v0.0.5 // indirect github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect @@ -170,13 +184,14 @@ require ( go.uber.org/mock v0.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect + golang.org/x/arch v0.8.0 // indirect golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 // indirect golang.org/x/mod v0.22.0 // indirect golang.org/x/net v0.33.0 // indirect - golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.28.0 // indirect + golang.org/x/sync v0.11.0 // indirect + golang.org/x/sys v0.30.0 // indirect golang.org/x/term v0.27.0 // indirect - golang.org/x/text v0.21.0 // indirect + golang.org/x/text v0.22.0 // indirect golang.org/x/tools v0.28.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 // indirect google.golang.org/grpc/examples v0.0.0-20230724170852-2aa261560586 // indirect @@ -191,3 +206,5 @@ replace github.com/Sirupsen/logrus => github.com/sirupsen/logrus v1.8.1 replace sourcegraph.com/sourcegraph/go-diff => github.com/sourcegraph/go-diff v0.6.0 replace sourcegraph.com/sourcegraph/appdash => github.com/sourcegraph/appdash v0.0.0-20211028080628-e2786a622600 + +replace github.com/dgraph-io/badger/v3 => github.com/shepelt/badger/v3 v3.2104.5 diff --git a/go.sum b/go.sum index 6744c511a..328bf2af2 100644 --- a/go.sum +++ b/go.sum @@ -55,8 +55,8 @@ github.com/Workiva/go-datastructures v1.0.50 h1:slDmfW6KCHcC7U+LP3DDBbm4fqTwZGn1 github.com/Workiva/go-datastructures v1.0.50/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= github.com/aergoio/aergo-actor v0.0.0-20190219030625-562037d5fec7 h1:dYRi21hTS3fJwjSh/KZTAuLXUbV/Ijm2395Nf4b3wNs= github.com/aergoio/aergo-actor v0.0.0-20190219030625-562037d5fec7/go.mod h1:/nqZcvcM0UipJRnUm61LrQ8rC7IyBr8mfx5F00sCbvs= -github.com/aergoio/aergo-lib v1.1.0 h1:tPilY3bZr28DyJ0gZFXquiYv2veUIar1fGTDYljAL4k= -github.com/aergoio/aergo-lib v1.1.0/go.mod h1:+RYRhok9tHDgRR8nj+mQx9qqknKBnJYvrlEJwr+RYqY= +github.com/aergoio/aergo-lib v1.3.0 h1:29lPhJPsE75KtK3UpueVjSY9NX4jp6oLqrnHIDT3qTY= +github.com/aergoio/aergo-lib v1.3.0/go.mod h1:vGXUumCltCrJ6xvXT1gAyNLiI1qLP1AqskPUnm1cOII= github.com/aergoio/etcd v0.0.0-20190429013412-e8b3f96f6399 h1:dJSTOiNe0xJFreGUBSh4bY3KGDxjilUVxAKqjij1pcw= github.com/aergoio/etcd v0.0.0-20190429013412-e8b3f96f6399/go.mod h1:Blp9ztau8P3FoDynvGUeKUD6qqW/2xQ80kNwU+ywPUM= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= @@ -95,6 +95,10 @@ github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= +github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= +github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/c-bata/go-prompt v0.2.3 h1:jjCS+QhG/sULBhAaBdjb2PlMRVaKXQgn+4yzaauvs2s= github.com/c-bata/go-prompt v0.2.3/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= @@ -113,6 +117,10 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= +github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -121,7 +129,6 @@ github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -156,21 +163,20 @@ github.com/derekparker/trie v0.0.0-20190322172448-1ce4922c7ad9 h1:aSaTVlEXc2QKl4 github.com/derekparker/trie v0.0.0-20190322172448-1ce4922c7ad9/go.mod h1:D6ICZm05D9VN1n/8iOtBxLpXtoGp6HDFUJ1RNVieOSE= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= -github.com/dgraph-io/badger/v3 v3.2103.2 h1:dpyM5eCJAtQCBcMCZcT4UBZchuTJgCywerHHgmxfxM8= -github.com/dgraph-io/badger/v3 v3.2103.2/go.mod h1:RHo4/GmYcKKh5Lxu63wLEMHJ70Pac2JqZRYGhlyAo2M= -github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI= github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= +github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= +github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= @@ -198,18 +204,20 @@ github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2 github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.8-0.20180830220226-ccc981bf8038/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/funkygao/assert v0.0.0-20160929004900-4a267e33bc79 h1:pMT64UqbHiYr/i6NEYi7MQrCbySinLNS/rXM8hjJpFE= github.com/funkygao/assert v0.0.0-20160929004900-4a267e33bc79/go.mod h1:f/3KPzEHvMhxhf0Kh6QUNJffbavpJUCyFWw1hnW6yXg= github.com/funkygao/golib v0.0.0-20180314131852-90d4905c1961 h1:17GfB8KI6sVSDbk6P9JmXhYcXI83brT609GUOviGSSs= github.com/funkygao/golib v0.0.0-20180314131852-90d4905c1961/go.mod h1:o83CLAArAI7NmTbznViTftc/ELn38qwnCOGsRI/DgR4= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ= +github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -224,12 +232,17 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8= +github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= @@ -240,6 +253,8 @@ github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= @@ -254,10 +269,9 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= -github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +github.com/golang/glog v1.2.4 h1:CNNw5U8lSiiBk7druxtSHHTsRWcxKoac6kZKm2peBBc= +github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -291,12 +305,14 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/flatbuffers v23.5.26+incompatible h1:M9dgRyhJemaM4Sw8+66GHBu8ioaQmyPLg1b8VwK5WJg= +github.com/google/flatbuffers v23.5.26+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -308,8 +324,8 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -346,22 +362,19 @@ github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51 github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= -github.com/guptarohit/asciigraph v0.4.1 h1:YHmCMN8VH81BIUIgTg2Fs3B52QDxNZw2RQ6j5pGoSxo= -github.com/guptarohit/asciigraph v0.4.1/go.mod h1:9fYEfE5IGJGxlP1B+w8wHFy7sNZMhPtn59f0RLtpRFM= +github.com/guptarohit/asciigraph v0.7.3 h1:p05XDDn7cBTWiBqWb30mrwxd6oU0claAjqeytllnsPY= +github.com/guptarohit/asciigraph v0.7.3/go.mod h1:dYl5wwK4gNsnFf9Zp+l06rFiDZ5YtXM6x7SRWZ3KGag= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -381,8 +394,8 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/hcl v1.0.1-0.20180906183839-65a6292f0157 h1:uyodBE3xDz0ynKs1tLBU26wOQoEkAqqiY18DbZ+FZrA= -github.com/hashicorp/hcl v1.0.1-0.20180906183839-65a6292f0157/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= +github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= @@ -431,8 +444,10 @@ github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= @@ -448,8 +463,9 @@ github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/libp2p/go-flow-metrics v0.2.0 h1:EIZzjmeOE6c8Dav0sNv35vhZxATIXWZg6j/C08XmmDw= @@ -475,24 +491,20 @@ github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0U github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= @@ -578,17 +590,14 @@ github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8= github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= @@ -614,9 +623,8 @@ github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2D github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.2.1-0.20180930205832-81a861c69d25/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= -github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= @@ -678,7 +686,6 @@ github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndr github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= @@ -693,9 +700,7 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= @@ -705,14 +710,12 @@ github.com/prometheus/common v0.61.0/go.mod h1:zr29OCN/2BsJRaFwG8QOBr41D6kkchKbp github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= github.com/quic-go/quic-go v0.48.2 h1:wsKXZPeGWpMpCGSWqOcqpW2wZYic/8T3aqiOID0/KWE= @@ -728,11 +731,9 @@ github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjR github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= -github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.16.1-0.20191111091419-e709c5d91e35/go.mod h1:9nvC1axdVrAHcu/s9taAVfBuIdTZLVQmKQyvrUjF5+I= -github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc= -github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= +github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= @@ -747,6 +748,8 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/serialx/hashring v0.0.0-20190515033939-7706f26af194 h1:YWnuNx9HpWDl2VXcLw2O+va5a8Ii9AVcsqrOkTjWPas= github.com/serialx/hashring v0.0.0-20190515033939-7706f26af194/go.mod h1:/yeG0My1xr/u+HZrFQ1tOQQQQrOawfyMUH13ai5brBc= +github.com/shepelt/badger/v3 v3.2104.5 h1:3y1JonARNE7gPaE6K/eMHa/BwFtd2noXpHZH/hvxFJ4= +github.com/shepelt/badger/v3 v3.2104.5/go.mod h1:RHo4/GmYcKKh5Lxu63wLEMHJ70Pac2JqZRYGhlyAo2M= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= @@ -798,13 +801,11 @@ github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3 github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.5.0/go.mod h1:AkYRkVJF8TkSG/xet6PzXX+l39KhhXa2pdqVSxnTcn4= github.com/spf13/viper v1.17.0 h1:I5txKw7MJasPL/BrfkbA0Jyo/oELqVmux4pR/UxOMfI= github.com/spf13/viper v1.17.0/go.mod h1:BmMMMLQXSbcHK6KAOiFLz0l5JHrU89OdIRHvsk0+yVI= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= @@ -830,20 +831,19 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= +github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= @@ -865,8 +865,6 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= @@ -905,6 +903,9 @@ go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= +golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -987,7 +988,6 @@ golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1052,8 +1052,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1066,7 +1066,6 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1078,7 +1077,6 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1118,20 +1116,21 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -1153,8 +1152,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1179,7 +1178,6 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1391,7 +1389,9 @@ lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/libtool/src/luajit b/libtool/src/luajit index eda86b19a..7b99b5011 160000 --- a/libtool/src/luajit +++ b/libtool/src/luajit @@ -1 +1 @@ -Subproject commit eda86b19a18b0f1da53bdc3c0f281124d4fe4260 +Subproject commit 7b99b50113f16f07cfe74efe8f1148cf5bd85361 diff --git a/mempool/mempool.go b/mempool/mempool.go index 54374a459..1b629df75 100644 --- a/mempool/mempool.go +++ b/mempool/mempool.go @@ -21,6 +21,7 @@ import ( "github.com/aergoio/aergo-actor/router" "github.com/aergoio/aergo-lib/log" "github.com/aergoio/aergo/v2/account/key" + "github.com/aergoio/aergo/v2/blacklist" "github.com/aergoio/aergo/v2/chain" cfg "github.com/aergoio/aergo/v2/config" "github.com/aergoio/aergo/v2/contract/enterprise" @@ -35,7 +36,6 @@ import ( "github.com/aergoio/aergo/v2/state/statedb" "github.com/aergoio/aergo/v2/types" "github.com/aergoio/aergo/v2/types/message" - "github.com/aergoio/aergo/v2/blacklist" ) const ( @@ -75,6 +75,7 @@ type MemPool struct { acceptChainIdHash []byte isPublic bool whitelist *whitelistConf + blockMulticall bool blockDeploy bool // followings are for test testConfig bool @@ -104,6 +105,7 @@ func NewMemPoolService(cfg *cfg.Config, cs *chain.ChainService) *MemPool { status: initial, verifier: nil, quit: make(chan bool), + blockMulticall: cfg.Mempool.BlockMulticall, blockDeploy: cfg.Mempool.BlockDeploy, } actor.BaseComponent = component.NewBaseComponent(message.MemPoolSvc, actor, log.NewLogger("mempool")) @@ -672,6 +674,10 @@ func (mp *MemPool) validateTx(tx types.Transaction, account types.Address) error return types.ErrTxInvalidRecipient } } + case types.TxType_MULTICALL: + if mp.blockMulticall { + return types.ErrTxInvalidType + } case types.TxType_DEPLOY: if tx.GetBody().GetRecipient() != nil { return types.ErrTxInvalidRecipient diff --git a/p2p/msgorder_test.go b/p2p/msgorder_test.go index 600491031..8f919c7e0 100644 --- a/p2p/msgorder_test.go +++ b/p2p/msgorder_test.go @@ -45,6 +45,7 @@ func Test_pbRequestOrder_SendTo(t *testing.T) { mockPeerManager := p2pmock.NewMockPeerManager(ctrl) mockRW := p2pmock.NewMockMsgReadWriter(ctrl) + mockPeerManager.EXPECT().MsgBufSize().Return(writeMsgBufferSize).AnyTimes() mockRW.EXPECT().WriteMsg(gomock.Any()).Return(tt.writeErr) peer := newRemotePeer(sampleRemote, 0, mockPeerManager, mockActorServ, logger, factory, &dummySigner{}, mockRW) @@ -92,6 +93,7 @@ func Test_pbMessageOrder_SendTo(t *testing.T) { mockPeerManager := p2pmock.NewMockPeerManager(ctrl) mockRW := p2pmock.NewMockMsgReadWriter(ctrl) + mockPeerManager.EXPECT().MsgBufSize().Return(writeMsgBufferSize).AnyTimes() mockRW.EXPECT().WriteMsg(gomock.Any()).Return(tt.writeErr) peer := newRemotePeer(sampleRemote, 0, mockPeerManager, mockActorServ, logger, factory, &dummySigner{}, mockRW) @@ -141,6 +143,8 @@ func Test_pbBlkNoticeOrder_SendTo(t *testing.T) { mockPeerManager := p2pmock.NewMockPeerManager(ctrl) mockRW := p2pmock.NewMockMsgReadWriter(ctrl) + mockPeerManager.EXPECT().MsgBufSize().Return(writeMsgBufferSize).AnyTimes() + if tt.keyExist { mockRW.EXPECT().WriteMsg(gomock.Any()).Return(tt.writeErr).Times(0) } else { @@ -211,6 +215,7 @@ func Test_pbBlkNoticeOrder_SendTo_SkipByHeight(t *testing.T) { mockPeerManager := p2pmock.NewMockPeerManager(ctrl) mockRW := p2pmock.NewMockMsgReadWriter(ctrl) + mockPeerManager.EXPECT().MsgBufSize().Return(writeMsgBufferSize).AnyTimes() writeCnt := 0 mockRW.EXPECT().WriteMsg(gomock.Any()).Do(func(arg interface{}) { writeCnt++ @@ -287,6 +292,7 @@ func Test_pbBlkNoticeOrder_SendTo_SkipByTime(t *testing.T) { mockPeerManager := p2pmock.NewMockPeerManager(ctrl) mockRW := p2pmock.NewMockMsgReadWriter(ctrl) + mockPeerManager.EXPECT().MsgBufSize().Return(writeMsgBufferSize).AnyTimes() writeCnt := 0 mockRW.EXPECT().WriteMsg(gomock.Any()).Do(func(arg interface{}) { writeCnt++ @@ -350,6 +356,7 @@ func Test_pbTxNoticeOrder_SendTo(t *testing.T) { mockPeerManager := p2pmock.NewMockPeerManager(ctrl) mockRW := p2pmock.NewMockMsgReadWriter(ctrl) + mockPeerManager.EXPECT().MsgBufSize().Return(writeMsgBufferSize).AnyTimes() if tt.keyExist == len(sampleHashes) { mockRW.EXPECT().WriteMsg(gomock.Any()).Return(tt.writeErr).Times(0) } else { diff --git a/p2p/p2pcommon/peermanager.go b/p2p/p2pcommon/peermanager.go index 6dfe4121e..6e8fb5625 100644 --- a/p2p/p2pcommon/peermanager.go +++ b/p2p/p2pcommon/peermanager.go @@ -44,4 +44,5 @@ type PeerManager interface { AddDesignatedPeer(meta PeerMeta) RemoveDesignatedPeer(peerID types.PeerID) ListDesignatedPeers() []PeerMeta + MsgBufSize() int } diff --git a/p2p/p2pcommon/temptype.go b/p2p/p2pcommon/temptype.go index fde708572..42b8144c3 100644 --- a/p2p/p2pcommon/temptype.go +++ b/p2p/p2pcommon/temptype.go @@ -6,7 +6,7 @@ package p2pcommon // This file describe the command to generate mock objects of imported interfaces -//go:generate sh -c "mockgen github.com/aergoio/aergo/v2/p2p/p2pcommon NTContainer,NetworkTransport | gsed -e 's/[Pp]ackage mock_p2pcommon/package p2pmock/g' > p2p/p2pmock/mock_networktransport.go" +//go:generate sh -c "mockgen github.com/aergoio/aergo/v2/p2p/p2pcommon NTContainer,NetworkTransport | gsed -e 's/[Pp]ackage mock_p2pcommon/package p2pmock/g' > ../p2pmock/mock_networktransport.go" // in aergo but outside of p2p //go:generate sh -c "mockgen github.com/aergoio/aergo/v2/types ChainAccessor | sed -e 's/[Pp]ackage mock_types/package p2pmock/g' > ../p2pmock/mock_chainaccessor.go" diff --git a/p2p/p2pmock/mock_chainaccessor.go b/p2p/p2pmock/mock_chainaccessor.go index d921c0920..12fbfa4c8 100644 --- a/p2p/p2pmock/mock_chainaccessor.go +++ b/p2p/p2pmock/mock_chainaccessor.go @@ -1,7 +1,7 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/aergoio/aergo/v2/types (interfaces: ChainAccessor) -// package p2pmock is a generated GoMock package. +// Package p2pmock is a generated GoMock package. package p2pmock import ( @@ -165,3 +165,17 @@ func (mr *MockChainAccessorMockRecorder) GetSystemValue(arg0 interface{}) *gomoc mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSystemValue", reflect.TypeOf((*MockChainAccessor)(nil).GetSystemValue), arg0) } + +// HardforkHeights mocks base method +func (m *MockChainAccessor) HardforkHeights() map[string]uint64 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HardforkHeights") + ret0, _ := ret[0].(map[string]uint64) + return ret0 +} + +// HardforkHeights indicates an expected call of HardforkHeights +func (mr *MockChainAccessorMockRecorder) HardforkHeights() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HardforkHeights", reflect.TypeOf((*MockChainAccessor)(nil).HardforkHeights)) +} diff --git a/p2p/p2pmock/mock_peermanager.go b/p2p/p2pmock/mock_peermanager.go index 0a499dd69..fa7802241 100644 --- a/p2p/p2pmock/mock_peermanager.go +++ b/p2p/p2pmock/mock_peermanager.go @@ -5,9 +5,9 @@ package p2pmock import ( - message "github.com/aergoio/aergo/v2/types/message" p2pcommon "github.com/aergoio/aergo/v2/p2p/p2pcommon" types "github.com/aergoio/aergo/v2/types" + message "github.com/aergoio/aergo/v2/types/message" gomock "github.com/golang/mock/gomock" reflect "reflect" ) @@ -273,3 +273,17 @@ func (mr *MockPeerManagerMockRecorder) ListDesignatedPeers() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDesignatedPeers", reflect.TypeOf((*MockPeerManager)(nil).ListDesignatedPeers)) } + +// MsgBufSize mocks base method +func (m *MockPeerManager) MsgBufSize() int { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MsgBufSize") + ret0, _ := ret[0].(int) + return ret0 +} + +// MsgBufSize indicates an expected call of MsgBufSize +func (mr *MockPeerManagerMockRecorder) MsgBufSize() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MsgBufSize", reflect.TypeOf((*MockPeerManager)(nil).MsgBufSize)) +} diff --git a/p2p/p2pmock/readme.txt b/p2p/p2pmock/readme.txt index f4e01fdb3..af6e35d0b 100644 --- a/p2p/p2pmock/readme.txt +++ b/p2p/p2pmock/readme.txt @@ -1,14 +1,23 @@ Prerequisites +NOTE: + +At this point, it may not works properly in this document. As the version of Golang has updated, the change in security policy or internal implementation is suspected of not being able to execute properly. + Installing mockgen the package github.com/golang/mock is superseded by https://github.com/uber/mock in 2021, but we are not ready to migrate yet by transitive dependencies. -go install github.com/golang/mock/mockgen@v1.6.0 +go install github.com/golang/mock/mockgen@v1.4.0 (In the future) Refering to https://github.com/uber-go/mock/ ( go install go.uber.org/mock/mockgen@latest ) +Installing stringer + +Some generate operations of this project needs stringer tool. It can be installed like below; + +go install golang.org/x/tools/cmd/stringer@latest Examples to generate mock class @@ -29,8 +38,9 @@ mockgen -source=p2p/p2pcommon/pool.go -mock_names=WaitingPeerManager=MockWaiting # Manually generated mock classes -The generate descriptions of these mock objects are in p2p/p2pcommon/temptypes.go . So you can use such like `go generate ./p2p/p2pcommon/temptypes.go` command. +The generate descriptions of these mock objects are in p2p/p2pcommon/temptypes.go . So you can use such like `go generate ./p2p/p2pcommon/temptype.go` command. +# Some files cannot be generated by go generate command. They should be generated using mockgen and gnu sed. # mock files which are not generated automatically by go generate ./p2p mockgen github.com/aergoio/aergo/v2/consensus ConsensusAccessor,AergoRaftAccessor | gsed -e 's/^package mock_[a-zA-Z0-9_]\+/package p2pmock/g' > p2p/p2pmock/mock_consensus.go @@ -38,4 +48,4 @@ mockgen -source=types/blockchain.go -package=p2pmock -destination=p2p/p2pmock/mo mockgen io Reader,ReadCloser,Writer,WriteCloser,ReadWriteCloser > p2p/p2pmock/mock_io.go | gsed -e 's/^package mock_[a-zA-Z0-9_]\+/package p2pmock/g' > p2p/p2pmock/mock_io.go -mockgen github.com/aergoio/aergo/v2/types ChainAccessor | sed -e 's/^package mock_[a-zA-Z0-9_]\+/package p2pmock/g' > p2p/p2pmock/mock_chainaccessor.go \ No newline at end of file +mockgen github.com/aergoio/aergo/v2/types ChainAccessor | sed -e 's/^package mock_[a-zA-Z0-9_]\+/package p2pmock/g' > p2p/p2pmock/mock_chainaccessor.go diff --git a/p2p/peermanager.go b/p2p/peermanager.go index ac4c48ba9..8418bd387 100644 --- a/p2p/peermanager.go +++ b/p2p/peermanager.go @@ -75,7 +75,8 @@ type peerManager struct { designatedPeers map[types.PeerID]p2pcommon.PeerMeta hiddenPeerSet map[types.PeerID]bool - logger *log.Logger + msgBufSize int + logger *log.Logger } // getPeerTask is struct to get peer for concurrent use @@ -90,6 +91,10 @@ var _ p2pcommon.PeerManager = (*peerManager)(nil) func NewPeerManager(is p2pcommon.InternalService, hsFactory p2pcommon.HSHandlerFactory, actor p2pcommon.ActorService, pf p2pcommon.PeerFactory, nt p2pcommon.NetworkTransport, mm metric.MetricsManager, lm p2pcommon.ListManager, logger *log.Logger, cfg *cfg.Config, skipHandshakeSync bool) p2pcommon.PeerManager { p2pConf := cfg.P2P //logger.SetLevel("debug") + msgBufSize := p2pConf.MsgBufSize + if msgBufSize < writeMsgBufferSize { + msgBufSize = writeMsgBufferSize + } pm := &peerManager{ is: is, nt: nt, @@ -125,6 +130,7 @@ func NewPeerManager(is p2pcommon.InternalService, hsFactory p2pcommon.HSHandlerF eventListeners: make([]p2pcommon.PeerEventListener, 0, 4), taskChannel: make(chan pmTask, 4), finishChannel: make(chan struct{}), + msgBufSize: msgBufSize, } // additional initializations @@ -471,6 +477,10 @@ func (pm *peerManager) GetPeerBlockInfos() []types.PeerBlockInfo { return infos } +func (pm *peerManager) MsgBufSize() int { + return pm.msgBufSize +} + func (pm *peerManager) GetPeerAddresses(noHidden bool, showSelf bool) []*message.PeerInfo { peers := make([]*message.PeerInfo, 0, len(pm.peerCache)) if showSelf { diff --git a/p2p/raftsupport/concclusterreceiver.go b/p2p/raftsupport/concclusterreceiver.go index 75e271b16..1baabf54d 100644 --- a/p2p/raftsupport/concclusterreceiver.go +++ b/p2p/raftsupport/concclusterreceiver.go @@ -19,30 +19,39 @@ import ( "github.com/pkg/errors" ) -// ClusterInfoReceiver is send p2p getClusterInfo to connected peers and Receive p2p responses one of peers return successful response -// The first version will be simplified version. it send and Receive one by one. +// ConcurrentClusterInfoReceiver is a struct that manages concurrent requests for cluster information from peers. +// It sends p2p GetClusterInfo requests to connected peers and collects responses until either: +// - A successful response is received +// - The required number of responses are collected +// - The operation times out +// +// The initial implementation processes requests and responses sequentially (one by one). type ConcurrentClusterInfoReceiver struct { - logger *log.Logger - mf p2pcommon.MoFactory + logger *log.Logger // Logger for recording events and errors + mf p2pcommon.MoFactory // Factory for creating message objects + peers []p2pcommon.RemotePeer // List of connected peers to query - peers []p2pcommon.RemotePeer - mutex sync.Mutex - sent map[p2pcommon.MsgID]p2pcommon.RemotePeer - sentCnt int + mutex sync.Mutex // Mutex to protect concurrent access to the struct - req *message.GetCluster + sent map[p2pcommon.MsgID]p2pcommon.RemotePeer // Tracks sent requests by message ID + sentCnt int // Count of total sent requests - ttl time.Duration - timeout time.Time - respCnt int - requiredResp int - succResps map[types.PeerID]*types.GetClusterInfoResponse - status receiverStatus + req *message.GetCluster // The cluster information request message + ttl time.Duration // Time-to-live duration for the operation + timeout time.Time // Absolute time when the operation will timeout - finished chan bool + respCnt int // Count of received responses + requiredResp int // Minimum required responses before completing + // Successful responses by peer ID + succResps map[types.PeerID]*types.GetClusterInfoResponse + + status receiverStatus // Current state of the receiver + finished chan bool // Channel to signal operation completion } func NewConcClusterInfoReceiver(actor p2pcommon.ActorService, mf p2pcommon.MoFactory, peers []p2pcommon.RemotePeer, ttl time.Duration, req *message.GetCluster, logger *log.Logger) *ConcurrentClusterInfoReceiver { + // TODO the value requiredResp of can cause trouble. + // Only the members of cluster can give the cluster information. There is a possibility of calculating the quorum because it sends requests to all connected peers regardless of membership. There is another problem. There is no cluster information in node when it send a request, so it is difficult to get the exact quorum because it also has no number of members. r := &ConcurrentClusterInfoReceiver{logger: logger, mf: mf, peers: peers, ttl: ttl, req: req, requiredResp: len(peers)/2 + 1, succResps: make(map[types.PeerID]*types.GetClusterInfoResponse), @@ -194,19 +203,19 @@ func (r *ConcurrentClusterInfoReceiver) calculate(err error) *message.GetCluster if err != nil { rsp.Err = err } else if len(r.succResps) < r.requiredResp { - rsp.Err = errors.New("too low responses: " + strconv.Itoa(len(r.succResps))) + rsp.Err = errors.New("too few responses: " + strconv.Itoa(len(r.succResps)) + " , required " + strconv.Itoa(r.requiredResp)) } else { r.logger.Debug().Int("respCnt", len(r.succResps)).Msg("calculating collected responses") var bestRsp *types.GetClusterInfoResponse = nil var bestPid types.PeerID - for pid, rsp := range r.succResps { + for peerId, rsp := range r.succResps { if bestRsp == nil || rsp.BestBlockNo > bestRsp.BestBlockNo { bestRsp = rsp - bestPid = pid + bestPid = peerId } } if bestRsp != nil { - r.logger.Debug().Stringer(p2putil.LogPeerID, types.LogPeerShort(bestPid)).Object("resp", bestRsp).Msg("chosed best response") + r.logger.Debug().Stringer(p2putil.LogPeerID, types.LogPeerShort(bestPid)).Object("resp", bestRsp).Msg("chose best response") rsp.ClusterID = bestRsp.GetClusterID() rsp.ChainID = bestRsp.GetChainID() rsp.Members = bestRsp.GetMbrAttrs() diff --git a/p2p/remotepeer.go b/p2p/remotepeer.go index 948a07c91..efd19633b 100644 --- a/p2p/remotepeer.go +++ b/p2p/remotepeer.go @@ -108,7 +108,7 @@ func newRemotePeer(remote p2pcommon.RemoteInfo, manageNum uint32, pm p2pcommon.P maxTxNoticeHashSize: DefaultPeerTxQueueSize, taskChannel: make(chan p2pcommon.PeerTask, 1), } - rPeer.writeBuf = make(chan p2pcommon.MsgOrder, writeMsgBufferSize) + rPeer.writeBuf = make(chan p2pcommon.MsgOrder, pm.MsgBufSize()) rPeer.writeDirect = make(chan p2pcommon.MsgOrder) var err error diff --git a/p2p/remotepeer_test.go b/p2p/remotepeer_test.go index e03fd0cab..35f80b8a2 100644 --- a/p2p/remotepeer_test.go +++ b/p2p/remotepeer_test.go @@ -330,13 +330,18 @@ func TestRemotePeerImpl_UpdateBlkCache(t *testing.T) { } for _, test := range tests { t.Run(test.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + mockActor := new(p2pmock.MockActorService) - mockPeerManager := new(p2pmock.MockPeerManager) + mockPeerManager := p2pmock.NewMockPeerManager(ctrl) mockSigner := new(p2pmock.MockMsgSigner) mockMF := new(p2pmock.MockMoFactory) sampleConn := p2pcommon.RemoteConn{IP: net.ParseIP(sampleMeta.PrimaryAddress()), Port: sampleMeta.PrimaryPort()} sampleRemote := p2pcommon.RemoteInfo{Meta: sampleMeta, Connection: sampleConn} + mockPeerManager.EXPECT().MsgBufSize().Return(writeMsgBufferSize).AnyTimes() + target := newRemotePeer(sampleRemote, 0, mockPeerManager, mockActor, logger, mockMF, mockSigner, nil) for _, hash := range test.inCache { target.blkHashCache.Add(hash, true) @@ -362,13 +367,17 @@ func TestRemotePeerImpl_UpdateTxCache(t *testing.T) { } for _, test := range tests { t.Run(test.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() mockActor := new(p2pmock.MockActorService) - mockPeerManager := new(p2pmock.MockPeerManager) + mockPeerManager := p2pmock.NewMockPeerManager(ctrl) mockSigner := new(p2pmock.MockMsgSigner) mockMF := new(p2pmock.MockMoFactory) sampleConn := p2pcommon.RemoteConn{IP: net.ParseIP(sampleMeta.PrimaryAddress()), Port: sampleMeta.PrimaryPort()} sampleRemote := p2pcommon.RemoteInfo{Meta: sampleMeta, Connection: sampleConn} + mockPeerManager.EXPECT().MsgBufSize().Return(writeMsgBufferSize).AnyTimes() + target := newRemotePeer(sampleRemote, 0, mockPeerManager, mockActor, logger, mockMF, mockSigner, nil) for _, hash := range test.inCache { target.txHashCache.Add(hash, true) @@ -417,13 +426,15 @@ func TestRemotePeerImpl_GetReceiver(t *testing.T) { defer ctrl.Finish() mockActor := new(p2pmock.MockActorService) - mockPeerManager := new(p2pmock.MockPeerManager) + mockPeerManager := p2pmock.NewMockPeerManager(ctrl) mockSigner := new(p2pmock.MockMsgSigner) mockMF := new(p2pmock.MockMoFactory) sampleConn := p2pcommon.RemoteConn{IP: net.ParseIP(sampleMeta.PrimaryAddress()), Port: sampleMeta.PrimaryPort()} sampleRemote := p2pcommon.RemoteInfo{Meta: sampleMeta, Connection: sampleConn} mockMo := p2pmock.NewMockMsgOrder(ctrl) + mockMo.EXPECT().GetProtocolID().Return(p2pcommon.GetBlocksRequest).AnyTimes() + mockPeerManager.EXPECT().MsgBufSize().Return(writeMsgBufferSize).AnyTimes() p := newRemotePeer(sampleRemote, 0, mockPeerManager, mockActor, logger, mockMF, mockSigner, nil) for _, add := range test.toAdd { @@ -471,6 +482,7 @@ func TestRemotePeerImpl_pushTxsNotice(t *testing.T) { mockMF := p2pmock.NewMockMoFactory(ctrl) mockSigner := new(p2pmock.MockMsgSigner) + mockPeerManager.EXPECT().MsgBufSize().Return(writeMsgBufferSize).AnyTimes() mockMO.EXPECT().GetMsgID().Return(p2pcommon.NewMsgID()).AnyTimes() mockMF.EXPECT().NewMsgTxBroadcastOrder(gomock.Any()).Return(mockMO). Times(test.expectSend) @@ -487,8 +499,6 @@ func TestRemotePeerImpl_pushTxsNotice(t *testing.T) { } } func TestRemotePeer_writeToPeer(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() rand := uuid.Must(uuid.NewV4()) var sampleMsgID p2pcommon.MsgID @@ -518,12 +528,16 @@ func TestRemotePeer_writeToPeer(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + mockPeerManager := p2pmock.NewMockPeerManager(ctrl) mockMO := p2pmock.NewMockMsgOrder(ctrl) mockStream := p2pmock.NewMockStream(ctrl) dummyRW := p2pmock.NewMockMsgReadWriter(ctrl) dummyRW.EXPECT().Close().AnyTimes() + mockPeerManager.EXPECT().MsgBufSize().Return(writeMsgBufferSize).AnyTimes() mockStream.EXPECT().Close().Return(nil).AnyTimes() mockMO.EXPECT().IsNeedSign().Return(true).AnyTimes() mockMO.EXPECT().SendTo(gomock.Any()).Return(tt.args.sendErr) diff --git a/p2p/subproto/blockhash_test.go b/p2p/subproto/blockhash_test.go index 551290b69..ef7370148 100644 --- a/p2p/subproto/blockhash_test.go +++ b/p2p/subproto/blockhash_test.go @@ -8,6 +8,7 @@ package subproto import ( "bytes" "crypto/sha256" + "fmt" "sync" "testing" @@ -261,6 +262,10 @@ func (a *testDoubleChainAccessor) getChain() [][]byte { } } +func (a *testDoubleChainAccessor) GetBlockByNo(blockNo types.BlockNo) (*types.Block, error) { + return nil, fmt.Errorf("not implemented") +} + type testDoubleHashesRespFactory struct { lastResp *types.GetHashesResponse lastStatus types.ResultStatus diff --git a/rpc/grpcserver.go b/rpc/grpcserver.go index a6253b18f..b7daff0ee 100644 --- a/rpc/grpcserver.go +++ b/rpc/grpcserver.go @@ -11,6 +11,7 @@ import ( "encoding/binary" "encoding/json" "errors" + "github.com/aergoio/aergo/v2/types/utils" "reflect" "strings" "sync" @@ -42,6 +43,8 @@ var ( // ErrNotSupportedConsensus = errors.New("not supported by this consensus") ) +const maxTxHashLength = 32 + type EventStream struct { filter *types.FilterInfo stream types.AergoRPCService_ListEventStreamServer @@ -76,8 +79,8 @@ const defaultActorTimeout = time.Second * 3 var _ types.AergoRPCServiceServer = (*AergoRPCService)(nil) -func (ns *AergoRPCService) GetActorHelper() p2pcommon.ActorService { - return ns.actorHelper +func (rpc *AergoRPCService) GetActorHelper() p2pcommon.ActorService { + return rpc.actorHelper } func (rpc *AergoRPCService) SetConsensusAccessor(ca consensus.ConsensusAccessor) { @@ -234,6 +237,8 @@ func (rpc *AergoRPCService) getChainInfo(ctx context.Context) (*types.ChainInfo, return nil, err } + chainInfo.Hardfork = rpc.actorHelper.GetChainAccessor().HardforkHeights() + return chainInfo, nil } @@ -559,6 +564,10 @@ func (rpc *AergoRPCService) GetTX(ctx context.Context, in *types.SingleBytes) (* if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil { return nil, err } + // in.Value is txHash + if in.Value == nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid input hash") + } result, err := rpc.actorHelper.CallRequestDefaultTimeout(message.MemPoolSvc, &message.MemPoolExist{Hash: in.Value}) if err != nil { @@ -581,6 +590,9 @@ func (rpc *AergoRPCService) GetBlockTX(ctx context.Context, in *types.SingleByte if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil { return nil, err } + if in.Value == nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid input hash") + } result, err := rpc.hub.RequestFuture(message.ChainSvc, &message.GetTx{TxHash: in.Value}, defaultActorTimeout, "rpc.(*AergoRPCService).GetBlockTX").Result() if err != nil { @@ -600,6 +612,9 @@ func (rpc *AergoRPCService) SendTX(ctx context.Context, tx *types.Tx) (*types.Co if err := rpc.checkAuth(ctx, WriteBlockChain); err != nil { return nil, err } + if tx.Body == nil { + return nil, status.Errorf(codes.InvalidArgument, "input tx is empty") + } if tx.Body.Nonce == 0 { getStateResult, err := rpc.hub.RequestFuture(message.ChainSvc, &message.GetState{Account: tx.Body.Account}, defaultActorTimeout, "rpc.(*AergoRPCService).SendTx").Result() @@ -665,8 +680,13 @@ func (rpc *AergoRPCService) CommitTX(ctx context.Context, in *types.TxList) (*ty if err := rpc.checkAuth(ctx, WriteBlockChain); err != nil { return nil, err } - if in.Txs == nil { - return nil, status.Errorf(codes.InvalidArgument, "input tx is empty") + if in.Txs == nil || len(in.Txs) == 0 { + return nil, status.Errorf(codes.InvalidArgument, "empty transaction") + } + for _, tx := range in.Txs { + if tx.Body == nil { + return nil, status.Errorf(codes.InvalidArgument, "input tx is empty") + } } rpc.hub.Get(message.MemPoolSvc) @@ -685,6 +705,10 @@ func (rpc *AergoRPCService) GetState(ctx context.Context, in *types.SingleBytes) if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil { return nil, err } + if in.Value == nil { + return nil, status.Errorf(codes.InvalidArgument, "input account is empty") + } + result, err := rpc.hub.RequestFuture(message.ChainSvc, &message.GetState{Account: in.Value}, defaultActorTimeout, "rpc.(*AergoRPCService).GetState").Result() if err != nil { @@ -702,6 +726,10 @@ func (rpc *AergoRPCService) GetStateAndProof(ctx context.Context, in *types.Acco if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil { return nil, err } + if len(in.Account) == 0 { + return nil, status.Errorf(codes.InvalidArgument, "input account is empty") + } + result, err := rpc.hub.RequestFuture(message.ChainSvc, &message.GetStateAndProof{Account: in.Account, Root: in.Root, Compressed: in.Compressed}, defaultActorTimeout, "rpc.(*AergoRPCService).GetStateAndProof").Result() if err != nil { @@ -715,6 +743,7 @@ func (rpc *AergoRPCService) GetStateAndProof(ctx context.Context, in *types.Acco } // CreateAccount handle rpc request newaccount +// This function is deprecated since aergo v2 func (rpc *AergoRPCService) CreateAccount(ctx context.Context, in *types.Personal) (*types.Account, error) { if err := rpc.checkAuth(ctx, WriteBlockChain); err != nil { return nil, err @@ -780,6 +809,10 @@ func (rpc *AergoRPCService) LockAccount(ctx context.Context, in *types.Personal) if err := rpc.checkAuth(ctx, WriteBlockChain); err != nil { return nil, err } + if in.Account == nil || len(in.Account.Address) == 0 { + return nil, status.Errorf(codes.InvalidArgument, "input account is empty") + } + result, err := rpc.hub.RequestFutureResult(message.AccountsSvc, &message.LockAccount{Account: in.Account, Passphrase: in.Passphrase}, defaultActorTimeout, "rpc.(*AergoRPCService).LockAccount") @@ -802,6 +835,10 @@ func (rpc *AergoRPCService) UnlockAccount(ctx context.Context, in *types.Persona if err := rpc.checkAuth(ctx, WriteBlockChain); err != nil { return nil, err } + if in.Account == nil || len(in.Account.Address) == 0 { + return nil, status.Errorf(codes.InvalidArgument, "input account is empty") + } + result, err := rpc.hub.RequestFutureResult(message.AccountsSvc, &message.UnlockAccount{Account: in.Account, Passphrase: in.Passphrase}, defaultActorTimeout, "rpc.(*AergoRPCService).UnlockAccount") @@ -852,6 +889,10 @@ func (rpc *AergoRPCService) exportAccountWithFormat(ctx context.Context, in *typ if err := rpc.checkAuth(ctx, WriteBlockChain); err != nil { return nil, err } + if in.Account == nil || len(in.Account.Address) == 0 { + return nil, status.Errorf(codes.InvalidArgument, "input account is empty") + } + result, err := rpc.hub.RequestFutureResult(message.AccountsSvc, &message.ExportAccount{Account: in.Account, Pass: in.Passphrase, AsKeystore: asKeystore}, defaultActorTimeout, "rpc.(*AergoRPCService).ExportAccount") @@ -882,6 +923,10 @@ func (rpc *AergoRPCService) SignTX(ctx context.Context, in *types.Tx) (*types.Tx if err := rpc.checkAuth(ctx, WriteBlockChain); err != nil { return nil, err } + if in.Body == nil { + return nil, status.Errorf(codes.InvalidArgument, "input tx is empty") + } + result, err := rpc.hub.RequestFutureResult(message.AccountsSvc, &message.SignTx{Tx: in}, defaultActorTimeout, "rpc.(*AergoRPCService).SignTX") if err != nil { @@ -904,6 +949,10 @@ func (rpc *AergoRPCService) VerifyTX(ctx context.Context, in *types.Tx) (*types. return nil, err } //TODO : verify without account service + if in.Body == nil { + return nil, status.Errorf(codes.InvalidArgument, "input tx is empty") + } + result, err := rpc.hub.RequestFutureResult(message.AccountsSvc, &message.VerifyTx{Tx: in}, defaultActorTimeout, "rpc.(*AergoRPCService).VerifyTX") if err != nil { @@ -956,7 +1005,15 @@ func (rpc *AergoRPCService) NodeState(ctx context.Context, in *types.NodeReq) (* if err := rpc.checkAuth(ctx, ShowNode); err != nil { return nil, err } - timeout := int64(binary.LittleEndian.Uint64(in.Timeout)) + uTimeout, err := utils.ToUint64(in.Timeout) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid timeout value") + } + timeout := int64(uTimeout) + if timeout < 0 || timeout > 1800 { + // even 30 minutes is very big for timeout + timeout = 1800 + } component := string(in.Component) logger.Debug().Str("comp", component).Int64("timeout", timeout).Msg("nodestate") @@ -998,6 +1055,9 @@ func (rpc *AergoRPCService) GetAccountVotes(ctx context.Context, in *types.Accou } result, err := rpc.hub.RequestFuture(message.ChainSvc, &message.GetVote{Addr: in.Value}, defaultActorTimeout, "rpc.(*AergoRPCService).GetAccountVote").Result() + if len(in.Value) == 0 { + return nil, status.Errorf(codes.InvalidArgument, "input address is empty") + } if err != nil { return nil, err } @@ -1036,6 +1096,9 @@ func (rpc *AergoRPCService) GetNameInfo(ctx context.Context, in *types.Name) (*t if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil { return nil, err } + if len(in.Name) == 0 { + return nil, status.Errorf(codes.InvalidArgument, "input name is empty") + } result, err := rpc.hub.RequestFuture(message.ChainSvc, &message.GetNameInfo{Name: in.Name, BlockNo: in.BlockNo}, defaultActorTimeout, "rpc.(*AergoRPCService).GetName").Result() if err != nil { @@ -1055,6 +1118,9 @@ func (rpc *AergoRPCService) GetReceipt(ctx context.Context, in *types.SingleByte if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil { return nil, err } + if len(in.Value) == 0 { + return nil, status.Errorf(codes.InvalidArgument, "input hash is empty") + } result, err := rpc.hub.RequestFuture(message.ChainSvc, &message.GetReceipt{TxHash: in.Value}, defaultActorTimeout, "rpc.(*AergoRPCService).GetReceipt").Result() if err != nil { @@ -1067,10 +1133,29 @@ func (rpc *AergoRPCService) GetReceipt(ctx context.Context, in *types.SingleByte return rsp.Receipt, rsp.Err } +func (rpc *AergoRPCService) GetInternalOperations(ctx context.Context, in *types.BlockNumberParam) (*types.SingleBytes, error) { + if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil { + return nil, err + } + result, err := rpc.hub.RequestFuture(message.ChainSvc, + &message.GetInternalOperations{BlockNo: in.BlockNo}, defaultActorTimeout, "rpc.(*AergoRPCService).GetInternalOperations").Result() + if err != nil { + return nil, err + } + rsp, ok := result.(message.GetInternalOperationsRsp) + if !ok { + return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(result)) + } + return &types.SingleBytes{Value: []byte(rsp.Operations)}, rsp.Err +} + func (rpc *AergoRPCService) GetABI(ctx context.Context, in *types.SingleBytes) (*types.ABI, error) { if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil { return nil, err } + if len(in.Value) == 0 { + return nil, status.Errorf(codes.InvalidArgument, "input address is empty") + } result, err := rpc.hub.RequestFuture(message.ChainSvc, &message.GetABI{Contract: in.Value}, defaultActorTimeout, "rpc.(*AergoRPCService).GetABI").Result() if err != nil { @@ -1087,6 +1172,9 @@ func (rpc *AergoRPCService) QueryContract(ctx context.Context, in *types.Query) if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil { return nil, err } + if len(in.ContractAddress) == 0 { + return nil, status.Errorf(codes.InvalidArgument, "input contract info is empty") + } result, err := rpc.hub.RequestFuture(message.ChainSvc, &message.GetQuery{Contract: in.ContractAddress, Queryinfo: in.Queryinfo}, defaultActorTimeout, "rpc.(*AergoRPCService).QueryContract").Result() if err != nil { @@ -1104,6 +1192,9 @@ func (rpc *AergoRPCService) QueryContractState(ctx context.Context, in *types.St if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil { return nil, err } + if len(in.ContractAddress) == 0 { + return nil, status.Errorf(codes.InvalidArgument, "input contract info is empty") + } result, err := rpc.hub.RequestFuture(message.ChainSvc, &message.GetStateQuery{ContractAddress: in.ContractAddress, StorageKeys: in.StorageKeys, Root: in.Root, Compressed: in.Compressed}, defaultActorTimeout, "rpc.(*AergoRPCService).GetStateQuery").Result() if err != nil { @@ -1239,6 +1330,10 @@ func (rpc *AergoRPCService) GetEnterpriseConfig(ctx context.Context, in *types.E return nil, status.Error(codes.Unavailable, "not supported in public") } + if len(in.Key) == 0 { + return nil, status.Errorf(codes.InvalidArgument, "input key is empty") + } + if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil { return nil, err } diff --git a/rpc/grpcserver_test.go b/rpc/grpcserver_test.go index 25f611f7d..9af249225 100644 --- a/rpc/grpcserver_test.go +++ b/rpc/grpcserver_test.go @@ -7,6 +7,7 @@ package rpc import ( "context" "fmt" + "github.com/aergoio/aergo/v2/types/utils" "math/big" "reflect" "testing" @@ -69,18 +70,12 @@ func init() { mockCtx = &Context{} } -func TestAergoRPCService_GetTX(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - mockMsgHelper := messagemock.NewHelper(ctrl) - mockActorHelper := p2pmock.NewMockActorService(ctrl) +func TestAergoRPCService_GetTX(t *testing.T) { dummyTxBody := types.TxBody{Account: dummyWalletAddress, Amount: new(big.Int).SetUint64(4332).Bytes(), Recipient: dummyWalletAddress2, Payload: dummyPayload} sampleTx := &types.Tx{Hash: dummyTxHash, Body: &dummyTxBody} - mockActorHelper.EXPECT().CallRequestDefaultTimeout(message.MemPoolSvc, gomock.Any()).Return(message.MemPoolGetRsp{}, nil) - mockMsgHelper.EXPECT().ExtractTxFromResponse(gomock.AssignableToTypeOf(message.MemPoolGetRsp{})).Return(sampleTx, nil) + type fields struct { hub *component.ComponentHub actorHelper p2pcommon.ActorService @@ -97,14 +92,28 @@ func TestAergoRPCService_GetTX(t *testing.T) { want *types.Tx wantErr bool }{ - {name: "T00", args: args{ctx: mockCtx, in: &types.SingleBytes{Value: append(dummyTxHash, 'b', 'd')}}, fields: fields{hubStub, mockActorHelper, mockMsgHelper}, + {name: "TNormal", args: args{ctx: mockCtx, in: &types.SingleBytes{Value: dummyTxHash}}, + want: &types.Tx{Hash: dummyTxHash, Body: &dummyTxBody}, wantErr: false}, + // TODO the malformed hash is allowed until v2.8.x , but should return error at v2.9.0 + {name: "TMalformedHash", args: args{ctx: mockCtx, in: &types.SingleBytes{Value: append(dummyTxHash, 'b', 'd')}}, want: &types.Tx{Hash: dummyTxHash, Body: &dummyTxBody}, wantErr: false}, - // TODO: Add test cases. + {name: "TEmptyHash", args: args{ctx: mockCtx, in: &types.SingleBytes{Value: []byte{}}}, + want: &types.Tx{Hash: dummyTxHash, Body: &dummyTxBody}, wantErr: false}, + {name: "TNilHash", args: args{ctx: mockCtx, in: &types.SingleBytes{Value: nil}}, + want: nil, wantErr: true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockMsgHelper := messagemock.NewHelper(ctrl) + mockActorHelper := p2pmock.NewMockActorService(ctrl) + mockActorHelper.EXPECT().CallRequestDefaultTimeout(message.MemPoolSvc, gomock.Any()).Return(message.MemPoolGetRsp{}, nil).AnyTimes() + mockMsgHelper.EXPECT().ExtractTxFromResponse(gomock.AssignableToTypeOf(message.MemPoolGetRsp{})).Return(sampleTx, nil).AnyTimes() + rpc := &AergoRPCService{ - hub: tt.fields.hub, actorHelper: mockActorHelper, msgHelper: mockMsgHelper, + hub: hubStub, actorHelper: mockActorHelper, msgHelper: mockMsgHelper, } got, err := rpc.GetTX(tt.args.ctx, tt.args.in) if (err != nil) != tt.wantErr { @@ -118,6 +127,63 @@ func TestAergoRPCService_GetTX(t *testing.T) { } } +func TestAergoRPCService_NodeState(t *testing.T) { + var emptyMap = []byte("{}") + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockMsgHelper := messagemock.NewHelper(ctrl) + mockActorHelper := p2pmock.NewMockActorService(ctrl) + + dummyResult := make(map[string]*component.CompStatRsp) + mockActorHelper.EXPECT().CallRequestDefaultTimeout(gomock.Any(), gomock.Any()).Return(dummyResult, nil).AnyTimes() + type fields struct { + hub *component.ComponentHub + actorHelper p2pcommon.ActorService + msgHelper message.Helper + } + type args struct { + ctx context.Context + in *types.NodeReq + } + tests := []struct { + name string + fields fields + args args + want *types.SingleBytes + wantErr bool + }{ + {name: "normal", args: args{ctx: mockCtx, + in: &types.NodeReq{Timeout: utils.ToByteArrayOrEmpty(int64(5)), Component: nil}}, fields: fields{hubStub, mockActorHelper, mockMsgHelper}, + want: &types.SingleBytes{Value: emptyMap}, wantErr: false}, + {name: "nilTime", args: args{ctx: mockCtx, + in: &types.NodeReq{Timeout: nil, Component: nil}}, fields: fields{hubStub, mockActorHelper, mockMsgHelper}, + want: &types.SingleBytes{Value: emptyBytes}, wantErr: true}, + {name: "shortData", args: args{ctx: mockCtx, + in: &types.NodeReq{Timeout: []byte("short"), Component: nil}}, fields: fields{hubStub, mockActorHelper, mockMsgHelper}, + want: &types.SingleBytes{Value: emptyMap}, wantErr: true}, + {name: "wrongComponent", args: args{ctx: mockCtx, + in: &types.NodeReq{Timeout: utils.ToByteArrayOrEmpty(int64(5)), Component: []byte("nope")}}, fields: fields{hubStub, mockActorHelper, mockMsgHelper}, + want: &types.SingleBytes{Value: emptyBytes}, wantErr: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + rpc := &AergoRPCService{ + hub: tt.fields.hub, actorHelper: mockActorHelper, msgHelper: mockMsgHelper, + } + got, err := rpc.NodeState(tt.args.ctx, tt.args.in) + if (err != nil) != tt.wantErr { + t.Errorf("AergoRPCService.GetTX() error = %v, wantErr %v", err, tt.wantErr) + return + } + // do not check return value when error is expected + if !tt.wantErr && !reflect.DeepEqual(got, tt.want) { + t.Errorf("AergoRPCService.GetTX() = %v, want %v", got, tt.want) + } + }) + } +} + type FutureStub struct { actor.Future dumbResult interface{} @@ -130,3 +196,44 @@ func (fs *FutureStub) Result() interface{} { func NewFutureStub(result interface{}) FutureStub { return FutureStub{dumbResult: result} } + +func TestAergoRPCService_GetBlockIncompleteArg(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockMsgHelper := messagemock.NewHelper(ctrl) + mockActorHelper := p2pmock.NewMockActorService(ctrl) + + dummyResult := make(map[string]*component.CompStatRsp) + mockActorHelper.EXPECT().CallRequestDefaultTimeout(gomock.Any(), gomock.Any()).Return(dummyResult, nil).AnyTimes() + type fields struct { + hub *component.ComponentHub + actorHelper p2pcommon.ActorService + msgHelper message.Helper + } + type args struct { + ctx context.Context + in *types.SingleBytes + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + {name: "nilValue", fields: fields{hubStub, mockActorHelper, mockMsgHelper}, + args: args{mockCtx, &types.SingleBytes{}}, wantErr: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + rpc := &AergoRPCService{ + hub: tt.fields.hub, actorHelper: mockActorHelper, msgHelper: mockMsgHelper, + } + _, err := rpc.GetBlock(tt.args.ctx, tt.args.in) + if (err != nil) != tt.wantErr { + t.Errorf("GetBlock() error = %v, wantErr %v", err, tt.wantErr) + return + } + }) + } +} diff --git a/rpc/rpc.go b/rpc/rpc.go index 64636d221..b55c5b78a 100644 --- a/rpc/rpc.go +++ b/rpc/rpc.go @@ -48,6 +48,7 @@ type RPC struct { grpcWebServer *grpcweb.WrappedGrpcServer actualServer *AergoRPCService httpServer *http.Server + Listener net.Listener ca types.ChainAccessor version string @@ -277,6 +278,7 @@ func (ns *RPC) serveGRPC(l net.Listener, server *grpc.Server) { switch err { case cmux.ErrListenerClosed: // Server killed, usually by ctrl-c signal + ns.Info().Msg("Listener closed") default: panic(err) } @@ -286,7 +288,12 @@ func (ns *RPC) serveGRPC(l net.Listener, server *grpc.Server) { // Serve HTTP server over TCP func (ns *RPC) serveHTTP(l net.Listener, server *http.Server) { if err := server.Serve(l); err != nil && err != http.ErrServerClosed { - panic(err) + switch err { + case cmux.ErrListenerClosed: + ns.Info().Msg("Listener closed") + default: + panic(err) + } } } @@ -304,6 +311,8 @@ func (ns *RPC) serve() { panic(err) } + ns.Listener = l + // Setup TCP multiplexer tcpm := cmux.New(l) diff --git a/state/block.go b/state/block.go index 91d28f8ad..2cfd9a80e 100644 --- a/state/block.go +++ b/state/block.go @@ -1,6 +1,7 @@ package state import ( + "strings" "math/big" "github.com/aergoio/aergo/v2/consensus" @@ -15,6 +16,7 @@ type BlockState struct { *statedb.StateDB BpReward big.Int // final bp reward, increment when tx executes receipts types.Receipts + internalOps []string CCProposal *consensus.ConfChangePropose prevBlockHash []byte consensus []byte // Consensus Header @@ -80,6 +82,17 @@ func (bs *BlockState) SetConsensus(ch []byte) { bs.consensus = ch } +func (bs *BlockState) AddInternalOps(txops string) { + bs.internalOps = append(bs.internalOps, txops) +} + +func (bs *BlockState) InternalOps() string { + if bs == nil || len(bs.internalOps) == 0 { + return "" + } + return "[" + strings.Join(bs.internalOps, ",") + "]" +} + func (bs *BlockState) AddReceipt(r *types.Receipt) error { if len(r.Events) > 0 { rBloom := bloom.New(types.BloomBitBits, types.BloomHashKNum) diff --git a/state/chain.go b/state/chain.go index 72560d7cd..5b1e354f2 100644 --- a/state/chain.go +++ b/state/chain.go @@ -20,11 +20,14 @@ var ( // ChainStateDB manages statedb and additional informations about blocks like a state root hash type ChainStateDB struct { sync.RWMutex - states *statedb.StateDB - store db.DB - testmode bool + states *statedb.StateDB + store db.DB + testmode bool + MaintenanceEvent MaintenanceEventHandler } +type MaintenanceEventHandler func(event db.CompactionEvent) + // NewChainStateDB creates instance of ChainStateDB func NewChainStateDB() *ChainStateDB { return &ChainStateDB{} @@ -43,7 +46,7 @@ func (sdb *ChainStateDB) Clone() *ChainStateDB { } // Init initialize database and load statedb of latest block -func (sdb *ChainStateDB) Init(dbType string, dataDir string, bestBlock *types.Block, test bool) error { +func (sdb *ChainStateDB) Init(dbType string, dataDir string, bestBlock *types.Block, test bool, opts []db.Option) error { sdb.Lock() defer sdb.Unlock() @@ -51,7 +54,25 @@ func (sdb *ChainStateDB) Init(dbType string, dataDir string, bestBlock *types.Bl // init db if sdb.store == nil { dbPath := common.PathMkdirAll(dataDir, statedb.StateName) - sdb.store = db.NewDB(db.ImplType(dbType), dbPath) + opts = append(opts, db.Option{ + Name: db.OptCompactionEventHandler, + Value: func(event db.CompactionEvent) { + if event.Start { + logger.Info().Str("reason", event.Reason).Int("fromlevel", event.Level). + Int("nextlevel", event.Level).Int("splits", event.NumSplits).Msg("sdb compaction started") + } else { + logger.Info().Str("reason", event.Reason).Int("fromlevel", event.Level). + Int("nextlevel", event.Level).Int("splits", event.NumSplits).Msg("sdb compaction complete") + } + if sdb.MaintenanceEvent != nil { + // fire maintenance event only for manual maintenance event + if event.Reason == "maintenance" { + sdb.MaintenanceEvent(event) + } + } + }, + }) + sdb.store = db.NewDB(db.ImplType(dbType), dbPath, opts...) } // init trie diff --git a/state/statedb/dump.go b/state/statedb/dump.go index 61fe85972..6272ba699 100644 --- a/state/statedb/dump.go +++ b/state/statedb/dump.go @@ -2,7 +2,6 @@ package statedb import ( "encoding/json" - "github.com/aergoio/aergo/v2/internal/enc/base58" "github.com/aergoio/aergo/v2/types" ) @@ -97,3 +96,70 @@ func (sdb *StateDB) RawDump() (Dump, error) { return dump, nil } + +type RawDumpConfig struct { + ShowCode bool +} + +func DefaultConfig() RawDumpConfig { + return RawDumpConfig{ + ShowCode: false, + } +} + +type Processor func(idx int64, accountId types.AccountID, account *DumpAccount) error + +// RawDumpWith iterate accounts information and let the processor handle them. +func (sdb *StateDB) RawDumpWith(config RawDumpConfig, processor Processor) error { + var err error + skipCode := []byte("(skipped)") + + self := sdb.Clone() + + // write accounts + for idx, key := range self.Trie.GetKeys() { + var st *types.State + var code []byte + storage := make(map[types.AccountID][]byte) + + // load account state + aid := types.AccountID(types.ToHashID(key)) + st, err = sdb.getState(aid) + if err != nil { + return err + } + if len(st.GetCodeHash()) > 0 { + if config.ShowCode { + // load code + loadData(self.Store, st.GetCodeHash(), &code) + } else { + code = skipCode + } + + // load contract state + cs, err := OpenContractState(key, st, self) + if err != nil { + return err + } + + // load storage + for _, key := range cs.storage.Trie.GetKeys() { + data, _ := cs.getInitialData(key) + aid := types.AccountID(types.ToHashID(key)) + storage[aid] = data + } + } + + dumpAccount := DumpAccount{ + State: st, + Code: code, + Storage: storage, + } + err = processor(int64(idx), aid, &dumpAccount) + if err != nil { + return err + } + } + + return nil +} diff --git a/state/statedb/dump_test.go b/state/statedb/dump_test.go index 9aa208731..b9660e92f 100644 --- a/state/statedb/dump_test.go +++ b/state/statedb/dump_test.go @@ -1,6 +1,8 @@ package statedb import ( + "encoding/json" + "os" "testing" "github.com/aergoio/aergo/v2/internal/common" @@ -141,3 +143,36 @@ func TestDumpStorage(t *testing.T) { "root": "9bQx52KdKfMkVdakKEWQLBscgkMiFwd2Zx2hr7u1GYam" }`) } + +func TestStateDB_RawDumpWith(t *testing.T) { + initTest(t) + defer deinitTest() + + // set account state + for _, v := range testStates { + err := stateDB.PutState(testAccount, v) + require.NoError(t, err, "failed to put state") + } + stateDB.Update() + stateDB.Commit() + + W := os.Stdout + processor := func(idx int64, accountId types.AccountID, account *DumpAccount) error { + if idx > 0 { + W.Write([]byte(",\n")) + } + accountJson, err := json.MarshalIndent(account, "", "\t") + if err != nil { + return err + } + W.Write([]byte("\"")) + W.Write([]byte(accountId.String())) + W.Write([]byte("\":")) + W.Write(accountJson) + return nil + } + + W.Write([]byte("{\n")) + stateDB.RawDumpWith(DefaultConfig(), processor) + W.Write([]byte("\n}\n")) +} diff --git a/syncer/blockfetcher.go b/syncer/blockfetcher.go index ac753c2d4..1be988573 100644 --- a/syncer/blockfetcher.go +++ b/syncer/blockfetcher.go @@ -437,7 +437,7 @@ func (bf *BlockFetcher) searchCandidateTask() (*FetchTask, error) { task := &FetchTask{count: end - start, hashes: hashSet.Hashes[start:end], startNo: hashSet.StartNo + uint64(start), retry: 0} - logger.Debug().Uint64("StartNo", task.startNo).Int("count", task.count).Msg("add fetchtask") + logger.Trace().Uint64("StartNo", task.startNo).Int("count", task.count).Msg("add fetchtask") bf.pendingQueue.PushBack(task) diff --git a/tests/common.sh b/tests/common.sh index 95029365f..3fa1bd423 100644 --- a/tests/common.sh +++ b/tests/common.sh @@ -2,7 +2,7 @@ start_nodes() { if [ "$consensus" == "sbp" ]; then # open the aergo node in testmode - ../bin/aergosvr --testmode --home ./aergo-files > logs 2> logs & + ../bin/aergosvr --testmode --home ./aergo-files >> logs 2>> logs & pid=$! else # open the 5 nodes @@ -13,8 +13,8 @@ start_nodes() { ../bin/aergosvr --home ./node3 >> logs3 2>> logs3 & pid3=$! # nodes 4 and 5 use a previous version of aergosvr for backwards compatibility check - docker run --name aergo-test-node4 --rm --net=host -v $(pwd)/node4:/aergo aergo/node:2.6.1 aergosvr --home /aergo >> logs4 2>> logs4 & - docker run --name aergo-test-node5 --rm --net=host -v $(pwd)/node5:/aergo aergo/node:2.6.1 aergosvr --home /aergo >> logs5 2>> logs5 & + docker run --name aergo-test-node4 --rm --net=host -v $(pwd)/node4:/aergo aergo/node:2.8.1 aergosvr --home /aergo >> logs4 2>> logs4 & + docker run --name aergo-test-node5 --rm --net=host -v $(pwd)/node5:/aergo aergo/node:2.8.1 aergosvr --home /aergo >> logs5 2>> logs5 & fi } @@ -239,6 +239,26 @@ get_receipt() { rm receipt{2..5}.json } +get_internal_operations() { + txhash=$1 + # do not stop on errors + set +e + + output=$(../bin/aergocli operations $txhash --port $query_port 2>&1 > internal_operations.json) + + #echo "output: $output" + + if [[ $output == *"No internal operations found for this transaction"* ]]; then + echo -n "" > internal_operations.json + elif [[ -n $output ]]; then + echo "Error getting internal operations: $output" + exit 1 + fi + + # stop on errors + set -e +} + assert_equals() { local var="$1" local expected="$2" diff --git a/tests/config-node1.toml b/tests/config-node1.toml index 561ff7099..92edc0bc4 100644 --- a/tests/config-node1.toml +++ b/tests/config-node1.toml @@ -48,3 +48,4 @@ name="bp01" v2 = "0" v3 = "10000" v4 = "10000" +v5 = "10000" \ No newline at end of file diff --git a/tests/config-node2.toml b/tests/config-node2.toml index 5ad16fae7..65a7bb09e 100644 --- a/tests/config-node2.toml +++ b/tests/config-node2.toml @@ -48,3 +48,4 @@ name="bp02" v2 = "0" v3 = "10000" v4 = "10000" +v5 = "10000" diff --git a/tests/config-node3.toml b/tests/config-node3.toml index e0e6fea0b..a82b67f29 100644 --- a/tests/config-node3.toml +++ b/tests/config-node3.toml @@ -10,6 +10,7 @@ nstls = false nscert = "" nskey = "" nsallowcors = false +log_internal_operations = true [p2p] netprotocoladdr = "127.0.0.1" @@ -48,3 +49,4 @@ name="bp03" v2 = "0" v3 = "10000" v4 = "10000" +v5 = "10000" diff --git a/tests/config-node4.toml b/tests/config-node4.toml index 5abbe5eb6..6f45285ad 100644 --- a/tests/config-node4.toml +++ b/tests/config-node4.toml @@ -48,3 +48,4 @@ name="bp04" v2 = "0" v3 = "10000" v4 = "10000" +v5 = "10000" diff --git a/tests/config-node5.toml b/tests/config-node5.toml index 4167fa4ec..f7629df42 100644 --- a/tests/config-node5.toml +++ b/tests/config-node5.toml @@ -48,3 +48,4 @@ name="bp05" v2 = "0" v3 = "10000" v4 = "10000" +v5 = "10000" diff --git a/tests/config-sbp.toml b/tests/config-sbp.toml index 10b3304d7..026987fd5 100644 --- a/tests/config-sbp.toml +++ b/tests/config-sbp.toml @@ -18,6 +18,7 @@ nscert = "" nskey = "" nscacert = "" nsallowcors = false +log_internal_operations = true [p2p] # Set address and port to which the inbound peers connect, and don't set loopback address or private network unless used in local network @@ -82,3 +83,4 @@ enablelocalconf = "false" v2 = "0" v3 = "10000" v4 = "10000" +v5 = "10000" diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 97e55b510..9733ee2c4 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -78,6 +78,13 @@ elif [ "$consensus" == "raft" ]; then config_files=("./node1/config.toml" "./node2/config.toml" "./node3/config.toml" "./node4/config.toml" "./node5/config.toml") fi +# define which port is used for queries +if [ "$consensus" == "sbp" ]; then + query_port="7845" +else + query_port="9845" +fi + echo "" echo "starting nodes..." start_nodes @@ -93,8 +100,8 @@ function set_version() { echo "now test hardfork version $version" # get the current block number / height block_no=$(../bin/aergocli blockchain | jq .height | sed 's/"//g') - # increment 2 numbers - block_no=$((block_no+2)) + # increment 3 numbers + block_no=$((block_no+3)) # terminate the server process(es) stop_nodes # save the hardfork config on the config file(s) @@ -135,6 +142,7 @@ function check() { # make these variables accessible to the called scripts export consensus +export query_port # create the account used on tests echo "creating user account..." @@ -142,8 +150,9 @@ echo "creating user account..." # run the integration tests - version 2 if [ "$short_tests" = true ]; then - check ./test-contract-deploy.sh + check ./test-aergocli.sh else + check ./test-aergocli.sh check ./test-gas-deploy.sh check ./test-gas-op.sh check ./test-gas-bf.sh @@ -160,8 +169,9 @@ set_version 3 # run the integration tests - version 3 if [ "$short_tests" = true ]; then - check ./test-contract-deploy.sh + check ./test-aergocli.sh else + check ./test-aergocli.sh check ./test-max-call-depth.sh check ./test-gas-deploy.sh check ./test-gas-op.sh @@ -172,6 +182,7 @@ else check ./test-pcall-events.sh check ./test-transaction-types.sh check ./test-name-service.sh + check ./test-internal-operations.sh fi # change the hardfork version @@ -179,8 +190,32 @@ set_version 4 # run the integration tests - version 4 if [ "$short_tests" = true ]; then + check ./test-aergocli.sh +else + check ./test-aergocli.sh + check ./test-max-call-depth.sh + check ./test-gas-deploy.sh + check ./test-gas-op.sh + check ./test-gas-bf.sh + check ./test-gas-verify-proof.sh + check ./test-gas-per-function-v4.sh check ./test-contract-deploy.sh + check ./test-pcall-events.sh + check ./test-transaction-types.sh + check ./test-name-service.sh + check ./test-multicall.sh + check ./test-disabled-functions.sh + check ./test-internal-operations.sh +fi + +# change the hardfork version +set_version 5 + +# run the integration tests - version 5 +if [ "$short_tests" = true ]; then + check ./test-aergocli.sh else + check ./test-aergocli.sh check ./test-max-call-depth.sh check ./test-gas-deploy.sh check ./test-gas-op.sh diff --git a/tests/test-aergocli.sh b/tests/test-aergocli.sh new file mode 100755 index 000000000..54637ff3c --- /dev/null +++ b/tests/test-aergocli.sh @@ -0,0 +1,520 @@ +set -e +source common.sh + +fork_version=$1 + +# Test network commands +echo "--- Testing network commands ---" + +# Test getpeers +echo -n "Testing getpeers... " +peers=$(../bin/aergocli getpeers) +if [ -z "$peers" ]; then + echo "ERROR: Failed to get peers" + exit 1 +fi +echo "✓" + +# Test getconsensusinfo +echo -n "Testing getconsensusinfo... " +consensus_info=$(../bin/aergocli getconsensusinfo) +if [ -z "$consensus_info" ] || ! echo "$consensus_info" | jq . >/dev/null 2>&1; then + echo "ERROR: Failed to get consensus info" + exit 1 +fi +echo "✓" + +# Test system commands +echo "--- Testing system commands ---" + +# Test serverinfo +echo -n "Testing serverinfo... " +server_info=$(../bin/aergocli serverinfo) +if [ -z "$server_info" ] || ! echo "$server_info" | jq . >/dev/null 2>&1; then + echo "ERROR: Failed to get server info" + exit 1 +fi +echo "✓" + +# Test chaininfo +echo -n "Testing chaininfo... " +chain_info=$(../bin/aergocli chaininfo) +if [ -z "$chain_info" ] || ! echo "$chain_info" | jq . >/dev/null 2>&1; then + echo "ERROR: Failed to get chain info" + exit 1 +fi +echo "✓" + +# Test chainstat +echo -n "Testing chainstat... " +chain_stat=$(../bin/aergocli chainstat) +if [ -z "$chain_stat" ] || ! echo "$chain_stat" | jq . >/dev/null 2>&1; then + echo "ERROR: Failed to get chain stats" + exit 1 +fi +echo "✓" + +# Test utility commands +echo "--- Testing utility commands ---" + +# Test version +echo -n "Testing version... " +version=$(../bin/aergocli version) +if [ -z "$version" ]; then + echo "ERROR: Failed to get version" + exit 1 +fi +echo "✓" + +# Test keygen +echo -n "Testing keygen... " +key_info=$(../bin/aergocli keygen --password bmttest) +if [ -z "$key_info" ]; then + echo "ERROR: Failed to generate key" + exit 1 +fi +echo "✓" + +# Test metric +echo -n "Testing metric... " +metric_info=$(../bin/aergocli metric) +if [ -z "$metric_info" ]; then + echo "ERROR: Failed to get metrics" + exit 1 +fi +echo "✓" + +# Test account commands +echo "--- Testing account commands ---" + +# Test account new +echo -n "Testing account new... " +account=$(../bin/aergocli account new --keystore . --password bmttest | grep -o "Am.*") +if [ -z "$account" ]; then + echo "ERROR: Failed to create new account" + exit 1 +fi +echo "✓" + +# Test account list +echo -n "Testing account list... " +accounts=$(../bin/aergocli account list --keystore .) +if [[ ! "$accounts" == *"$account"* ]]; then + echo "ERROR: Newly created account not found in account list" + exit 1 +fi +echo "✓" + +# Test account import (using existing test data) +echo -n "Testing account import... " +../bin/aergocli account import --keystore . --password bmttest --if 47zh1byk8MqWkQo5y8dvbrex99ZMdgZqfydar7w2QQgQqc7YrmFsBuMeF1uHWa5TwA1ZwQ7V6 >/dev/null 2>&1 +echo "✓" + +# Test blockchain commands +echo "--- Testing blockchain commands ---" + +# Test blockchain info +echo -n "Testing blockchain info... " +chain_info=$(../bin/aergocli blockchain) +if [ -z "$chain_info" ] || ! echo "$chain_info" | jq . >/dev/null 2>&1; then + echo "ERROR: Failed to get blockchain info" + exit 1 +fi +echo "✓" + +# Test getblock +echo -n "Testing getblock... " +block=$(../bin/aergocli getblock --number 1) +if [ -z "$block" ] || ! echo "$block" | jq . >/dev/null 2>&1; then + echo "ERROR: Failed to get block 1" + exit 1 +fi +echo "✓" + +# Test getstate +echo -n "Testing getstate... " +state=$(../bin/aergocli getstate --address AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R) +if [ -z "$state" ] || ! echo "$state" | jq . >/dev/null 2>&1; then + echo "ERROR: Failed to get state for test account" + exit 1 +fi +echo "✓" + +# Test transaction commands +echo "--- Testing transaction commands ---" + +# Test sendtx +echo -n "Testing sendtx... " +txhash=$(../bin/aergocli --keystore . --password bmttest \ + sendtx --from AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R \ + --to AmQ2tS46doLfqsH4vy7PXmvGn7paec8wgqPWmGrcJKiLZADrJcME \ + --amount 1aergo | jq .hash | sed 's/"//g') + +if [ -z "$txhash" ] || [ ${#txhash} -lt 43 ]; then + echo "ERROR: Failed to send transaction" + exit 1 +fi +echo "✓ txn hash: $txhash" + +# Test gettx +echo -n "Testing gettx... " +sleep 1 +transaction=$(../bin/aergocli gettx $txhash) +if [ -z "$transaction" ] || ! echo "$transaction" | jq . >/dev/null 2>&1; then + echo "ERROR: Failed to get transaction" + exit 1 +fi +echo "✓" + +# Wait for receipt +get_receipt $txhash + +# Test receipt +echo -n "Testing receipt... " +receipt=$(../bin/aergocli receipt get $txhash) +if [ -z "$receipt" ] || ! echo "$receipt" | jq . >/dev/null 2>&1; then + echo "ERROR: Failed to get receipt" + exit 1 +fi +echo "✓" + +# Test contract commands +echo "--- Testing contract commands ---" + +# Test contract deploy +echo -n "Testing contract deploy... " +deploy ../contract/vm_dummy/test_files/all_types.lua +if [ -z "$txhash" ] || [ ${#txhash} -lt 43 ]; then + echo "ERROR: Failed to deploy all_types.lua contract" + exit 1 +fi +echo "✓ txn hash: $txhash" + +# Wait for receipt +echo -n "Waiting for receipt... " +get_receipt $txhash +status=$(cat receipt.json | jq .status | sed 's/\"//g') +contract_address=$(cat receipt.json | jq .contractAddress | sed 's/\"//g') +if [ "$status" != "CREATED" ]; then + echo "ERROR: contract deployment failed with status: $status" + exit 1 +fi +echo "✓ deployed to: $contract_address" + +# Test contract abi +echo -n "Testing contract abi... " +abi=$(../bin/aergocli contract abi $contract_address) +if [ -z "$abi" ] || ! echo "$abi" | jq . >/dev/null 2>&1; then + echo "ERROR: Failed to get contract ABI" + exit 1 +fi +echo "✓" + +# Test contract calls (3 different types) +echo "--- Testing contract calls ---" + +# Capture initial block height for event testing +initial_block_height=$(../bin/aergocli blockchain | jq '.height') + +# Test value_set call +echo -n "Testing value_set call... " +txhash=$(../bin/aergocli --keystore . --password bmttest \ + contract call AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R \ + $contract_address value_set '["testname"]' | jq .hash | sed 's/\"//g') + +if [ -z "$txhash" ] || [ ${#txhash} -lt 43 ]; then + echo "ERROR: Failed to call value_set function" + exit 1 +fi +echo "✓ txn hash: $txhash" + +echo -n "Waiting for receipt... " +get_receipt $txhash +status=$(cat receipt.json | jq .status | sed 's/\"//g') +if [ "$status" != "SUCCESS" ]; then + echo "ERROR: value_set function call failed with status: $status" + exit 1 +fi +echo "✓" + +# Test array_set call +echo -n "Testing array_set call... " +txhash=$(../bin/aergocli --keystore . --password bmttest \ + contract call AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R \ + $contract_address array_append '["testarray"]' | jq .hash | sed 's/\"//g') + +if [ -z "$txhash" ] || [ ${#txhash} -lt 43 ]; then + echo "ERROR: Failed to call array_append function" + exit 1 +fi +echo "✓ txn hash: $txhash" + +echo -n "Waiting for receipt... " +get_receipt $txhash +status=$(cat receipt.json | jq .status | sed 's/\"//g') +if [ "$status" != "SUCCESS" ]; then + echo "ERROR: array_append function call failed with status: $status" + exit 1 +fi +echo "✓" + +# Test map_set call +echo -n "Testing map_set call... " +txhash=$(../bin/aergocli --keystore . --password bmttest \ + contract call AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R \ + $contract_address map_set '["testkey", "testvalue"]' | jq .hash | sed 's/\"//g') + +if [ -z "$txhash" ] || [ ${#txhash} -lt 43 ]; then + echo "ERROR: Failed to call map_set function" + exit 1 +fi +echo "✓ txn hash: $txhash" + +echo -n "Waiting for receipt... " +get_receipt $txhash +status=$(cat receipt.json | jq .status | sed 's/\"//g') +if [ "$status" != "SUCCESS" ]; then + echo "ERROR: map_set function call failed with status: $status" + exit 1 +fi +echo "✓" + +# Test contract queries (3 different types) +echo "--- Testing contract queries ---" + +# Test value_get query +echo -n "Testing value_get query... " +../bin/aergocli contract query $contract_address value_get '[]' > query_result.txt 2>&1 +query_exit_code=$? +if [ $query_exit_code -ne 0 ]; then + echo "ERROR: value_get query failed with exit code $query_exit_code." + cat query_result.txt + exit 1 +else + query_result=$(cat query_result.txt) + if [ -z "$query_result" ]; then + echo "ERROR: value_get query returned empty result" + exit 1 + else + cleaned_result=$(echo "$query_result" | sed 's/"//g' | sed 's/\\//g' | sed 's/value://g') + assert_equals "$cleaned_result" "testname" + echo "✓" + fi +fi + +# Test array_get query +echo -n "Testing array_get query... " +../bin/aergocli contract query $contract_address array_get '[1]' > query_result.txt 2>&1 +query_exit_code=$? +if [ $query_exit_code -ne 0 ]; then + echo "ERROR: array_get query failed with exit code $query_exit_code." + cat query_result.txt + exit 1 +else + query_result=$(cat query_result.txt) + if [ -z "$query_result" ]; then + echo "ERROR: array_get query returned empty result" + exit 1 + else + cleaned_result=$(echo "$query_result" | sed 's/"//g' | sed 's/\\//g' | sed 's/value://g') + assert_equals "$cleaned_result" "testarray" + echo "✓" + fi +fi + +# Test map_get query +echo -n "Testing map_get query... " +../bin/aergocli contract query $contract_address map_get '["testkey"]' > query_result.txt 2>&1 +query_exit_code=$? +if [ $query_exit_code -ne 0 ]; then + echo "ERROR: map_get query failed with exit code $query_exit_code." + cat query_result.txt + exit 1 +else + query_result=$(cat query_result.txt) + if [ -z "$query_result" ]; then + echo "ERROR: map_get query returned empty result" + exit 1 + else + cleaned_result=$(echo "$query_result" | sed 's/"//g' | sed 's/\\//g' | sed 's/value://g') + assert_equals "$cleaned_result" "testvalue" + echo "✓" + fi +fi + +# Test contract state queries (3 different state variables) +echo "--- Testing contract state queries ---" + +# Test statequery for name (single value) +echo -n "Testing statequery for name... " +../bin/aergocli contract statequery $contract_address name > state_result.txt 2>&1 +state_exit_code=$? +if [ $state_exit_code -ne 0 ]; then + echo "ERROR: State query for name failed with exit code $state_exit_code." + cat state_result.txt + exit 1 +else + state_result=$(cat state_result.txt) + if [ -z "$state_result" ]; then + echo "ERROR: State query for name returned empty result" + exit 1 + else + cleaned_result=$(echo "$state_result" | sed 's/"//g' | sed 's/\\//g' | sed 's/value://g') + assert_equals "$cleaned_result" "testname" + echo "✓" + fi +fi + +# Test statequery for list (array) +echo -n "Testing statequery for list... " +../bin/aergocli contract statequery $contract_address list 1 > state_result.txt 2>&1 +state_exit_code=$? +if [ $state_exit_code -ne 0 ]; then + echo "ERROR: State query for list failed with exit code $state_exit_code." + cat state_result.txt + exit 1 +else + state_result=$(cat state_result.txt) + if [ -z "$state_result" ]; then + echo "ERROR: State query for list returned empty result" + exit 1 + else + cleaned_result=$(echo "$state_result" | sed 's/"//g' | sed 's/\\//g' | sed 's/value://g') + assert_equals "$cleaned_result" "testarray" + echo "✓" + fi +fi + +# Test statequery for values (map) +echo -n "Testing statequery for values... " +../bin/aergocli contract statequery $contract_address values testkey > state_result.txt 2>&1 +state_exit_code=$? +if [ $state_exit_code -ne 0 ]; then + echo "ERROR: State query for values failed with exit code $state_exit_code." + cat state_result.txt + exit 1 +else + state_result=$(cat state_result.txt) + if [ -z "$state_result" ]; then + echo "ERROR: State query for values returned empty result" + exit 1 + else + cleaned_result=$(echo "$state_result" | sed 's/"//g' | sed 's/\\//g' | sed 's/value://g') + assert_equals "$cleaned_result" "testvalue" + echo "✓" + fi +fi + +# Test name service commands +echo "--- Testing name service commands ---" + +# use a different account name for each hardfork +account_name="testuserver$fork_version" + +# Test name new +echo -n "Testing name new... " +name_txhash=$(../bin/aergocli --keystore . --password bmttest \ + name new --from AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R \ + --name $account_name | jq .hash | sed 's/"//g') + +if [ -z "$name_txhash" ] || [ ${#name_txhash} -lt 43 ]; then + echo "ERROR: Failed to register name" + exit 1 +fi +echo "✓ txn hash: $name_txhash" + +# Wait for receipt +echo -n "Waiting for receipt... " +get_receipt $name_txhash +status=$(cat receipt.json | jq .status | sed 's/"//g') +if [ "$status" != "SUCCESS" ]; then + echo "ERROR: name registration failed with status: $status" + exit 1 +fi +echo "✓" + +# Test event command with initial block height +echo -n "Testing event command... " +events=$(../bin/aergocli event list --address $contract_address --start $initial_block_height) +if [ -z "$events" ]; then + echo "ERROR: No events found from block $initial_block_height" + exit 1 +fi + +# Save events to a file for parsing +echo "$events" > events.json + +# Since events are returned as separate JSON objects (not an array), we need to parse them differently +# Split events into individual objects and count them +event_count=0 +event_names="" + +# Process the events output line by line, handling multi-line JSON objects +while IFS= read -r line; do + if [[ "$line" == "{"* ]]; then + # Start of a new JSON object + current_event="$line" + elif [[ "$line" == "}"* ]]; then + # End of JSON object + current_event="$current_event +$line" + + # Parse this complete event + if echo "$current_event" | jq . >/dev/null 2>&1; then + event_count=$((event_count + 1)) + + # Extract event name + event_name=$(echo "$current_event" | jq -r .eventName) + contract_addr=$(echo "$current_event" | jq -r .contractAddress) + + # Validate required fields + if [ "$event_name" = "null" ] || [ "$contract_addr" = "null" ]; then + echo "ERROR: Event missing required fields: $current_event" + exit 1 + fi + + # Verify contract address matches + if [ "$contract_addr" != "$contract_address" ]; then + echo "ERROR: Event contract address mismatch. Expected: $contract_address, Got: $contract_addr" + exit 1 + fi + + # Collect event names + if [ -z "$event_names" ]; then + event_names="$event_name" + else + event_names="$event_names +$event_name" + fi + else + echo "ERROR: Invalid JSON event: $current_event" + exit 1 + fi + + current_event="" + else + # Middle of JSON object + current_event="$current_event +$line" + fi +done <<< "$events" + +# Check event count +if [ "$event_count" -ne 3 ]; then + echo "ERROR: Expected 3 events, but found $event_count" + exit 1 +fi + +# Check event names in order +expected_events="value_set +array_append +map_set" + +if [ "$event_names" != "$expected_events" ]; then + echo "ERROR: Event names don't match expected sequence" + echo "Expected: value_set, array_append, map_set" + echo "Actual: $(echo "$event_names" | tr '\n' ', ' | sed 's/,$//')" + exit 1 +fi + +echo "✓" diff --git a/tests/test-gas-bf.sh b/tests/test-gas-bf.sh index 703520274..d08033318 100755 --- a/tests/test-gas-bf.sh +++ b/tests/test-gas-bf.sh @@ -6,7 +6,7 @@ fork_version=$1 echo "-- deploy --" -if [ "$fork_version" -eq "4" ]; then +if [ "$fork_version" -ge "4" ]; then deploy ../contract/vm_dummy/test_files/gas_bf_v4.lua else deploy ../contract/vm_dummy/test_files/gas_bf_v2.lua @@ -42,7 +42,7 @@ fi if [ "$consensus" = "raft" ]; then assert_equals "$gasUsed" "0" -elif [ "$fork_version" -eq "4" ]; then +elif [ "$fork_version" -ge "4" ]; then assert_equals "$gasUsed" "47342481" elif [ "$fork_version" -eq "3" ]; then assert_equals "$gasUsed" "47456046" diff --git a/tests/test-gas-deploy.sh b/tests/test-gas-deploy.sh index 2dcf6da38..d1ceae34c 100755 --- a/tests/test-gas-deploy.sh +++ b/tests/test-gas-deploy.sh @@ -33,7 +33,7 @@ assert_equals "$status" "SUCCESS" if [ "$consensus" = "raft" ]; then assert_equals "$gasUsed" "0" -elif [ "$fork_version" -eq "4" ]; then +elif [ "$fork_version" -ge "4" ]; then assert_equals "$gasUsed" "118350" else assert_equals "$gasUsed" "117861" diff --git a/tests/test-gas-op.sh b/tests/test-gas-op.sh index 6d2fef02f..d82137b4e 100755 --- a/tests/test-gas-op.sh +++ b/tests/test-gas-op.sh @@ -33,7 +33,7 @@ assert_equals "$status" "SUCCESS" if [ "$consensus" = "raft" ]; then assert_equals "$gasUsed" "0" -elif [ "$fork_version" -eq "4" ]; then +elif [ "$fork_version" -ge "4" ]; then assert_equals "$gasUsed" "120832" else assert_equals "$gasUsed" "117610" diff --git a/tests/test-gas-verify-proof.sh b/tests/test-gas-verify-proof.sh index f1a743e2b..f941a0df1 100755 --- a/tests/test-gas-verify-proof.sh +++ b/tests/test-gas-verify-proof.sh @@ -33,7 +33,7 @@ assert_equals "$status" "SUCCESS" if [ "$consensus" = "raft" ]; then assert_equals "$gasUsed" "0" -elif [ "$fork_version" -eq "4" ]; then +elif [ "$fork_version" -ge "4" ]; then assert_equals "$gasUsed" "160281" else assert_equals "$gasUsed" "154137" @@ -57,7 +57,7 @@ assert_equals "$status" "SUCCESS" if [ "$consensus" = "raft" ]; then assert_equals "$gasUsed" "0" -elif [ "$fork_version" -eq "4" ]; then +elif [ "$fork_version" -ge "4" ]; then assert_equals "$gasUsed" "108404" else assert_equals "$gasUsed" "108404" diff --git a/tests/test-internal-operations.sh b/tests/test-internal-operations.sh new file mode 100755 index 000000000..bb3db5213 --- /dev/null +++ b/tests/test-internal-operations.sh @@ -0,0 +1,722 @@ +set -e +source common.sh + +fork_version=$1 + + +cat > test-args.lua << EOF +function do_call(...) + return contract.call(...) +end + +function do_delegate_call(...) + return contract.delegatecall(...) +end + +function do_multicall(script) + return contract.delegatecall("multicall", script) +end + +function do_event(...) + return contract.event(...) +end + +function do_deploy(...) + return contract.deploy(...) +end + +function do_send(...) + return contract.send(...) +end + +function do_gov(commands) + for i, command in ipairs(commands) do + local cmd = command[1] + local arg = command[2] + if cmd == "stake" then + contract.stake(arg) + elseif cmd == "vote" then + contract.vote(arg) + elseif cmd == "unstake" then + contract.unstake(arg) + end + end +end + +function constructor(...) + contract.event("constructor", ...) +end + +function default() + contract.event("aergo received", system.getAmount()) + return system.getAmount() +end + +abi.register(do_call, do_delegate_call, do_multicall, do_event, do_deploy, do_send, do_gov, constructor) +abi.payable(default) +EOF + + +cat > test-reverted-operations.lua << EOF +function error_case(to_call, to_send) + --contract.stake("10000 aergo") + --contract.vote("16Uiu2HAm2gtByd6DQu95jXURJXnS59Dyb9zTe16rDrcwKQaxma4p") + contract.call(to_call, "do_event", "ping", "called - within") + contract.send(to_send, "15 aergo") + contract.event("ping", "within") + assert(false) -- revert all operations above +end + +function test_pcall(to_call, to_send) + contract.call(to_call, "do_event", "ping", "called - before") + contract.send(to_send, "15 aergo") + contract.event("ping", "before") + + pcall(error_case, to_call, to_send) + + contract.send(to_send, "15 aergo") + contract.event("ping", "after") + contract.call(to_call, "do_event", "ping", "called - after") +end + +abi.payable(test_pcall, error_case) +EOF + + +echo "-- deploy test contract 1 --" + +deploy test-args.lua +rm test-args.lua + +get_receipt $txhash + +status=$(cat receipt.json | jq .status | sed 's/"//g') +test_args_address=$(cat receipt.json | jq .contractAddress | sed 's/"//g') + +assert_equals "$status" "CREATED" + +get_internal_operations $txhash +internal_operations=$(cat internal_operations.json) + +assert_equals "$internal_operations" '{ + "call": { + "contract": "'$test_args_address'", + "function": "constructor", + "operations": [ + { + "args": [ + "constructor", + "[]" + ], + "op": "event" + } + ] + } +}' + + +echo "-- call test contract 1 --" + +#txhash=$(../bin/aergocli --keystore . --password bmttest \ +# contract call AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R \ +# $test_args_address do_event '["test",123,4.56,"test",true,{"_bignum":"1234567890"}]' | jq .hash | sed 's/"//g') + +txhash=$(../bin/aergocli --keystore . --password bmttest \ + contract call AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R \ + $test_args_address do_call '["'$test_args_address'","do_event","test",123,4.56,"test",true,{"_bignum":"1234567890"}]' | jq .hash | sed 's/"//g') + +get_receipt $txhash + +status=$(cat receipt.json | jq .status | sed 's/"//g') +ret=$(cat receipt.json | jq .ret | sed 's/"//g') +gasUsed=$(cat receipt.json | jq .gasUsed | sed 's/"//g') + +assert_equals "$status" "SUCCESS" + +get_internal_operations $txhash +internal_operations=$(cat internal_operations.json) + +assert_equals "$internal_operations" '{ + "call": { + "args": [ + "'$test_args_address'", + "do_event", + "test", + 123, + 4.56, + "test", + true, + { + "_bignum": "1234567890" + } + ], + "contract": "'$test_args_address'", + "function": "do_call", + "operations": [ + { + "args": [ + "'$test_args_address'", + "do_event", + "[\"test\",123,4.56,\"test\",true,{\"_bignum\":\"1234567890\"}]" + ], + "call": { + "args": [ + "test", + 123, + 4.56, + "test", + true, + { + "_bignum": "1234567890" + } + ], + "contract": "'$test_args_address'", + "function": "do_event", + "operations": [ + { + "args": [ + "test", + "[123,4.56,\"test\",true,{\"_bignum\":\"1234567890\"}]" + ], + "op": "event" + } + ] + }, + "op": "call" + } + ] + } +}' + + +echo "-- deploy ARC1 factory --" + +deploy ../contract/vm_dummy/test_files/arc1-factory.lua + +get_receipt $txhash + +status=$(cat receipt.json | jq .status | sed 's/"//g') +arc1_address=$(cat receipt.json | jq .contractAddress | sed 's/"//g') + +assert_equals "$status" "CREATED" + + +echo "-- deploy ARC2 factory --" + +deploy ../contract/vm_dummy/test_files/arc2-factory.lua + +get_receipt $txhash + +status=$(cat receipt.json | jq .status | sed 's/"//g') +arc2_address=$(cat receipt.json | jq .contractAddress | sed 's/"//g') + +assert_equals "$status" "CREATED" + + +echo "-- deploy caller contract --" + +get_deploy_args ../contract/vm_dummy/test_files/token-deployer.lua + +txhash=$(../bin/aergocli --keystore . --password bmttest \ + contract deploy AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R \ + $deploy_args "[\"$arc1_address\",\"$arc2_address\"]" | jq .hash | sed 's/"//g') + +get_receipt $txhash + +status=$(cat receipt.json | jq .status | sed 's/"//g') +deployer_address=$(cat receipt.json | jq .contractAddress | sed 's/"//g') + +assert_equals "$status" "CREATED" + +get_internal_operations $txhash + +internal_operations=$(cat internal_operations.json) + +assert_equals "$internal_operations" '{ + "call": { + "args": [ + "'$arc1_address'", + "'$arc2_address'" + ], + "contract": "'$deployer_address'", + "function": "constructor", + "operations": [ + { + "args": [ + "arc1_factory", + "\"'$arc1_address'\"" + ], + "op": "set_variable" + }, + { + "args": [ + "arc2_factory", + "\"'$arc2_address'\"" + ], + "op": "set_variable" + } + ] + } +}' + + + +echo "-- transfer 1 aergo to the contract --" + +txhash=$(../bin/aergocli --keystore . --password bmttest \ + sendtx --from AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R --to $test_args_address --amount 1aergo \ + | jq .hash | sed 's/"//g') + +get_receipt $txhash + +status=$(cat receipt.json | jq .status | sed 's/"//g') +ret=$(cat receipt.json | jq .ret | sed 's/"//g') + +assert_equals "$status" "SUCCESS" +assert_equals "$ret" "1000000000000000000" + + +get_internal_operations $txhash + +internal_operations=$(cat internal_operations.json) + +assert_equals "$internal_operations" '{ + "call": { + "amount": "1000000000000000000", + "contract": "'$test_args_address'", + "function": "default", + "operations": [ + { + "args": [ + "aergo received", + "[\"1000000000000000000\"]" + ], + "op": "event" + } + ] + } +}' + + +if [ "$fork_version" -lt "4" ]; then + # composable transactions are only available from hard fork 4 + # the tracking of reverted operations is also only available from hard fork 4 + rm test-reverted-operations.lua + exit 0 +fi + + +echo "-- multicall --" + +script='[ + ["send","'$test_args_address'","0.125 aergo"], + ["get aergo balance","'$test_args_address'"], + ["to string"], + ["store result as","amount"], + ["call","'$test_args_address'","do_send","%my account address%","0.125 aergo"], + ["return","%amount%"] +]' + +txhash=$(../bin/aergocli --keystore . --password bmttest \ + contract multicall AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R "$script" | jq .hash | sed 's/"//g') + +get_receipt $txhash + +status=$(cat receipt.json | jq .status | sed 's/"//g') +ret=$(cat receipt.json | jq .ret | sed 's/"//g') + +assert_equals "$status" "SUCCESS" + +if [ "$consensus" == "sbp" ]; then + assert_equals "$ret" "20001125000000000000000" +else + assert_equals "$ret" "1125000000000000000" +fi + +get_internal_operations $txhash + +internal_operations=$(cat internal_operations.json) + +assert_equals "$internal_operations" '{ + "call": { + "args": [ + [ + [ + "send", + "'$test_args_address'", + "0.125 aergo" + ], + [ + "get aergo balance", + "'$test_args_address'" + ], + [ + "to string" + ], + [ + "store result as", + "amount" + ], + [ + "call", + "'$test_args_address'", + "do_send", + "%my account address%", + "0.125 aergo" + ], + [ + "return", + "%amount%" + ] + ] + ], + "contract": "AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R", + "function": "execute", + "operations": [ + { + "amount": "0.125 aergo", + "args": [ + "'$test_args_address'" + ], + "call": { + "amount": "125000000000000000", + "contract": "'$test_args_address'", + "function": "default", + "operations": [ + { + "args": [ + "aergo received", + "[\"125000000000000000\"]" + ], + "op": "event" + } + ] + }, + "op": "send" + }, + { + "args": [ + "'$test_args_address'", + "do_send", + "[\"AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R\",\"0.125 aergo\"]" + ], + "call": { + "args": [ + "AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R", + "0.125 aergo" + ], + "contract": "'$test_args_address'", + "function": "do_send", + "operations": [ + { + "amount": "0.125 aergo", + "args": [ + "AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R" + ], + "op": "send" + } + ] + }, + "op": "call" + } + ] + } +}' + + +echo "-- deploy test contract 2 --" + +deploy test-reverted-operations.lua +rm test-reverted-operations.lua + +get_receipt $txhash + +status=$(cat receipt.json | jq .status | sed 's/"//g') +test_reverted_address=$(cat receipt.json | jq .contractAddress | sed 's/"//g') + +assert_equals "$status" "CREATED" + +#get_internal_operations $txhash +#internal_operations=$(cat internal_operations.json) + +#assert_equals "$internal_operations" '' + + +echo "-- call test contract 2 - reverted operations --" + +txhash=$(../bin/aergocli --keystore . --password bmttest \ + contract call AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R \ + --amount 50000000000000000000 \ + $test_reverted_address test_pcall '["'$test_args_address'","'$test_args_address'"]' | jq .hash | sed 's/"//g') + +get_receipt $txhash + +status=$(cat receipt.json | jq .status | sed 's/"//g') +ret=$(cat receipt.json | jq .ret | sed 's/"//g') + +assert_equals "$status" "SUCCESS" + +get_internal_operations $txhash +internal_operations=$(cat internal_operations.json) + +assert_equals "$internal_operations" '{ + "call": { + "amount": "50000000000000000000", + "args": [ + "'$test_args_address'", + "'$test_args_address'" + ], + "contract": "'$test_reverted_address'", + "function": "test_pcall", + "operations": [ + { + "args": [ + "'$test_args_address'", + "do_event", + "[\"ping\",\"called - before\"]" + ], + "call": { + "args": [ + "ping", + "called - before" + ], + "contract": "'$test_args_address'", + "function": "do_event", + "operations": [ + { + "args": [ + "ping", + "[\"called - before\"]" + ], + "op": "event" + } + ] + }, + "op": "call" + }, + { + "amount": "15 aergo", + "args": [ + "'$test_args_address'" + ], + "call": { + "amount": "15000000000000000000", + "contract": "'$test_args_address'", + "function": "default", + "operations": [ + { + "args": [ + "aergo received", + "[\"15000000000000000000\"]" + ], + "op": "event" + } + ] + }, + "op": "send" + }, + { + "args": [ + "ping", + "[\"before\"]" + ], + "op": "event" + }, + { + "args": [ + "'$test_args_address'", + "do_event", + "[\"ping\",\"called - within\"]" + ], + "call": { + "args": [ + "ping", + "called - within" + ], + "contract": "'$test_args_address'", + "function": "do_event", + "operations": [ + { + "args": [ + "ping", + "[\"called - within\"]" + ], + "op": "event" + } + ] + }, + "op": "call", + "reverted": true + }, + { + "amount": "15 aergo", + "args": [ + "'$test_args_address'" + ], + "call": { + "amount": "15000000000000000000", + "contract": "'$test_args_address'", + "function": "default", + "operations": [ + { + "args": [ + "aergo received", + "[\"15000000000000000000\"]" + ], + "op": "event" + } + ] + }, + "op": "send", + "reverted": true + }, + { + "args": [ + "ping", + "[\"within\"]" + ], + "op": "event", + "reverted": true + }, + { + "amount": "15 aergo", + "args": [ + "'$test_args_address'" + ], + "call": { + "amount": "15000000000000000000", + "contract": "'$test_args_address'", + "function": "default", + "operations": [ + { + "args": [ + "aergo received", + "[\"15000000000000000000\"]" + ], + "op": "event" + } + ] + }, + "op": "send" + }, + { + "args": [ + "ping", + "[\"after\"]" + ], + "op": "event" + }, + { + "args": [ + "'$test_args_address'", + "do_event", + "[\"ping\",\"called - after\"]" + ], + "call": { + "args": [ + "ping", + "called - after" + ], + "contract": "'$test_args_address'", + "function": "do_event", + "operations": [ + { + "args": [ + "ping", + "[\"called - after\"]" + ], + "op": "event" + } + ] + }, + "op": "call" + } + ] + } +}' + + +echo "-- call test contract 2 - error case --" + +txhash=$(../bin/aergocli --keystore . --password bmttest \ + contract call AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R \ + --amount 50000000000000000000 \ + $test_reverted_address error_case '["'$test_args_address'","'$test_args_address'"]' | jq .hash | sed 's/"//g') + +get_receipt $txhash + +status=$(cat receipt.json | jq .status | sed 's/"//g') +ret=$(cat receipt.json | jq .ret | sed 's/"//g') + +assert_equals "$status" "ERROR" +assert_contains "$ret" "assertion failed!" + +get_internal_operations $txhash +internal_operations=$(cat internal_operations.json) + +assert_equals "$internal_operations" '{ + "call": { + "amount": "50000000000000000000", + "args": [ + "'$test_args_address'", + "'$test_args_address'" + ], + "contract": "'$test_reverted_address'", + "function": "error_case", + "operations": [ + { + "args": [ + "'$test_args_address'", + "do_event", + "[\"ping\",\"called - within\"]" + ], + "call": { + "args": [ + "ping", + "called - within" + ], + "contract": "'$test_args_address'", + "function": "do_event", + "operations": [ + { + "args": [ + "ping", + "[\"called - within\"]" + ], + "op": "event" + } + ] + }, + "op": "call" + }, + { + "amount": "15 aergo", + "args": [ + "'$test_args_address'" + ], + "call": { + "amount": "15000000000000000000", + "contract": "'$test_args_address'", + "function": "default", + "operations": [ + { + "args": [ + "aergo received", + "[\"15000000000000000000\"]" + ], + "op": "event" + } + ] + }, + "op": "send" + }, + { + "args": [ + "ping", + "[\"within\"]" + ], + "op": "event" + } + ] + } +}' diff --git a/tests/test-name-service.sh b/tests/test-name-service.sh index 8fdb8db29..daf487f85 100755 --- a/tests/test-name-service.sh +++ b/tests/test-name-service.sh @@ -28,7 +28,7 @@ status=$(cat receipt.json | jq .status | sed 's/"//g') ret=$(cat receipt.json | jq .ret | sed 's/"//g') gasUsed=$(cat receipt.json | jq .gasUsed | sed 's/"//g') -if [ "$fork_version" -eq "4" ]; then +if [ "$fork_version" -ge "4" ]; then assert_equals "$status" "ERROR" # assert_equals "$ret" "[Contract.LuaResolve] Data and checksum don't match" assert_contains "$ret" "Data and checksum don't match" @@ -49,7 +49,7 @@ get_receipt $txhash status=$(cat receipt.json | jq .status | sed 's/"//g') ret=$(cat receipt.json | jq .ret | sed 's/"//g') -if [ "$fork_version" -eq "4" ]; then +if [ "$fork_version" -ge "4" ]; then assert_equals "$status" "SUCCESS" assert_equals "$ret" "AmgExqUu6J4Za8VjyWMJANxoRaUvwgngGQJgemHgwWvuRSEd3wnE" else @@ -69,7 +69,7 @@ get_receipt $txhash status=$(cat receipt.json | jq .status | sed 's/"//g') ret=$(cat receipt.json | jq .ret | sed 's/"//g') -if [ "$fork_version" -eq "4" ]; then +if [ "$fork_version" -ge "4" ]; then assert_equals "$status" "SUCCESS" assert_equals "$ret" "" else @@ -88,7 +88,7 @@ get_receipt $txhash status=$(cat receipt.json | jq .status | sed 's/"//g') ret=$(cat receipt.json | jq .ret | sed 's/"//g') -if [ "$fork_version" -eq "4" ]; then +if [ "$fork_version" -ge "4" ]; then assert_equals "$status" "SUCCESS" assert_equals "$ret" "" else @@ -127,7 +127,7 @@ get_receipt $txhash status=$(cat receipt.json | jq .status | sed 's/"//g') ret=$(cat receipt.json | jq .ret | sed 's/"//g') -if [ "$fork_version" -eq "4" ]; then +if [ "$fork_version" -ge "4" ]; then assert_equals "$status" "SUCCESS" assert_equals "$ret" "AmPpcKvToDCUkhT1FJjdbNvR4kNDhLFJGHkSqfjWe3QmHm96qv4R" else @@ -160,7 +160,7 @@ get_receipt $txhash status=$(cat receipt.json | jq .status | sed 's/"//g') ret=$(cat receipt.json | jq .ret | sed 's/"//g') -if [ "$fork_version" -eq "4" ]; then +if [ "$fork_version" -ge "4" ]; then assert_equals "$status" "SUCCESS" assert_equals "$ret" "Amh9vfP5My5DpSafe3gcZ1u8DiZNuqHSN2oAWehZW1kgB3XP4kPi" else @@ -174,7 +174,7 @@ echo "-- query the contract --" ../bin/aergocli contract query ${address} resolve '["'$account_name'"]' > result.txt 2> result.txt || true result=$(cat result.txt) -if [ "$fork_version" -eq "4" ]; then +if [ "$fork_version" -ge "4" ]; then result=$(echo $result | sed 's/"//g' | sed 's/\\//g' | sed 's/value://g') assert_equals "$result" "Amh9vfP5My5DpSafe3gcZ1u8DiZNuqHSN2oAWehZW1kgB3XP4kPi" else diff --git a/tests/test-pcall-events.sh b/tests/test-pcall-events.sh index 206f83f9f..905185522 100755 --- a/tests/test-pcall-events.sh +++ b/tests/test-pcall-events.sh @@ -74,7 +74,7 @@ nevents=$(cat receipt.json | jq '.events | length') assert_equals "$status" "SUCCESS" #assert_equals "$ret" "{}" -if [ "$fork_version" -eq "4" ]; then +if [ "$fork_version" -ge "4" ]; then assert_equals "$nevents" "2" else assert_equals "$nevents" "6" @@ -97,7 +97,7 @@ nevents=$(cat receipt.json | jq '.events | length') assert_equals "$status" "SUCCESS" #assert_equals "$ret" "{}" -if [ "$fork_version" -eq "4" ]; then +if [ "$fork_version" -ge "4" ]; then assert_equals "$nevents" "2" else assert_equals "$nevents" "6" @@ -120,7 +120,7 @@ nevents=$(cat receipt.json | jq '.events | length') assert_equals "$status" "SUCCESS" #assert_equals "$ret" "{}" -if [ "$fork_version" -eq "4" ]; then +if [ "$fork_version" -ge "4" ]; then assert_equals "$nevents" "2" else assert_equals "$nevents" "6" diff --git a/types/blockchain.go b/types/blockchain.go index 9c00a7028..b23f2be52 100644 --- a/types/blockchain.go +++ b/types/blockchain.go @@ -141,6 +141,9 @@ type ChainAccessor interface { // GetEnterpriseConfig always return non-nil object if there is no error, but it can return EnterpriseConfig with empty values GetEnterpriseConfig(key string) (*EnterpriseConfig, error) ChainID(bno BlockNo) *ChainID + + // HardforkHeights returns a map with hardfork version number as keys and their corresponding block numbers as values. + HardforkHeights() map[string]BlockNo } type SyncContext struct { diff --git a/types/dbkey/key.go b/types/dbkey/key.go index b25be2cdc..bc15f1740 100644 --- a/types/dbkey/key.go +++ b/types/dbkey/key.go @@ -25,6 +25,10 @@ func Receipts(blockHash []byte, blockNo types.BlockNo) []byte { return key } +func InternalOps(blockNo types.BlockNo) []byte { + return append([]byte(internalOpsPrefix), types.BlockNoToBytes(blockNo)...) +} + //---------------------------------------------------------------------------------// // metadata diff --git a/types/dbkey/schema.go b/types/dbkey/schema.go index 311481c58..6bb883cb1 100644 --- a/types/dbkey/schema.go +++ b/types/dbkey/schema.go @@ -9,6 +9,7 @@ const ( // chain const ( receiptsPrefix = "r" + internalOpsPrefix = "i" ) // metadata diff --git a/types/jsonrpc/chainInfo.go b/types/jsonrpc/chainInfo.go index 447f44a37..f0bb956f1 100644 --- a/types/jsonrpc/chainInfo.go +++ b/types/jsonrpc/chainInfo.go @@ -28,20 +28,22 @@ func ConvChainInfo(msg *types.ChainInfo) *InOutChainInfo { ci.NamePrice = new(big.Int).SetBytes(msg.Nameprice).String() ci.TotalVotingPower = new(big.Int).SetBytes(msg.Totalvotingpower).String() ci.VotingReward = new(big.Int).SetBytes(msg.Votingreward).String() + ci.Hardfork = msg.Hardfork return ci } type InOutChainInfo struct { - Id *InOutChainId `json:"id,omitempty"` - BpNumber uint32 `json:"bpNumber,omitempty"` - MaxBlockSize uint64 `json:"maxblocksize,omitempty"` - MaxTokens string `json:"maxtokens,omitempty"` - StakingMinimum string `json:"stakingminimum,omitempty"` - Totalstaking string `json:"totalstaking,omitempty"` - GasPrice string `json:"gasprice,omitempty"` - NamePrice string `json:"nameprice,omitempty"` - TotalVotingPower string `json:"totalvotingpower,omitempty"` - VotingReward string `json:"votingreward,omitempty"` + Id *InOutChainId `json:"id,omitempty"` + BpNumber uint32 `json:"bpNumber,omitempty"` + MaxBlockSize uint64 `json:"maxblocksize,omitempty"` + MaxTokens string `json:"maxtokens,omitempty"` + StakingMinimum string `json:"stakingminimum,omitempty"` + Totalstaking string `json:"totalstaking,omitempty"` + GasPrice string `json:"gasprice,omitempty"` + NamePrice string `json:"nameprice,omitempty"` + TotalVotingPower string `json:"totalvotingpower,omitempty"` + VotingReward string `json:"votingreward,omitempty"` + Hardfork map[string]uint64 `json:"hardfork,omitempty"` } func ConvChainId(msg *types.ChainId) *InOutChainId { diff --git a/types/jsonrpc/chaininfo_test.go b/types/jsonrpc/chaininfo_test.go index 6552ddb89..e2b4a16f5 100644 --- a/types/jsonrpc/chaininfo_test.go +++ b/types/jsonrpc/chaininfo_test.go @@ -20,6 +20,7 @@ func TestConvChainInfo(t *testing.T) { namePrice = types.NewAmount(1, types.Aergo) totalVotingPower = types.NewAmount(10000000, types.Aergo) votingReward = types.NewAmount(1, types.Aergo) + hardfork = map[string]uint64{"V1": 100000, "V2": 200000, "V3": 3000000} ) for _, test := range []struct { @@ -36,6 +37,7 @@ func TestConvChainInfo(t *testing.T) { Nameprice: namePrice.Bytes(), Totalvotingpower: totalVotingPower.Bytes(), Votingreward: votingReward.Bytes(), + Hardfork: hardfork, }, &InOutChainInfo{ BpNumber: 13, MaxBlockSize: uint64(chain.MaxBlockSize()), @@ -44,6 +46,7 @@ func TestConvChainInfo(t *testing.T) { NamePrice: namePrice.String(), TotalVotingPower: totalVotingPower.String(), VotingReward: votingReward.String(), + Hardfork: hardfork, }}, {&types.ChainInfo{ // dpos @@ -57,6 +60,7 @@ func TestConvChainInfo(t *testing.T) { Nameprice: namePrice.Bytes(), Totalvotingpower: totalVotingPower.Bytes(), Votingreward: votingReward.Bytes(), + Hardfork: hardfork, }, &InOutChainInfo{ Id: &InOutChainId{Consensus: "dpos"}, BpNumber: 13, @@ -68,6 +72,7 @@ func TestConvChainInfo(t *testing.T) { NamePrice: namePrice.String(), TotalVotingPower: totalVotingPower.String(), VotingReward: votingReward.String(), + Hardfork: hardfork, }}, } { require.Equal(t, test.inout, ConvChainInfo(test.types)) diff --git a/types/message/blockchainmsg.go b/types/message/blockchainmsg.go index df88cd5fc..462e91606 100644 --- a/types/message/blockchainmsg.go +++ b/types/message/blockchainmsg.go @@ -93,6 +93,14 @@ type GetReceiptsByNo struct { } type GetReceiptsByNoRsp GetReceiptsRsp +type GetInternalOperations struct { + BlockNo types.BlockNo +} +type GetInternalOperationsRsp struct { + Operations string + Err error +} + type GetABI struct { Contract []byte } diff --git a/types/rpc.pb.go b/types/rpc.pb.go index 1d7ef4d10..7fc50f207 100644 --- a/types/rpc.pb.go +++ b/types/rpc.pb.go @@ -301,16 +301,17 @@ type ChainInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id *ChainId `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - BpNumber uint32 `protobuf:"varint,2,opt,name=bpNumber,proto3" json:"bpNumber,omitempty"` - Maxblocksize uint64 `protobuf:"varint,3,opt,name=maxblocksize,proto3" json:"maxblocksize,omitempty"` - Maxtokens []byte `protobuf:"bytes,4,opt,name=maxtokens,proto3" json:"maxtokens,omitempty"` - Stakingminimum []byte `protobuf:"bytes,5,opt,name=stakingminimum,proto3" json:"stakingminimum,omitempty"` - Totalstaking []byte `protobuf:"bytes,6,opt,name=totalstaking,proto3" json:"totalstaking,omitempty"` - Gasprice []byte `protobuf:"bytes,7,opt,name=gasprice,proto3" json:"gasprice,omitempty"` - Nameprice []byte `protobuf:"bytes,8,opt,name=nameprice,proto3" json:"nameprice,omitempty"` - Totalvotingpower []byte `protobuf:"bytes,9,opt,name=totalvotingpower,proto3" json:"totalvotingpower,omitempty"` - Votingreward []byte `protobuf:"bytes,10,opt,name=votingreward,proto3" json:"votingreward,omitempty"` + Id *ChainId `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + BpNumber uint32 `protobuf:"varint,2,opt,name=bpNumber,proto3" json:"bpNumber,omitempty"` + Maxblocksize uint64 `protobuf:"varint,3,opt,name=maxblocksize,proto3" json:"maxblocksize,omitempty"` + Maxtokens []byte `protobuf:"bytes,4,opt,name=maxtokens,proto3" json:"maxtokens,omitempty"` + Stakingminimum []byte `protobuf:"bytes,5,opt,name=stakingminimum,proto3" json:"stakingminimum,omitempty"` + Totalstaking []byte `protobuf:"bytes,6,opt,name=totalstaking,proto3" json:"totalstaking,omitempty"` + Gasprice []byte `protobuf:"bytes,7,opt,name=gasprice,proto3" json:"gasprice,omitempty"` + Nameprice []byte `protobuf:"bytes,8,opt,name=nameprice,proto3" json:"nameprice,omitempty"` + Totalvotingpower []byte `protobuf:"bytes,9,opt,name=totalvotingpower,proto3" json:"totalvotingpower,omitempty"` + Votingreward []byte `protobuf:"bytes,10,opt,name=votingreward,proto3" json:"votingreward,omitempty"` + Hardfork map[string]uint64 `protobuf:"bytes,11,rep,name=hardfork,proto3" json:"hardfork,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` } func (x *ChainInfo) Reset() { @@ -415,6 +416,13 @@ func (x *ChainInfo) GetVotingreward() []byte { return nil } +func (x *ChainInfo) GetHardfork() map[string]uint64 { + if x != nil { + return x.Hardfork + } + return nil +} + // ChainStats corresponds to a chain statistics report. type ChainStats struct { state protoimpl.MessageState @@ -1139,6 +1147,53 @@ func (x *PageParams) GetSize() uint32 { return 0 } +type BlockNumberParam struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + BlockNo uint64 `protobuf:"varint,1,opt,name=blockNo,proto3" json:"blockNo,omitempty"` +} + +func (x *BlockNumberParam) Reset() { + *x = BlockNumberParam{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BlockNumberParam) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BlockNumberParam) ProtoMessage() {} + +func (x *BlockNumberParam) ProtoReflect() protoreflect.Message { + mi := &file_rpc_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BlockNumberParam.ProtoReflect.Descriptor instead. +func (*BlockNumberParam) Descriptor() ([]byte, []int) { + return file_rpc_proto_rawDescGZIP(), []int{15} +} + +func (x *BlockNumberParam) GetBlockNo() uint64 { + if x != nil { + return x.BlockNo + } + return 0 +} + type BlockBodyPaged struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1153,7 +1208,7 @@ type BlockBodyPaged struct { func (x *BlockBodyPaged) Reset() { *x = BlockBodyPaged{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[15] + mi := &file_rpc_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1166,7 +1221,7 @@ func (x *BlockBodyPaged) String() string { func (*BlockBodyPaged) ProtoMessage() {} func (x *BlockBodyPaged) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[15] + mi := &file_rpc_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1179,7 +1234,7 @@ func (x *BlockBodyPaged) ProtoReflect() protoreflect.Message { // Deprecated: Use BlockBodyPaged.ProtoReflect.Descriptor instead. func (*BlockBodyPaged) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{15} + return file_rpc_proto_rawDescGZIP(), []int{16} } func (x *BlockBodyPaged) GetTotal() uint32 { @@ -1222,7 +1277,7 @@ type BlockBodyParams struct { func (x *BlockBodyParams) Reset() { *x = BlockBodyParams{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[16] + mi := &file_rpc_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1235,7 +1290,7 @@ func (x *BlockBodyParams) String() string { func (*BlockBodyParams) ProtoMessage() {} func (x *BlockBodyParams) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[16] + mi := &file_rpc_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1248,7 +1303,7 @@ func (x *BlockBodyParams) ProtoReflect() protoreflect.Message { // Deprecated: Use BlockBodyParams.ProtoReflect.Descriptor instead. func (*BlockBodyParams) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{16} + return file_rpc_proto_rawDescGZIP(), []int{17} } func (x *BlockBodyParams) GetHashornumber() []byte { @@ -1276,7 +1331,7 @@ type BlockHeaderList struct { func (x *BlockHeaderList) Reset() { *x = BlockHeaderList{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[17] + mi := &file_rpc_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1289,7 +1344,7 @@ func (x *BlockHeaderList) String() string { func (*BlockHeaderList) ProtoMessage() {} func (x *BlockHeaderList) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[17] + mi := &file_rpc_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1302,7 +1357,7 @@ func (x *BlockHeaderList) ProtoReflect() protoreflect.Message { // Deprecated: Use BlockHeaderList.ProtoReflect.Descriptor instead. func (*BlockHeaderList) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{17} + return file_rpc_proto_rawDescGZIP(), []int{18} } func (x *BlockHeaderList) GetBlocks() []*Block { @@ -1326,7 +1381,7 @@ type BlockMetadata struct { func (x *BlockMetadata) Reset() { *x = BlockMetadata{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[18] + mi := &file_rpc_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1339,7 +1394,7 @@ func (x *BlockMetadata) String() string { func (*BlockMetadata) ProtoMessage() {} func (x *BlockMetadata) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[18] + mi := &file_rpc_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1352,7 +1407,7 @@ func (x *BlockMetadata) ProtoReflect() protoreflect.Message { // Deprecated: Use BlockMetadata.ProtoReflect.Descriptor instead. func (*BlockMetadata) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{18} + return file_rpc_proto_rawDescGZIP(), []int{19} } func (x *BlockMetadata) GetHash() []byte { @@ -1394,7 +1449,7 @@ type BlockMetadataList struct { func (x *BlockMetadataList) Reset() { *x = BlockMetadataList{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[19] + mi := &file_rpc_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1407,7 +1462,7 @@ func (x *BlockMetadataList) String() string { func (*BlockMetadataList) ProtoMessage() {} func (x *BlockMetadataList) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[19] + mi := &file_rpc_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1420,7 +1475,7 @@ func (x *BlockMetadataList) ProtoReflect() protoreflect.Message { // Deprecated: Use BlockMetadataList.ProtoReflect.Descriptor instead. func (*BlockMetadataList) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{19} + return file_rpc_proto_rawDescGZIP(), []int{20} } func (x *BlockMetadataList) GetBlocks() []*BlockMetadata { @@ -1443,7 +1498,7 @@ type CommitResult struct { func (x *CommitResult) Reset() { *x = CommitResult{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[20] + mi := &file_rpc_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1456,7 +1511,7 @@ func (x *CommitResult) String() string { func (*CommitResult) ProtoMessage() {} func (x *CommitResult) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[20] + mi := &file_rpc_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1469,7 +1524,7 @@ func (x *CommitResult) ProtoReflect() protoreflect.Message { // Deprecated: Use CommitResult.ProtoReflect.Descriptor instead. func (*CommitResult) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{20} + return file_rpc_proto_rawDescGZIP(), []int{21} } func (x *CommitResult) GetHash() []byte { @@ -1504,7 +1559,7 @@ type CommitResultList struct { func (x *CommitResultList) Reset() { *x = CommitResultList{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[21] + mi := &file_rpc_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1517,7 +1572,7 @@ func (x *CommitResultList) String() string { func (*CommitResultList) ProtoMessage() {} func (x *CommitResultList) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[21] + mi := &file_rpc_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1530,7 +1585,7 @@ func (x *CommitResultList) ProtoReflect() protoreflect.Message { // Deprecated: Use CommitResultList.ProtoReflect.Descriptor instead. func (*CommitResultList) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{21} + return file_rpc_proto_rawDescGZIP(), []int{22} } func (x *CommitResultList) GetResults() []*CommitResult { @@ -1552,7 +1607,7 @@ type VerifyResult struct { func (x *VerifyResult) Reset() { *x = VerifyResult{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[22] + mi := &file_rpc_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1565,7 +1620,7 @@ func (x *VerifyResult) String() string { func (*VerifyResult) ProtoMessage() {} func (x *VerifyResult) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[22] + mi := &file_rpc_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1578,7 +1633,7 @@ func (x *VerifyResult) ProtoReflect() protoreflect.Message { // Deprecated: Use VerifyResult.ProtoReflect.Descriptor instead. func (*VerifyResult) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{22} + return file_rpc_proto_rawDescGZIP(), []int{23} } func (x *VerifyResult) GetTx() *Tx { @@ -1607,7 +1662,7 @@ type Personal struct { func (x *Personal) Reset() { *x = Personal{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[23] + mi := &file_rpc_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1620,7 +1675,7 @@ func (x *Personal) String() string { func (*Personal) ProtoMessage() {} func (x *Personal) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[23] + mi := &file_rpc_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1633,7 +1688,7 @@ func (x *Personal) ProtoReflect() protoreflect.Message { // Deprecated: Use Personal.ProtoReflect.Descriptor instead. func (*Personal) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{23} + return file_rpc_proto_rawDescGZIP(), []int{24} } func (x *Personal) GetPassphrase() string { @@ -1664,7 +1719,7 @@ type ImportFormat struct { func (x *ImportFormat) Reset() { *x = ImportFormat{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[24] + mi := &file_rpc_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1677,7 +1732,7 @@ func (x *ImportFormat) String() string { func (*ImportFormat) ProtoMessage() {} func (x *ImportFormat) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[24] + mi := &file_rpc_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1690,7 +1745,7 @@ func (x *ImportFormat) ProtoReflect() protoreflect.Message { // Deprecated: Use ImportFormat.ProtoReflect.Descriptor instead. func (*ImportFormat) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{24} + return file_rpc_proto_rawDescGZIP(), []int{25} } func (x *ImportFormat) GetWif() *SingleBytes { @@ -1733,7 +1788,7 @@ type Staking struct { func (x *Staking) Reset() { *x = Staking{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[25] + mi := &file_rpc_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1746,7 +1801,7 @@ func (x *Staking) String() string { func (*Staking) ProtoMessage() {} func (x *Staking) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[25] + mi := &file_rpc_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1759,7 +1814,7 @@ func (x *Staking) ProtoReflect() protoreflect.Message { // Deprecated: Use Staking.ProtoReflect.Descriptor instead. func (*Staking) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{25} + return file_rpc_proto_rawDescGZIP(), []int{26} } func (x *Staking) GetAmount() []byte { @@ -1788,7 +1843,7 @@ type Vote struct { func (x *Vote) Reset() { *x = Vote{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[26] + mi := &file_rpc_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1801,7 +1856,7 @@ func (x *Vote) String() string { func (*Vote) ProtoMessage() {} func (x *Vote) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[26] + mi := &file_rpc_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1814,7 +1869,7 @@ func (x *Vote) ProtoReflect() protoreflect.Message { // Deprecated: Use Vote.ProtoReflect.Descriptor instead. func (*Vote) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{26} + return file_rpc_proto_rawDescGZIP(), []int{27} } func (x *Vote) GetCandidate() []byte { @@ -1843,7 +1898,7 @@ type VoteParams struct { func (x *VoteParams) Reset() { *x = VoteParams{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[27] + mi := &file_rpc_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1856,7 +1911,7 @@ func (x *VoteParams) String() string { func (*VoteParams) ProtoMessage() {} func (x *VoteParams) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[27] + mi := &file_rpc_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1869,7 +1924,7 @@ func (x *VoteParams) ProtoReflect() protoreflect.Message { // Deprecated: Use VoteParams.ProtoReflect.Descriptor instead. func (*VoteParams) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{27} + return file_rpc_proto_rawDescGZIP(), []int{28} } func (x *VoteParams) GetId() string { @@ -1898,7 +1953,7 @@ type AccountVoteInfo struct { func (x *AccountVoteInfo) Reset() { *x = AccountVoteInfo{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[28] + mi := &file_rpc_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1911,7 +1966,7 @@ func (x *AccountVoteInfo) String() string { func (*AccountVoteInfo) ProtoMessage() {} func (x *AccountVoteInfo) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[28] + mi := &file_rpc_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1924,7 +1979,7 @@ func (x *AccountVoteInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use AccountVoteInfo.ProtoReflect.Descriptor instead. func (*AccountVoteInfo) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{28} + return file_rpc_proto_rawDescGZIP(), []int{29} } func (x *AccountVoteInfo) GetStaking() *Staking { @@ -1954,7 +2009,7 @@ type VoteInfo struct { func (x *VoteInfo) Reset() { *x = VoteInfo{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[29] + mi := &file_rpc_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1967,7 +2022,7 @@ func (x *VoteInfo) String() string { func (*VoteInfo) ProtoMessage() {} func (x *VoteInfo) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[29] + mi := &file_rpc_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1980,7 +2035,7 @@ func (x *VoteInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use VoteInfo.ProtoReflect.Descriptor instead. func (*VoteInfo) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{29} + return file_rpc_proto_rawDescGZIP(), []int{30} } func (x *VoteInfo) GetId() string { @@ -2016,7 +2071,7 @@ type VoteList struct { func (x *VoteList) Reset() { *x = VoteList{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[30] + mi := &file_rpc_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2029,7 +2084,7 @@ func (x *VoteList) String() string { func (*VoteList) ProtoMessage() {} func (x *VoteList) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[30] + mi := &file_rpc_proto_msgTypes[31] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2042,7 +2097,7 @@ func (x *VoteList) ProtoReflect() protoreflect.Message { // Deprecated: Use VoteList.ProtoReflect.Descriptor instead. func (*VoteList) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{30} + return file_rpc_proto_rawDescGZIP(), []int{31} } func (x *VoteList) GetVotes() []*Vote { @@ -2071,7 +2126,7 @@ type NodeReq struct { func (x *NodeReq) Reset() { *x = NodeReq{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[31] + mi := &file_rpc_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2084,7 +2139,7 @@ func (x *NodeReq) String() string { func (*NodeReq) ProtoMessage() {} func (x *NodeReq) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[31] + mi := &file_rpc_proto_msgTypes[32] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2097,7 +2152,7 @@ func (x *NodeReq) ProtoReflect() protoreflect.Message { // Deprecated: Use NodeReq.ProtoReflect.Descriptor instead. func (*NodeReq) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{31} + return file_rpc_proto_rawDescGZIP(), []int{32} } func (x *NodeReq) GetTimeout() []byte { @@ -2126,7 +2181,7 @@ type Name struct { func (x *Name) Reset() { *x = Name{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[32] + mi := &file_rpc_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2139,7 +2194,7 @@ func (x *Name) String() string { func (*Name) ProtoMessage() {} func (x *Name) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[32] + mi := &file_rpc_proto_msgTypes[33] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2152,7 +2207,7 @@ func (x *Name) ProtoReflect() protoreflect.Message { // Deprecated: Use Name.ProtoReflect.Descriptor instead. func (*Name) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{32} + return file_rpc_proto_rawDescGZIP(), []int{33} } func (x *Name) GetName() string { @@ -2182,7 +2237,7 @@ type NameInfo struct { func (x *NameInfo) Reset() { *x = NameInfo{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[33] + mi := &file_rpc_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2195,7 +2250,7 @@ func (x *NameInfo) String() string { func (*NameInfo) ProtoMessage() {} func (x *NameInfo) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[33] + mi := &file_rpc_proto_msgTypes[34] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2208,7 +2263,7 @@ func (x *NameInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use NameInfo.ProtoReflect.Descriptor instead. func (*NameInfo) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{33} + return file_rpc_proto_rawDescGZIP(), []int{34} } func (x *NameInfo) GetName() *Name { @@ -2244,7 +2299,7 @@ type PeersParams struct { func (x *PeersParams) Reset() { *x = PeersParams{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[34] + mi := &file_rpc_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2257,7 +2312,7 @@ func (x *PeersParams) String() string { func (*PeersParams) ProtoMessage() {} func (x *PeersParams) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[34] + mi := &file_rpc_proto_msgTypes[35] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2270,7 +2325,7 @@ func (x *PeersParams) ProtoReflect() protoreflect.Message { // Deprecated: Use PeersParams.ProtoReflect.Descriptor instead. func (*PeersParams) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{34} + return file_rpc_proto_rawDescGZIP(), []int{35} } func (x *PeersParams) GetNoHidden() bool { @@ -2298,7 +2353,7 @@ type KeyParams struct { func (x *KeyParams) Reset() { *x = KeyParams{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[35] + mi := &file_rpc_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2311,7 +2366,7 @@ func (x *KeyParams) String() string { func (*KeyParams) ProtoMessage() {} func (x *KeyParams) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[35] + mi := &file_rpc_proto_msgTypes[36] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2324,7 +2379,7 @@ func (x *KeyParams) ProtoReflect() protoreflect.Message { // Deprecated: Use KeyParams.ProtoReflect.Descriptor instead. func (*KeyParams) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{35} + return file_rpc_proto_rawDescGZIP(), []int{36} } func (x *KeyParams) GetKey() []string { @@ -2346,7 +2401,7 @@ type ServerInfo struct { func (x *ServerInfo) Reset() { *x = ServerInfo{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[36] + mi := &file_rpc_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2359,7 +2414,7 @@ func (x *ServerInfo) String() string { func (*ServerInfo) ProtoMessage() {} func (x *ServerInfo) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[36] + mi := &file_rpc_proto_msgTypes[37] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2372,7 +2427,7 @@ func (x *ServerInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use ServerInfo.ProtoReflect.Descriptor instead. func (*ServerInfo) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{36} + return file_rpc_proto_rawDescGZIP(), []int{37} } func (x *ServerInfo) GetStatus() map[string]string { @@ -2400,7 +2455,7 @@ type ConfigItem struct { func (x *ConfigItem) Reset() { *x = ConfigItem{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[37] + mi := &file_rpc_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2413,7 +2468,7 @@ func (x *ConfigItem) String() string { func (*ConfigItem) ProtoMessage() {} func (x *ConfigItem) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[37] + mi := &file_rpc_proto_msgTypes[38] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2426,7 +2481,7 @@ func (x *ConfigItem) ProtoReflect() protoreflect.Message { // Deprecated: Use ConfigItem.ProtoReflect.Descriptor instead. func (*ConfigItem) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{37} + return file_rpc_proto_rawDescGZIP(), []int{38} } func (x *ConfigItem) GetProps() map[string]string { @@ -2447,7 +2502,7 @@ type EventList struct { func (x *EventList) Reset() { *x = EventList{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[38] + mi := &file_rpc_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2460,7 +2515,7 @@ func (x *EventList) String() string { func (*EventList) ProtoMessage() {} func (x *EventList) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[38] + mi := &file_rpc_proto_msgTypes[39] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2473,7 +2528,7 @@ func (x *EventList) ProtoReflect() protoreflect.Message { // Deprecated: Use EventList.ProtoReflect.Descriptor instead. func (*EventList) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{38} + return file_rpc_proto_rawDescGZIP(), []int{39} } func (x *EventList) GetEvents() []*Event { @@ -2497,7 +2552,7 @@ type ConsensusInfo struct { func (x *ConsensusInfo) Reset() { *x = ConsensusInfo{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[39] + mi := &file_rpc_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2510,7 +2565,7 @@ func (x *ConsensusInfo) String() string { func (*ConsensusInfo) ProtoMessage() {} func (x *ConsensusInfo) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[39] + mi := &file_rpc_proto_msgTypes[40] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2523,7 +2578,7 @@ func (x *ConsensusInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use ConsensusInfo.ProtoReflect.Descriptor instead. func (*ConsensusInfo) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{39} + return file_rpc_proto_rawDescGZIP(), []int{40} } func (x *ConsensusInfo) GetType() string { @@ -2558,7 +2613,7 @@ type EnterpriseConfigKey struct { func (x *EnterpriseConfigKey) Reset() { *x = EnterpriseConfigKey{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[40] + mi := &file_rpc_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2571,7 +2626,7 @@ func (x *EnterpriseConfigKey) String() string { func (*EnterpriseConfigKey) ProtoMessage() {} func (x *EnterpriseConfigKey) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[40] + mi := &file_rpc_proto_msgTypes[41] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2584,7 +2639,7 @@ func (x *EnterpriseConfigKey) ProtoReflect() protoreflect.Message { // Deprecated: Use EnterpriseConfigKey.ProtoReflect.Descriptor instead. func (*EnterpriseConfigKey) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{40} + return file_rpc_proto_rawDescGZIP(), []int{41} } func (x *EnterpriseConfigKey) GetKey() string { @@ -2607,7 +2662,7 @@ type EnterpriseConfig struct { func (x *EnterpriseConfig) Reset() { *x = EnterpriseConfig{} if protoimpl.UnsafeEnabled { - mi := &file_rpc_proto_msgTypes[41] + mi := &file_rpc_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2620,7 +2675,7 @@ func (x *EnterpriseConfig) String() string { func (*EnterpriseConfig) ProtoMessage() {} func (x *EnterpriseConfig) ProtoReflect() protoreflect.Message { - mi := &file_rpc_proto_msgTypes[41] + mi := &file_rpc_proto_msgTypes[42] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2633,7 +2688,7 @@ func (x *EnterpriseConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use EnterpriseConfig.ProtoReflect.Descriptor instead. func (*EnterpriseConfig) Descriptor() ([]byte, []int) { - return file_rpc_proto_rawDescGZIP(), []int{41} + return file_rpc_proto_rawDescGZIP(), []int{42} } func (x *EnterpriseConfig) GetKey() string { @@ -2689,7 +2744,7 @@ var file_rpc_proto_rawDesc = []byte{ 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xdf, 0x02, 0x0a, 0x09, 0x43, 0x68, + 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xd8, 0x03, 0x0a, 0x09, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x70, 0x4e, 0x75, 0x6d, @@ -2711,385 +2766,400 @@ var file_rpc_proto_rawDesc = []byte{ 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x76, 0x6f, 0x74, 0x69, 0x6e, 0x67, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0c, 0x76, 0x6f, 0x74, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x77, 0x61, 0x72, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x76, - 0x6f, 0x74, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x77, 0x61, 0x72, 0x64, 0x22, 0x24, 0x0a, 0x0a, 0x43, - 0x68, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x22, 0x63, 0x0a, 0x05, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, - 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x18, - 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, - 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, - 0x0a, 0x06, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0x66, 0x0a, 0x06, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0x07, - 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x23, 0x0a, 0x0b, 0x53, 0x69, 0x6e, 0x67, 0x6c, - 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x24, 0x0a, 0x0c, - 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x22, 0x26, 0x0a, 0x0e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x5e, 0x0a, 0x0e, 0x41, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x6e, 0x64, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x18, 0x0a, 0x07, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x41, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x52, 0x6f, 0x6f, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x43, 0x6f, - 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, - 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x22, 0xdd, 0x02, 0x0a, 0x04, 0x50, - 0x65, 0x65, 0x72, 0x12, 0x2c, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x65, 0x65, - 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x12, 0x33, 0x0a, 0x09, 0x62, 0x65, 0x73, 0x74, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4e, 0x65, 0x77, - 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x6f, 0x74, 0x69, 0x63, 0x65, 0x52, 0x09, 0x62, 0x65, 0x73, - 0x74, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, - 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x68, 0x69, - 0x64, 0x64, 0x65, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x61, 0x73, 0x68, 0x43, 0x68, 0x65, 0x63, - 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6c, 0x61, 0x73, 0x68, 0x43, 0x68, 0x65, - 0x63, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x6c, 0x66, 0x70, 0x65, 0x65, 0x72, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, 0x65, 0x6c, 0x66, 0x70, 0x65, 0x65, 0x72, 0x12, 0x18, - 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3b, 0x0a, 0x0c, 0x63, 0x65, 0x72, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x0c, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x73, 0x12, 0x33, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, - 0x64, 0x52, 0x6f, 0x6c, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x0c, 0x61, 0x63, - 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x52, 0x6f, 0x6c, 0x65, 0x22, 0x2d, 0x0a, 0x08, 0x50, 0x65, - 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x05, 0x70, 0x65, 0x65, 0x72, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x65, - 0x65, 0x72, 0x52, 0x05, 0x70, 0x65, 0x65, 0x72, 0x73, 0x22, 0x76, 0x0a, 0x0a, 0x4c, 0x69, 0x73, - 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x68, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, - 0x67, 0x68, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, - 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, - 0x10, 0x0a, 0x03, 0x61, 0x73, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, 0x73, - 0x63, 0x22, 0x38, 0x0a, 0x0a, 0x50, 0x61, 0x67, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, - 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x78, 0x0a, 0x0e, 0x42, - 0x6c, 0x6f, 0x63, 0x6b, 0x42, 0x6f, 0x64, 0x79, 0x50, 0x61, 0x67, 0x65, 0x64, 0x12, 0x14, 0x0a, - 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x74, 0x6f, - 0x74, 0x61, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, - 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, - 0x24, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x42, 0x6f, 0x64, 0x79, 0x52, - 0x04, 0x62, 0x6f, 0x64, 0x79, 0x22, 0x60, 0x0a, 0x0f, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x42, 0x6f, - 0x64, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x68, 0x61, 0x73, 0x68, - 0x6f, 0x72, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, - 0x68, 0x61, 0x73, 0x68, 0x6f, 0x72, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x06, - 0x70, 0x61, 0x67, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, - 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, - 0x06, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x67, 0x22, 0x37, 0x0a, 0x0f, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x06, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x06, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, - 0x22, 0x7d, 0x0a, 0x0d, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x2a, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x42, 0x6c, - 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, - 0x72, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x78, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x07, 0x74, 0x78, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, - 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, - 0x41, 0x0a, 0x11, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x4c, 0x69, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x06, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x06, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x73, 0x22, 0x65, 0x0a, 0x0c, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x29, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x22, 0x41, 0x0a, 0x10, 0x43, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x2d, 0x0a, - 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x54, 0x0a, 0x0c, - 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x19, 0x0a, 0x02, - 0x74, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x54, 0x78, 0x52, 0x02, 0x74, 0x78, 0x12, 0x29, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x56, - 0x65, 0x72, 0x69, 0x66, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x05, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x22, 0x54, 0x0a, 0x08, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x12, 0x1e, - 0x0a, 0x0a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x12, 0x28, - 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, - 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x98, 0x01, 0x0a, 0x0c, 0x49, 0x6d, 0x70, - 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x24, 0x0a, 0x03, 0x77, 0x69, 0x66, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, - 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x03, 0x77, 0x69, 0x66, 0x12, - 0x18, 0x0a, 0x07, 0x6f, 0x6c, 0x64, 0x70, 0x61, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x6f, 0x6c, 0x64, 0x70, 0x61, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, 0x77, - 0x70, 0x61, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x77, 0x70, - 0x61, 0x73, 0x73, 0x12, 0x2e, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x69, - 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x74, - 0x6f, 0x72, 0x65, 0x22, 0x35, 0x0a, 0x07, 0x53, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x12, 0x16, - 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, - 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x68, 0x65, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x77, 0x68, 0x65, 0x6e, 0x22, 0x3c, 0x0a, 0x04, 0x56, 0x6f, - 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74, 0x65, - 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x32, 0x0a, 0x0a, 0x56, 0x6f, 0x74, 0x65, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x64, 0x0a, 0x0f, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x56, 0x6f, 0x74, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, - 0x28, 0x0a, 0x07, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, - 0x52, 0x07, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x12, 0x27, 0x0a, 0x06, 0x76, 0x6f, 0x74, - 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, - 0x73, 0x2e, 0x56, 0x6f, 0x74, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x76, 0x6f, 0x74, 0x69, - 0x6e, 0x67, 0x22, 0x52, 0x0a, 0x08, 0x56, 0x6f, 0x74, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0e, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1e, - 0x0a, 0x0a, 0x63, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x0a, 0x63, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x16, - 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3d, 0x0a, 0x08, 0x56, 0x6f, 0x74, 0x65, 0x4c, 0x69, - 0x73, 0x74, 0x12, 0x21, 0x0a, 0x05, 0x76, 0x6f, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x0b, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x56, 0x6f, 0x74, 0x65, 0x52, 0x05, - 0x76, 0x6f, 0x74, 0x65, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x41, 0x0a, 0x07, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, - 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, - 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, - 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x22, 0x34, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x6f, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x6f, 0x22, 0x63, - 0x0a, 0x08, 0x4e, 0x61, 0x6d, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1f, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6f, - 0x77, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, - 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x22, 0x45, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72, 0x73, 0x50, 0x61, 0x72, 0x61, - 0x6d, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x6f, 0x48, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x48, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x12, 0x1a, - 0x0a, 0x08, 0x73, 0x68, 0x6f, 0x77, 0x53, 0x65, 0x6c, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x08, 0x73, 0x68, 0x6f, 0x77, 0x53, 0x65, 0x6c, 0x66, 0x22, 0x1d, 0x0a, 0x09, 0x4b, 0x65, - 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x83, 0x02, 0x0a, 0x0a, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x35, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, - 0x35, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x6f, 0x74, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x77, 0x61, 0x72, 0x64, 0x12, 0x3a, 0x0a, 0x08, 0x68, + 0x61, 0x72, 0x64, 0x66, 0x6f, 0x72, 0x6b, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x2e, + 0x48, 0x61, 0x72, 0x64, 0x66, 0x6f, 0x72, 0x6b, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x68, + 0x61, 0x72, 0x64, 0x66, 0x6f, 0x72, 0x6b, 0x1a, 0x3b, 0x0a, 0x0d, 0x48, 0x61, 0x72, 0x64, 0x66, + 0x6f, 0x72, 0x6b, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x22, 0x24, 0x0a, 0x0a, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x61, + 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x63, 0x0a, 0x05, 0x49, 0x6e, + 0x70, 0x75, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, + 0x66, 0x0a, 0x06, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, + 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, + 0x16, 0x0a, 0x06, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x06, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x22, 0x23, 0x0a, 0x0b, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x24, 0x0a, 0x0c, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x53, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x26, 0x0a, 0x0e, 0x41, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x22, 0x5e, 0x0a, 0x0e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x6e, + 0x64, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x52, 0x6f, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x52, + 0x6f, 0x6f, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, + 0x73, 0x65, 0x64, 0x22, 0xdd, 0x02, 0x0a, 0x04, 0x50, 0x65, 0x65, 0x72, 0x12, 0x2c, 0x0a, 0x07, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x33, 0x0a, 0x09, 0x62, 0x65, + 0x73, 0x74, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4e, 0x65, 0x77, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x6f, + 0x74, 0x69, 0x63, 0x65, 0x52, 0x09, 0x62, 0x65, 0x73, 0x74, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x12, + 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x12, 0x1c, 0x0a, + 0x09, 0x6c, 0x61, 0x73, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x09, 0x6c, 0x61, 0x73, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x73, + 0x65, 0x6c, 0x66, 0x70, 0x65, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, + 0x65, 0x6c, 0x66, 0x70, 0x65, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x3b, 0x0a, 0x0c, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, + 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x52, 0x0c, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x12, 0x33, + 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x52, 0x6f, 0x6c, 0x65, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x65, 0x65, + 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x52, + 0x6f, 0x6c, 0x65, 0x22, 0x2d, 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, + 0x21, 0x0a, 0x05, 0x70, 0x65, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x05, 0x70, 0x65, 0x65, + 0x72, 0x73, 0x22, 0x76, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, + 0x68, 0x61, 0x73, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x12, 0x0a, 0x04, + 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, + 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x73, 0x63, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, 0x73, 0x63, 0x22, 0x38, 0x0a, 0x0a, 0x50, 0x61, + 0x67, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, + 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, + 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, + 0x73, 0x69, 0x7a, 0x65, 0x22, 0x2c, 0x0a, 0x10, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x4e, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x4e, 0x6f, 0x22, 0x78, 0x0a, 0x0e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x42, 0x6f, 0x64, 0x79, 0x50, + 0x61, 0x67, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, + 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, + 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x24, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x22, 0x60, 0x0a, 0x0f, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x42, 0x6f, 0x64, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, + 0x22, 0x0a, 0x0c, 0x68, 0x61, 0x73, 0x68, 0x6f, 0x72, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x68, 0x61, 0x73, 0x68, 0x6f, 0x72, 0x6e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x06, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x61, 0x67, 0x65, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x06, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x67, 0x22, 0x37, + 0x0a, 0x0f, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4c, 0x69, 0x73, + 0x74, 0x12, 0x24, 0x0a, 0x06, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x0c, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, + 0x06, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x22, 0x7d, 0x0a, 0x0d, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x2a, 0x0a, 0x06, + 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x78, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x74, 0x78, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x41, 0x0a, 0x11, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x06, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x52, 0x06, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x22, 0x65, 0x0a, 0x0c, 0x43, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, + 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x29, 0x0a, + 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x65, 0x74, 0x61, + 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, + 0x22, 0x41, 0x0a, 0x10, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x4c, 0x69, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x73, 0x22, 0x54, 0x0a, 0x0c, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x12, 0x19, 0x0a, 0x02, 0x74, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x09, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x54, 0x78, 0x52, 0x02, 0x74, 0x78, 0x12, 0x29, + 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x54, 0x0a, 0x08, 0x50, 0x65, 0x72, + 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, + 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x73, 0x73, 0x70, + 0x68, 0x72, 0x61, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, + 0x98, 0x01, 0x0a, 0x0c, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x12, 0x24, 0x0a, 0x03, 0x77, 0x69, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, + 0x73, 0x52, 0x03, 0x77, 0x69, 0x66, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x6c, 0x64, 0x70, 0x61, 0x73, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x6c, 0x64, 0x70, 0x61, 0x73, 0x73, + 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, 0x77, 0x70, 0x61, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x6e, 0x65, 0x77, 0x70, 0x61, 0x73, 0x73, 0x12, 0x2e, 0x0a, 0x08, 0x6b, 0x65, + 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, + 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x22, 0x35, 0x0a, 0x07, 0x53, 0x74, + 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x77, 0x68, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x77, 0x68, 0x65, + 0x6e, 0x22, 0x3c, 0x0a, 0x04, 0x56, 0x6f, 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x61, 0x6e, + 0x64, 0x69, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x61, + 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, + 0x32, 0x0a, 0x0a, 0x56, 0x6f, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, + 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x22, 0x64, 0x0a, 0x0f, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x56, 0x6f, + 0x74, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x28, 0x0a, 0x07, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, + 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, + 0x53, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, + 0x12, 0x27, 0x0a, 0x06, 0x76, 0x6f, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x56, 0x6f, 0x74, 0x65, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x06, 0x76, 0x6f, 0x74, 0x69, 0x6e, 0x67, 0x22, 0x52, 0x0a, 0x08, 0x56, 0x6f, 0x74, + 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, + 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x61, 0x6e, 0x64, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3d, 0x0a, + 0x08, 0x56, 0x6f, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x05, 0x76, 0x6f, 0x74, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x2e, 0x56, 0x6f, 0x74, 0x65, 0x52, 0x05, 0x76, 0x6f, 0x74, 0x65, 0x73, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x41, 0x0a, 0x07, + 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, + 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, + 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x22, + 0x34, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x4e, 0x6f, 0x22, 0x63, 0x0a, 0x08, 0x4e, 0x61, 0x6d, 0x65, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x1f, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0b, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x64, + 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x45, 0x0a, 0x0b, 0x50, 0x65, + 0x65, 0x72, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x6f, 0x48, + 0x69, 0x64, 0x64, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x48, + 0x69, 0x64, 0x64, 0x65, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x68, 0x6f, 0x77, 0x53, 0x65, 0x6c, + 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, 0x68, 0x6f, 0x77, 0x53, 0x65, 0x6c, + 0x66, 0x22, 0x1d, 0x0a, 0x09, 0x4b, 0x65, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x22, 0x83, 0x02, 0x0a, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x35, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x6e, - 0x66, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x39, 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x1a, 0x4c, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x12, 0x27, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, - 0x7a, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x32, 0x0a, - 0x05, 0x70, 0x72, 0x6f, 0x70, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, - 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x74, 0x65, 0x6d, 0x2e, - 0x50, 0x72, 0x6f, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x70, - 0x73, 0x1a, 0x38, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x31, 0x0a, 0x09, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x49, - 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, - 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x10, 0x0a, 0x03, 0x62, 0x70, 0x73, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x62, 0x70, 0x73, 0x22, 0x27, 0x0a, 0x13, 0x45, 0x6e, 0x74, - 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4b, 0x65, 0x79, - 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x22, 0x4c, 0x0a, 0x10, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, - 0x2a, 0xd2, 0x01, 0x0a, 0x0c, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x58, 0x5f, 0x4f, 0x4b, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, - 0x54, 0x58, 0x5f, 0x4e, 0x4f, 0x4e, 0x43, 0x45, 0x5f, 0x54, 0x4f, 0x4f, 0x5f, 0x4c, 0x4f, 0x57, - 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x58, 0x5f, 0x41, 0x4c, 0x52, 0x45, 0x41, 0x44, 0x59, - 0x5f, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x54, 0x58, 0x5f, - 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x10, 0x03, 0x12, 0x13, - 0x0a, 0x0f, 0x54, 0x58, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x49, 0x47, - 0x4e, 0x10, 0x04, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x58, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, - 0x44, 0x5f, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x10, 0x05, 0x12, 0x1b, 0x0a, 0x17, 0x54, 0x58, - 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x42, 0x41, - 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x06, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x58, 0x5f, 0x48, 0x41, - 0x53, 0x5f, 0x53, 0x41, 0x4d, 0x45, 0x5f, 0x4e, 0x4f, 0x4e, 0x43, 0x45, 0x10, 0x07, 0x12, 0x15, - 0x0a, 0x11, 0x54, 0x58, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f, 0x45, 0x52, - 0x52, 0x4f, 0x52, 0x10, 0x09, 0x2a, 0x66, 0x0a, 0x0c, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x10, 0x56, 0x45, 0x52, 0x49, 0x46, 0x59, 0x5f, - 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4f, 0x4b, 0x10, 0x00, 0x12, 0x20, 0x0a, 0x1c, 0x56, - 0x45, 0x52, 0x49, 0x46, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x53, 0x49, 0x47, - 0x4e, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x01, 0x12, 0x1e, 0x0a, - 0x1a, 0x56, 0x45, 0x52, 0x49, 0x46, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x49, - 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x10, 0x02, 0x32, 0x9b, 0x12, - 0x0a, 0x0f, 0x41, 0x65, 0x72, 0x67, 0x6f, 0x52, 0x50, 0x43, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x31, 0x0a, 0x09, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x12, + 0x66, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x35, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x39, 0x0a, + 0x0b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4c, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x27, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x7a, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x49, 0x74, 0x65, 0x6d, 0x12, 0x32, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x70, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x70, 0x73, 0x1a, 0x38, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x70, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, + 0x38, 0x01, 0x22, 0x31, 0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, + 0x24, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x0c, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x49, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, + 0x75, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x6e, + 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x10, + 0x0a, 0x03, 0x62, 0x70, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x62, 0x70, 0x73, + 0x22, 0x27, 0x0a, 0x13, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x4c, 0x0a, 0x10, 0x45, 0x6e, 0x74, + 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x0e, 0x0a, 0x02, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6e, 0x12, + 0x16, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2a, 0xd2, 0x01, 0x0a, 0x0c, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x58, 0x5f, 0x4f, + 0x4b, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x58, 0x5f, 0x4e, 0x4f, 0x4e, 0x43, 0x45, 0x5f, + 0x54, 0x4f, 0x4f, 0x5f, 0x4c, 0x4f, 0x57, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x58, 0x5f, + 0x41, 0x4c, 0x52, 0x45, 0x41, 0x44, 0x59, 0x5f, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x10, 0x02, + 0x12, 0x13, 0x0a, 0x0f, 0x54, 0x58, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x48, + 0x41, 0x53, 0x48, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x54, 0x58, 0x5f, 0x49, 0x4e, 0x56, 0x41, + 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x10, 0x04, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x58, + 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x10, + 0x05, 0x12, 0x1b, 0x0a, 0x17, 0x54, 0x58, 0x5f, 0x49, 0x4e, 0x53, 0x55, 0x46, 0x46, 0x49, 0x43, + 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x06, 0x12, 0x15, + 0x0a, 0x11, 0x54, 0x58, 0x5f, 0x48, 0x41, 0x53, 0x5f, 0x53, 0x41, 0x4d, 0x45, 0x5f, 0x4e, 0x4f, + 0x4e, 0x43, 0x45, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x58, 0x5f, 0x49, 0x4e, 0x54, 0x45, + 0x52, 0x4e, 0x41, 0x4c, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x09, 0x2a, 0x66, 0x0a, 0x0c, + 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x10, + 0x56, 0x45, 0x52, 0x49, 0x46, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4f, 0x4b, + 0x10, 0x00, 0x12, 0x20, 0x0a, 0x1c, 0x56, 0x45, 0x52, 0x49, 0x46, 0x59, 0x5f, 0x53, 0x54, 0x41, + 0x54, 0x55, 0x53, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x4d, 0x41, 0x54, + 0x43, 0x48, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, 0x56, 0x45, 0x52, 0x49, 0x46, 0x59, 0x5f, 0x53, + 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x48, 0x41, + 0x53, 0x48, 0x10, 0x02, 0x32, 0xe3, 0x12, 0x0a, 0x0f, 0x41, 0x65, 0x72, 0x67, 0x6f, 0x52, 0x50, + 0x43, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x31, 0x0a, 0x09, 0x4e, 0x6f, 0x64, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4e, 0x6f, + 0x64, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x69, + 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x06, 0x4d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x15, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4d, 0x65, + 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x22, 0x00, 0x12, 0x35, + 0x0a, 0x0a, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x0c, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x17, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x22, 0x00, 0x12, 0x30, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x69, + 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0c, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x1a, 0x10, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x68, 0x61, 0x69, + 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x00, 0x12, 0x2e, 0x0a, 0x09, 0x43, 0x68, 0x61, 0x69, 0x6e, + 0x53, 0x74, 0x61, 0x74, 0x12, 0x0c, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, + 0x53, 0x74, 0x61, 0x74, 0x73, 0x22, 0x00, 0x12, 0x3f, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x11, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x16, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x11, 0x2e, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x1a, 0x18, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x0f, + 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, + 0x0c, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0c, 0x2e, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x00, 0x30, 0x01, 0x12, + 0x41, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x0c, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x14, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x00, + 0x30, 0x01, 0x12, 0x2e, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, - 0x65, 0x73, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x15, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4d, 0x65, - 0x74, 0x72, 0x69, 0x63, 0x73, 0x22, 0x00, 0x12, 0x35, 0x0a, 0x0a, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x0c, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x1a, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, - 0x6b, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x00, 0x12, 0x30, - 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0c, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x10, 0x2e, 0x74, - 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x00, - 0x12, 0x2e, 0x0a, 0x09, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x12, 0x0c, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x22, 0x00, - 0x12, 0x3f, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, - 0x64, 0x65, 0x72, 0x73, 0x12, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x16, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, - 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x22, - 0x00, 0x12, 0x42, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x18, 0x2e, 0x74, 0x79, 0x70, 0x65, - 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4c, - 0x69, 0x73, 0x74, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x0c, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0c, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x42, - 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x00, 0x30, 0x01, 0x12, 0x41, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, - 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x53, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x12, 0x0c, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x1a, 0x14, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x00, 0x30, 0x01, 0x12, 0x2e, 0x0a, 0x08, 0x47, - 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, - 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x1a, 0x0c, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x10, 0x47, - 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, - 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, - 0x74, 0x65, 0x73, 0x1a, 0x14, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, - 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x00, 0x12, 0x3f, 0x0a, 0x0c, 0x47, - 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x16, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x42, 0x6f, 0x64, 0x79, 0x50, 0x61, 0x72, - 0x61, 0x6d, 0x73, 0x1a, 0x15, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, - 0x6b, 0x42, 0x6f, 0x64, 0x79, 0x50, 0x61, 0x67, 0x65, 0x64, 0x22, 0x00, 0x12, 0x28, 0x0a, 0x05, - 0x47, 0x65, 0x74, 0x54, 0x58, 0x12, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x69, - 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x1a, 0x09, 0x2e, 0x74, 0x79, 0x70, 0x65, - 0x73, 0x2e, 0x54, 0x78, 0x22, 0x00, 0x12, 0x34, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x54, 0x58, 0x12, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x69, 0x6e, - 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x1a, 0x10, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x54, 0x78, 0x49, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x00, 0x12, 0x32, 0x0a, 0x0a, - 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x12, 0x12, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x73, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x1a, 0x0e, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x22, 0x00, - 0x12, 0x2a, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x41, 0x42, 0x49, 0x12, 0x12, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x73, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x1a, 0x0a, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x42, 0x49, 0x22, 0x00, 0x12, 0x2a, 0x0a, 0x06, - 0x53, 0x65, 0x6e, 0x64, 0x54, 0x58, 0x12, 0x09, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x54, - 0x78, 0x1a, 0x13, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, 0x12, 0x20, 0x0a, 0x06, 0x53, 0x69, 0x67, 0x6e, - 0x54, 0x58, 0x12, 0x09, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x54, 0x78, 0x1a, 0x09, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x54, 0x78, 0x22, 0x00, 0x12, 0x2c, 0x0a, 0x08, 0x56, 0x65, - 0x72, 0x69, 0x66, 0x79, 0x54, 0x58, 0x12, 0x09, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x54, - 0x78, 0x1a, 0x13, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, 0x12, 0x34, 0x0a, 0x08, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x54, 0x58, 0x12, 0x0d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x54, 0x78, 0x4c, - 0x69, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x12, 0x2e, - 0x0a, 0x08, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x12, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x73, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x1a, 0x0c, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x00, 0x12, 0x40, - 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x41, 0x6e, 0x64, 0x50, 0x72, 0x6f, - 0x6f, 0x66, 0x12, 0x15, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x41, 0x6e, 0x64, 0x52, 0x6f, 0x6f, 0x74, 0x1a, 0x13, 0x2e, 0x74, 0x79, 0x70, 0x65, - 0x73, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x22, 0x00, - 0x12, 0x32, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x12, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, - 0x61, 0x6c, 0x1a, 0x0e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x73, 0x12, 0x0c, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x1a, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x12, 0x30, 0x0a, 0x0b, 0x4c, 0x6f, 0x63, 0x6b, 0x41, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, - 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x1a, 0x0e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x00, 0x12, 0x32, 0x0a, 0x0d, 0x55, 0x6e, 0x6c, - 0x6f, 0x63, 0x6b, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x0f, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x73, 0x2e, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x1a, 0x0e, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x00, 0x12, 0x36, 0x0a, - 0x0d, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x13, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, - 0x6d, 0x61, 0x74, 0x1a, 0x0e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x0d, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x41, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, - 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x1a, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, - 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x00, 0x12, 0x3e, 0x0a, - 0x15, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4b, 0x65, - 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, - 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x1a, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, - 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x00, 0x12, 0x33, 0x0a, - 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x12, 0x0c, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x1a, 0x12, 0x2e, 0x74, + 0x65, 0x73, 0x1a, 0x0c, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, + 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x1a, 0x14, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x22, 0x00, 0x12, 0x3f, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x42, 0x6f, + 0x64, 0x79, 0x12, 0x16, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x42, 0x6f, 0x64, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x15, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x42, 0x6f, 0x64, 0x79, 0x50, 0x61, 0x67, 0x65, + 0x64, 0x22, 0x00, 0x12, 0x28, 0x0a, 0x05, 0x47, 0x65, 0x74, 0x54, 0x58, 0x12, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, - 0x22, 0x00, 0x12, 0x41, 0x0a, 0x12, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x72, - 0x61, 0x63, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x1a, 0x16, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, - 0x6f, 0x6f, 0x66, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x50, 0x65, 0x65, 0x72, - 0x73, 0x12, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x50, - 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x65, - 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x12, 0x30, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x56, - 0x6f, 0x74, 0x65, 0x73, 0x12, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x56, 0x6f, 0x74, - 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, - 0x56, 0x6f, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x0f, 0x47, 0x65, - 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x56, 0x6f, 0x74, 0x65, 0x73, 0x12, 0x15, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x1a, 0x16, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x56, 0x6f, 0x74, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x00, 0x12, 0x35, - 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x12, 0x15, 0x2e, 0x74, + 0x1a, 0x09, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x54, 0x78, 0x22, 0x00, 0x12, 0x34, 0x0a, + 0x0a, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x58, 0x12, 0x12, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x1a, + 0x10, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x54, 0x78, 0x49, 0x6e, 0x42, 0x6c, 0x6f, 0x63, + 0x6b, 0x22, 0x00, 0x12, 0x32, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, + 0x74, 0x12, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, + 0x42, 0x79, 0x74, 0x65, 0x73, 0x1a, 0x0e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x52, 0x65, + 0x63, 0x65, 0x69, 0x70, 0x74, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x49, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x1a, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x00, 0x12, + 0x2a, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x41, 0x42, 0x49, 0x12, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x1a, 0x0a, 0x2e, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x42, 0x49, 0x22, 0x00, 0x12, 0x2a, 0x0a, 0x06, 0x53, + 0x65, 0x6e, 0x64, 0x54, 0x58, 0x12, 0x09, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x54, 0x78, + 0x1a, 0x13, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, 0x12, 0x20, 0x0a, 0x06, 0x53, 0x69, 0x67, 0x6e, 0x54, + 0x58, 0x12, 0x09, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x54, 0x78, 0x1a, 0x09, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x2e, 0x54, 0x78, 0x22, 0x00, 0x12, 0x2c, 0x0a, 0x08, 0x56, 0x65, 0x72, + 0x69, 0x66, 0x79, 0x54, 0x58, 0x12, 0x09, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x54, 0x78, + 0x1a, 0x13, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, 0x12, 0x34, 0x0a, 0x08, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x54, 0x58, 0x12, 0x0d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x54, 0x78, 0x4c, 0x69, + 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x12, 0x2e, 0x0a, + 0x08, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x1a, 0x0c, 0x2e, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x00, 0x12, 0x40, 0x0a, + 0x10, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x41, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f, + 0x66, 0x12, 0x15, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x41, 0x6e, 0x64, 0x52, 0x6f, 0x6f, 0x74, 0x1a, 0x13, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x22, 0x00, 0x12, + 0x32, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, + 0x6c, 0x1a, 0x0e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x73, 0x12, 0x0c, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x1a, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x12, 0x30, 0x0a, 0x0b, 0x4c, 0x6f, 0x63, 0x6b, 0x41, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x65, + 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x1a, 0x0e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x00, 0x12, 0x32, 0x0a, 0x0d, 0x55, 0x6e, 0x6c, 0x6f, + 0x63, 0x6b, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2e, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x1a, 0x0e, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x0d, + 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x13, 0x2e, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x6f, 0x72, 0x6d, + 0x61, 0x74, 0x1a, 0x0e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x0d, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x41, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x65, + 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x1a, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, + 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x15, + 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4b, 0x65, 0x79, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x65, + 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x1a, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, + 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x00, 0x12, 0x33, 0x0a, 0x0d, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x12, 0x0c, 0x2e, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x1a, 0x12, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, + 0x00, 0x12, 0x41, 0x0a, 0x12, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, + 0x63, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x1a, 0x16, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, + 0x6f, 0x66, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x50, 0x65, 0x65, 0x72, 0x73, + 0x12, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x65, 0x65, + 0x72, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x12, 0x30, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x56, 0x6f, + 0x74, 0x65, 0x73, 0x12, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x56, 0x6f, 0x74, 0x65, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x56, + 0x6f, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x0f, 0x47, 0x65, 0x74, + 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x56, 0x6f, 0x74, 0x65, 0x73, 0x12, 0x15, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x1a, 0x0e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x6b, - 0x69, 0x6e, 0x67, 0x22, 0x00, 0x12, 0x2d, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, - 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0b, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4e, 0x61, 0x6d, - 0x65, 0x1a, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x49, 0x6e, - 0x66, 0x6f, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, - 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x0c, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x73, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x00, 0x30, 0x01, 0x12, 0x33, 0x0a, 0x0a, - 0x4c, 0x69, 0x73, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x11, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x10, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x22, - 0x00, 0x12, 0x36, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x6e, - 0x66, 0x6f, 0x12, 0x10, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4b, 0x65, 0x79, 0x50, 0x61, - 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x10, 0x47, 0x65, 0x74, - 0x43, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0c, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x14, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x49, 0x6e, 0x66, - 0x6f, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, - 0x72, 0x69, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x4b, 0x65, 0x79, 0x1a, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, - 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, - 0x00, 0x12, 0x48, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x73, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x1a, 0x19, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x43, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x22, 0x00, 0x42, 0x08, 0x5a, 0x06, 0x2f, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x73, 0x73, 0x1a, 0x16, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x56, 0x6f, 0x74, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x00, 0x12, 0x35, 0x0a, + 0x0a, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x12, 0x15, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x1a, 0x0e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x6b, 0x69, + 0x6e, 0x67, 0x22, 0x00, 0x12, 0x2d, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x49, + 0x6e, 0x66, 0x6f, 0x12, 0x0b, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, + 0x1a, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x49, 0x6e, 0x66, + 0x6f, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x0c, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x00, 0x30, 0x01, 0x12, 0x33, 0x0a, 0x0a, 0x4c, + 0x69, 0x73, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x10, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, + 0x12, 0x36, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x10, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4b, 0x65, 0x79, 0x50, 0x61, 0x72, + 0x61, 0x6d, 0x73, 0x1a, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x43, + 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0c, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x14, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x49, 0x6e, 0x66, 0x6f, + 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, + 0x69, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x4b, 0x65, 0x79, 0x1a, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x6e, + 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x00, + 0x12, 0x48, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x43, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x1a, 0x19, 0x2e, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x22, 0x00, 0x42, 0x08, 0x5a, 0x06, 0x2f, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3105,7 +3175,7 @@ func file_rpc_proto_rawDescGZIP() []byte { } var file_rpc_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_rpc_proto_msgTypes = make([]protoimpl.MessageInfo, 45) +var file_rpc_proto_msgTypes = make([]protoimpl.MessageInfo, 47) var file_rpc_proto_goTypes = []interface{}{ (CommitStatus)(0), // 0: types.CommitStatus (VerifyStatus)(0), // 1: types.VerifyStatus @@ -3124,179 +3194,184 @@ var file_rpc_proto_goTypes = []interface{}{ (*PeerList)(nil), // 14: types.PeerList (*ListParams)(nil), // 15: types.ListParams (*PageParams)(nil), // 16: types.PageParams - (*BlockBodyPaged)(nil), // 17: types.BlockBodyPaged - (*BlockBodyParams)(nil), // 18: types.BlockBodyParams - (*BlockHeaderList)(nil), // 19: types.BlockHeaderList - (*BlockMetadata)(nil), // 20: types.BlockMetadata - (*BlockMetadataList)(nil), // 21: types.BlockMetadataList - (*CommitResult)(nil), // 22: types.CommitResult - (*CommitResultList)(nil), // 23: types.CommitResultList - (*VerifyResult)(nil), // 24: types.VerifyResult - (*Personal)(nil), // 25: types.Personal - (*ImportFormat)(nil), // 26: types.ImportFormat - (*Staking)(nil), // 27: types.Staking - (*Vote)(nil), // 28: types.Vote - (*VoteParams)(nil), // 29: types.VoteParams - (*AccountVoteInfo)(nil), // 30: types.AccountVoteInfo - (*VoteInfo)(nil), // 31: types.VoteInfo - (*VoteList)(nil), // 32: types.VoteList - (*NodeReq)(nil), // 33: types.NodeReq - (*Name)(nil), // 34: types.Name - (*NameInfo)(nil), // 35: types.NameInfo - (*PeersParams)(nil), // 36: types.PeersParams - (*KeyParams)(nil), // 37: types.KeyParams - (*ServerInfo)(nil), // 38: types.ServerInfo - (*ConfigItem)(nil), // 39: types.ConfigItem - (*EventList)(nil), // 40: types.EventList - (*ConsensusInfo)(nil), // 41: types.ConsensusInfo - (*EnterpriseConfigKey)(nil), // 42: types.EnterpriseConfigKey - (*EnterpriseConfig)(nil), // 43: types.EnterpriseConfig - nil, // 44: types.ServerInfo.StatusEntry - nil, // 45: types.ServerInfo.ConfigEntry - nil, // 46: types.ConfigItem.PropsEntry - (*PeerAddress)(nil), // 47: types.PeerAddress - (*NewBlockNotice)(nil), // 48: types.NewBlockNotice - (*AgentCertificate)(nil), // 49: types.AgentCertificate - (PeerRole)(0), // 50: types.PeerRole - (*BlockBody)(nil), // 51: types.BlockBody - (*Block)(nil), // 52: types.Block - (*BlockHeader)(nil), // 53: types.BlockHeader - (*Tx)(nil), // 54: types.Tx - (*Account)(nil), // 55: types.Account - (*Event)(nil), // 56: types.Event - (*MetricsRequest)(nil), // 57: types.MetricsRequest - (*TxList)(nil), // 58: types.TxList - (*Query)(nil), // 59: types.Query - (*StateQuery)(nil), // 60: types.StateQuery - (*FilterInfo)(nil), // 61: types.FilterInfo - (*Metrics)(nil), // 62: types.Metrics - (*TxInBlock)(nil), // 63: types.TxInBlock - (*Receipt)(nil), // 64: types.Receipt - (*ABI)(nil), // 65: types.ABI - (*State)(nil), // 66: types.State - (*AccountProof)(nil), // 67: types.AccountProof - (*AccountList)(nil), // 68: types.AccountList - (*StateQueryProof)(nil), // 69: types.StateQueryProof - (*ConfChangeProgress)(nil), // 70: types.ConfChangeProgress + (*BlockNumberParam)(nil), // 17: types.BlockNumberParam + (*BlockBodyPaged)(nil), // 18: types.BlockBodyPaged + (*BlockBodyParams)(nil), // 19: types.BlockBodyParams + (*BlockHeaderList)(nil), // 20: types.BlockHeaderList + (*BlockMetadata)(nil), // 21: types.BlockMetadata + (*BlockMetadataList)(nil), // 22: types.BlockMetadataList + (*CommitResult)(nil), // 23: types.CommitResult + (*CommitResultList)(nil), // 24: types.CommitResultList + (*VerifyResult)(nil), // 25: types.VerifyResult + (*Personal)(nil), // 26: types.Personal + (*ImportFormat)(nil), // 27: types.ImportFormat + (*Staking)(nil), // 28: types.Staking + (*Vote)(nil), // 29: types.Vote + (*VoteParams)(nil), // 30: types.VoteParams + (*AccountVoteInfo)(nil), // 31: types.AccountVoteInfo + (*VoteInfo)(nil), // 32: types.VoteInfo + (*VoteList)(nil), // 33: types.VoteList + (*NodeReq)(nil), // 34: types.NodeReq + (*Name)(nil), // 35: types.Name + (*NameInfo)(nil), // 36: types.NameInfo + (*PeersParams)(nil), // 37: types.PeersParams + (*KeyParams)(nil), // 38: types.KeyParams + (*ServerInfo)(nil), // 39: types.ServerInfo + (*ConfigItem)(nil), // 40: types.ConfigItem + (*EventList)(nil), // 41: types.EventList + (*ConsensusInfo)(nil), // 42: types.ConsensusInfo + (*EnterpriseConfigKey)(nil), // 43: types.EnterpriseConfigKey + (*EnterpriseConfig)(nil), // 44: types.EnterpriseConfig + nil, // 45: types.ChainInfo.HardforkEntry + nil, // 46: types.ServerInfo.StatusEntry + nil, // 47: types.ServerInfo.ConfigEntry + nil, // 48: types.ConfigItem.PropsEntry + (*PeerAddress)(nil), // 49: types.PeerAddress + (*NewBlockNotice)(nil), // 50: types.NewBlockNotice + (*AgentCertificate)(nil), // 51: types.AgentCertificate + (PeerRole)(0), // 52: types.PeerRole + (*BlockBody)(nil), // 53: types.BlockBody + (*Block)(nil), // 54: types.Block + (*BlockHeader)(nil), // 55: types.BlockHeader + (*Tx)(nil), // 56: types.Tx + (*Account)(nil), // 57: types.Account + (*Event)(nil), // 58: types.Event + (*MetricsRequest)(nil), // 59: types.MetricsRequest + (*TxList)(nil), // 60: types.TxList + (*Query)(nil), // 61: types.Query + (*StateQuery)(nil), // 62: types.StateQuery + (*FilterInfo)(nil), // 63: types.FilterInfo + (*Metrics)(nil), // 64: types.Metrics + (*TxInBlock)(nil), // 65: types.TxInBlock + (*Receipt)(nil), // 66: types.Receipt + (*ABI)(nil), // 67: types.ABI + (*State)(nil), // 68: types.State + (*AccountProof)(nil), // 69: types.AccountProof + (*AccountList)(nil), // 70: types.AccountList + (*StateQueryProof)(nil), // 71: types.StateQueryProof + (*ConfChangeProgress)(nil), // 72: types.ConfChangeProgress } var file_rpc_proto_depIdxs = []int32{ 4, // 0: types.BlockchainStatus.chain_info:type_name -> types.ChainInfo 3, // 1: types.ChainInfo.id:type_name -> types.ChainId - 47, // 2: types.Peer.address:type_name -> types.PeerAddress - 48, // 3: types.Peer.bestblock:type_name -> types.NewBlockNotice - 49, // 4: types.Peer.certificates:type_name -> types.AgentCertificate - 50, // 5: types.Peer.acceptedRole:type_name -> types.PeerRole - 13, // 6: types.PeerList.peers:type_name -> types.Peer - 51, // 7: types.BlockBodyPaged.body:type_name -> types.BlockBody - 16, // 8: types.BlockBodyParams.paging:type_name -> types.PageParams - 52, // 9: types.BlockHeaderList.blocks:type_name -> types.Block - 53, // 10: types.BlockMetadata.header:type_name -> types.BlockHeader - 20, // 11: types.BlockMetadataList.blocks:type_name -> types.BlockMetadata - 0, // 12: types.CommitResult.error:type_name -> types.CommitStatus - 22, // 13: types.CommitResultList.results:type_name -> types.CommitResult - 54, // 14: types.VerifyResult.tx:type_name -> types.Tx - 1, // 15: types.VerifyResult.error:type_name -> types.VerifyStatus - 55, // 16: types.Personal.account:type_name -> types.Account - 9, // 17: types.ImportFormat.wif:type_name -> types.SingleBytes - 9, // 18: types.ImportFormat.keystore:type_name -> types.SingleBytes - 27, // 19: types.AccountVoteInfo.staking:type_name -> types.Staking - 31, // 20: types.AccountVoteInfo.voting:type_name -> types.VoteInfo - 28, // 21: types.VoteList.votes:type_name -> types.Vote - 34, // 22: types.NameInfo.name:type_name -> types.Name - 44, // 23: types.ServerInfo.status:type_name -> types.ServerInfo.StatusEntry - 45, // 24: types.ServerInfo.config:type_name -> types.ServerInfo.ConfigEntry - 46, // 25: types.ConfigItem.props:type_name -> types.ConfigItem.PropsEntry - 56, // 26: types.EventList.events:type_name -> types.Event - 39, // 27: types.ServerInfo.ConfigEntry.value:type_name -> types.ConfigItem - 33, // 28: types.AergoRPCService.NodeState:input_type -> types.NodeReq - 57, // 29: types.AergoRPCService.Metric:input_type -> types.MetricsRequest - 8, // 30: types.AergoRPCService.Blockchain:input_type -> types.Empty - 8, // 31: types.AergoRPCService.GetChainInfo:input_type -> types.Empty - 8, // 32: types.AergoRPCService.ChainStat:input_type -> types.Empty - 15, // 33: types.AergoRPCService.ListBlockHeaders:input_type -> types.ListParams - 15, // 34: types.AergoRPCService.ListBlockMetadata:input_type -> types.ListParams - 8, // 35: types.AergoRPCService.ListBlockStream:input_type -> types.Empty - 8, // 36: types.AergoRPCService.ListBlockMetadataStream:input_type -> types.Empty - 9, // 37: types.AergoRPCService.GetBlock:input_type -> types.SingleBytes - 9, // 38: types.AergoRPCService.GetBlockMetadata:input_type -> types.SingleBytes - 18, // 39: types.AergoRPCService.GetBlockBody:input_type -> types.BlockBodyParams - 9, // 40: types.AergoRPCService.GetTX:input_type -> types.SingleBytes - 9, // 41: types.AergoRPCService.GetBlockTX:input_type -> types.SingleBytes - 9, // 42: types.AergoRPCService.GetReceipt:input_type -> types.SingleBytes - 9, // 43: types.AergoRPCService.GetABI:input_type -> types.SingleBytes - 54, // 44: types.AergoRPCService.SendTX:input_type -> types.Tx - 54, // 45: types.AergoRPCService.SignTX:input_type -> types.Tx - 54, // 46: types.AergoRPCService.VerifyTX:input_type -> types.Tx - 58, // 47: types.AergoRPCService.CommitTX:input_type -> types.TxList - 9, // 48: types.AergoRPCService.GetState:input_type -> types.SingleBytes - 12, // 49: types.AergoRPCService.GetStateAndProof:input_type -> types.AccountAndRoot - 25, // 50: types.AergoRPCService.CreateAccount:input_type -> types.Personal - 8, // 51: types.AergoRPCService.GetAccounts:input_type -> types.Empty - 25, // 52: types.AergoRPCService.LockAccount:input_type -> types.Personal - 25, // 53: types.AergoRPCService.UnlockAccount:input_type -> types.Personal - 26, // 54: types.AergoRPCService.ImportAccount:input_type -> types.ImportFormat - 25, // 55: types.AergoRPCService.ExportAccount:input_type -> types.Personal - 25, // 56: types.AergoRPCService.ExportAccountKeystore:input_type -> types.Personal - 59, // 57: types.AergoRPCService.QueryContract:input_type -> types.Query - 60, // 58: types.AergoRPCService.QueryContractState:input_type -> types.StateQuery - 36, // 59: types.AergoRPCService.GetPeers:input_type -> types.PeersParams - 29, // 60: types.AergoRPCService.GetVotes:input_type -> types.VoteParams - 11, // 61: types.AergoRPCService.GetAccountVotes:input_type -> types.AccountAddress - 11, // 62: types.AergoRPCService.GetStaking:input_type -> types.AccountAddress - 34, // 63: types.AergoRPCService.GetNameInfo:input_type -> types.Name - 61, // 64: types.AergoRPCService.ListEventStream:input_type -> types.FilterInfo - 61, // 65: types.AergoRPCService.ListEvents:input_type -> types.FilterInfo - 37, // 66: types.AergoRPCService.GetServerInfo:input_type -> types.KeyParams - 8, // 67: types.AergoRPCService.GetConsensusInfo:input_type -> types.Empty - 42, // 68: types.AergoRPCService.GetEnterpriseConfig:input_type -> types.EnterpriseConfigKey - 9, // 69: types.AergoRPCService.GetConfChangeProgress:input_type -> types.SingleBytes - 9, // 70: types.AergoRPCService.NodeState:output_type -> types.SingleBytes - 62, // 71: types.AergoRPCService.Metric:output_type -> types.Metrics - 2, // 72: types.AergoRPCService.Blockchain:output_type -> types.BlockchainStatus - 4, // 73: types.AergoRPCService.GetChainInfo:output_type -> types.ChainInfo - 5, // 74: types.AergoRPCService.ChainStat:output_type -> types.ChainStats - 19, // 75: types.AergoRPCService.ListBlockHeaders:output_type -> types.BlockHeaderList - 21, // 76: types.AergoRPCService.ListBlockMetadata:output_type -> types.BlockMetadataList - 52, // 77: types.AergoRPCService.ListBlockStream:output_type -> types.Block - 20, // 78: types.AergoRPCService.ListBlockMetadataStream:output_type -> types.BlockMetadata - 52, // 79: types.AergoRPCService.GetBlock:output_type -> types.Block - 20, // 80: types.AergoRPCService.GetBlockMetadata:output_type -> types.BlockMetadata - 17, // 81: types.AergoRPCService.GetBlockBody:output_type -> types.BlockBodyPaged - 54, // 82: types.AergoRPCService.GetTX:output_type -> types.Tx - 63, // 83: types.AergoRPCService.GetBlockTX:output_type -> types.TxInBlock - 64, // 84: types.AergoRPCService.GetReceipt:output_type -> types.Receipt - 65, // 85: types.AergoRPCService.GetABI:output_type -> types.ABI - 22, // 86: types.AergoRPCService.SendTX:output_type -> types.CommitResult - 54, // 87: types.AergoRPCService.SignTX:output_type -> types.Tx - 24, // 88: types.AergoRPCService.VerifyTX:output_type -> types.VerifyResult - 23, // 89: types.AergoRPCService.CommitTX:output_type -> types.CommitResultList - 66, // 90: types.AergoRPCService.GetState:output_type -> types.State - 67, // 91: types.AergoRPCService.GetStateAndProof:output_type -> types.AccountProof - 55, // 92: types.AergoRPCService.CreateAccount:output_type -> types.Account - 68, // 93: types.AergoRPCService.GetAccounts:output_type -> types.AccountList - 55, // 94: types.AergoRPCService.LockAccount:output_type -> types.Account - 55, // 95: types.AergoRPCService.UnlockAccount:output_type -> types.Account - 55, // 96: types.AergoRPCService.ImportAccount:output_type -> types.Account - 9, // 97: types.AergoRPCService.ExportAccount:output_type -> types.SingleBytes - 9, // 98: types.AergoRPCService.ExportAccountKeystore:output_type -> types.SingleBytes - 9, // 99: types.AergoRPCService.QueryContract:output_type -> types.SingleBytes - 69, // 100: types.AergoRPCService.QueryContractState:output_type -> types.StateQueryProof - 14, // 101: types.AergoRPCService.GetPeers:output_type -> types.PeerList - 32, // 102: types.AergoRPCService.GetVotes:output_type -> types.VoteList - 30, // 103: types.AergoRPCService.GetAccountVotes:output_type -> types.AccountVoteInfo - 27, // 104: types.AergoRPCService.GetStaking:output_type -> types.Staking - 35, // 105: types.AergoRPCService.GetNameInfo:output_type -> types.NameInfo - 56, // 106: types.AergoRPCService.ListEventStream:output_type -> types.Event - 40, // 107: types.AergoRPCService.ListEvents:output_type -> types.EventList - 38, // 108: types.AergoRPCService.GetServerInfo:output_type -> types.ServerInfo - 41, // 109: types.AergoRPCService.GetConsensusInfo:output_type -> types.ConsensusInfo - 43, // 110: types.AergoRPCService.GetEnterpriseConfig:output_type -> types.EnterpriseConfig - 70, // 111: types.AergoRPCService.GetConfChangeProgress:output_type -> types.ConfChangeProgress - 70, // [70:112] is the sub-list for method output_type - 28, // [28:70] is the sub-list for method input_type - 28, // [28:28] is the sub-list for extension type_name - 28, // [28:28] is the sub-list for extension extendee - 0, // [0:28] is the sub-list for field type_name + 45, // 2: types.ChainInfo.hardfork:type_name -> types.ChainInfo.HardforkEntry + 49, // 3: types.Peer.address:type_name -> types.PeerAddress + 50, // 4: types.Peer.bestblock:type_name -> types.NewBlockNotice + 51, // 5: types.Peer.certificates:type_name -> types.AgentCertificate + 52, // 6: types.Peer.acceptedRole:type_name -> types.PeerRole + 13, // 7: types.PeerList.peers:type_name -> types.Peer + 53, // 8: types.BlockBodyPaged.body:type_name -> types.BlockBody + 16, // 9: types.BlockBodyParams.paging:type_name -> types.PageParams + 54, // 10: types.BlockHeaderList.blocks:type_name -> types.Block + 55, // 11: types.BlockMetadata.header:type_name -> types.BlockHeader + 21, // 12: types.BlockMetadataList.blocks:type_name -> types.BlockMetadata + 0, // 13: types.CommitResult.error:type_name -> types.CommitStatus + 23, // 14: types.CommitResultList.results:type_name -> types.CommitResult + 56, // 15: types.VerifyResult.tx:type_name -> types.Tx + 1, // 16: types.VerifyResult.error:type_name -> types.VerifyStatus + 57, // 17: types.Personal.account:type_name -> types.Account + 9, // 18: types.ImportFormat.wif:type_name -> types.SingleBytes + 9, // 19: types.ImportFormat.keystore:type_name -> types.SingleBytes + 28, // 20: types.AccountVoteInfo.staking:type_name -> types.Staking + 32, // 21: types.AccountVoteInfo.voting:type_name -> types.VoteInfo + 29, // 22: types.VoteList.votes:type_name -> types.Vote + 35, // 23: types.NameInfo.name:type_name -> types.Name + 46, // 24: types.ServerInfo.status:type_name -> types.ServerInfo.StatusEntry + 47, // 25: types.ServerInfo.config:type_name -> types.ServerInfo.ConfigEntry + 48, // 26: types.ConfigItem.props:type_name -> types.ConfigItem.PropsEntry + 58, // 27: types.EventList.events:type_name -> types.Event + 40, // 28: types.ServerInfo.ConfigEntry.value:type_name -> types.ConfigItem + 34, // 29: types.AergoRPCService.NodeState:input_type -> types.NodeReq + 59, // 30: types.AergoRPCService.Metric:input_type -> types.MetricsRequest + 8, // 31: types.AergoRPCService.Blockchain:input_type -> types.Empty + 8, // 32: types.AergoRPCService.GetChainInfo:input_type -> types.Empty + 8, // 33: types.AergoRPCService.ChainStat:input_type -> types.Empty + 15, // 34: types.AergoRPCService.ListBlockHeaders:input_type -> types.ListParams + 15, // 35: types.AergoRPCService.ListBlockMetadata:input_type -> types.ListParams + 8, // 36: types.AergoRPCService.ListBlockStream:input_type -> types.Empty + 8, // 37: types.AergoRPCService.ListBlockMetadataStream:input_type -> types.Empty + 9, // 38: types.AergoRPCService.GetBlock:input_type -> types.SingleBytes + 9, // 39: types.AergoRPCService.GetBlockMetadata:input_type -> types.SingleBytes + 19, // 40: types.AergoRPCService.GetBlockBody:input_type -> types.BlockBodyParams + 9, // 41: types.AergoRPCService.GetTX:input_type -> types.SingleBytes + 9, // 42: types.AergoRPCService.GetBlockTX:input_type -> types.SingleBytes + 9, // 43: types.AergoRPCService.GetReceipt:input_type -> types.SingleBytes + 17, // 44: types.AergoRPCService.GetInternalOperations:input_type -> types.BlockNumberParam + 9, // 45: types.AergoRPCService.GetABI:input_type -> types.SingleBytes + 56, // 46: types.AergoRPCService.SendTX:input_type -> types.Tx + 56, // 47: types.AergoRPCService.SignTX:input_type -> types.Tx + 56, // 48: types.AergoRPCService.VerifyTX:input_type -> types.Tx + 60, // 49: types.AergoRPCService.CommitTX:input_type -> types.TxList + 9, // 50: types.AergoRPCService.GetState:input_type -> types.SingleBytes + 12, // 51: types.AergoRPCService.GetStateAndProof:input_type -> types.AccountAndRoot + 26, // 52: types.AergoRPCService.CreateAccount:input_type -> types.Personal + 8, // 53: types.AergoRPCService.GetAccounts:input_type -> types.Empty + 26, // 54: types.AergoRPCService.LockAccount:input_type -> types.Personal + 26, // 55: types.AergoRPCService.UnlockAccount:input_type -> types.Personal + 27, // 56: types.AergoRPCService.ImportAccount:input_type -> types.ImportFormat + 26, // 57: types.AergoRPCService.ExportAccount:input_type -> types.Personal + 26, // 58: types.AergoRPCService.ExportAccountKeystore:input_type -> types.Personal + 61, // 59: types.AergoRPCService.QueryContract:input_type -> types.Query + 62, // 60: types.AergoRPCService.QueryContractState:input_type -> types.StateQuery + 37, // 61: types.AergoRPCService.GetPeers:input_type -> types.PeersParams + 30, // 62: types.AergoRPCService.GetVotes:input_type -> types.VoteParams + 11, // 63: types.AergoRPCService.GetAccountVotes:input_type -> types.AccountAddress + 11, // 64: types.AergoRPCService.GetStaking:input_type -> types.AccountAddress + 35, // 65: types.AergoRPCService.GetNameInfo:input_type -> types.Name + 63, // 66: types.AergoRPCService.ListEventStream:input_type -> types.FilterInfo + 63, // 67: types.AergoRPCService.ListEvents:input_type -> types.FilterInfo + 38, // 68: types.AergoRPCService.GetServerInfo:input_type -> types.KeyParams + 8, // 69: types.AergoRPCService.GetConsensusInfo:input_type -> types.Empty + 43, // 70: types.AergoRPCService.GetEnterpriseConfig:input_type -> types.EnterpriseConfigKey + 9, // 71: types.AergoRPCService.GetConfChangeProgress:input_type -> types.SingleBytes + 9, // 72: types.AergoRPCService.NodeState:output_type -> types.SingleBytes + 64, // 73: types.AergoRPCService.Metric:output_type -> types.Metrics + 2, // 74: types.AergoRPCService.Blockchain:output_type -> types.BlockchainStatus + 4, // 75: types.AergoRPCService.GetChainInfo:output_type -> types.ChainInfo + 5, // 76: types.AergoRPCService.ChainStat:output_type -> types.ChainStats + 20, // 77: types.AergoRPCService.ListBlockHeaders:output_type -> types.BlockHeaderList + 22, // 78: types.AergoRPCService.ListBlockMetadata:output_type -> types.BlockMetadataList + 54, // 79: types.AergoRPCService.ListBlockStream:output_type -> types.Block + 21, // 80: types.AergoRPCService.ListBlockMetadataStream:output_type -> types.BlockMetadata + 54, // 81: types.AergoRPCService.GetBlock:output_type -> types.Block + 21, // 82: types.AergoRPCService.GetBlockMetadata:output_type -> types.BlockMetadata + 18, // 83: types.AergoRPCService.GetBlockBody:output_type -> types.BlockBodyPaged + 56, // 84: types.AergoRPCService.GetTX:output_type -> types.Tx + 65, // 85: types.AergoRPCService.GetBlockTX:output_type -> types.TxInBlock + 66, // 86: types.AergoRPCService.GetReceipt:output_type -> types.Receipt + 9, // 87: types.AergoRPCService.GetInternalOperations:output_type -> types.SingleBytes + 67, // 88: types.AergoRPCService.GetABI:output_type -> types.ABI + 23, // 89: types.AergoRPCService.SendTX:output_type -> types.CommitResult + 56, // 90: types.AergoRPCService.SignTX:output_type -> types.Tx + 25, // 91: types.AergoRPCService.VerifyTX:output_type -> types.VerifyResult + 24, // 92: types.AergoRPCService.CommitTX:output_type -> types.CommitResultList + 68, // 93: types.AergoRPCService.GetState:output_type -> types.State + 69, // 94: types.AergoRPCService.GetStateAndProof:output_type -> types.AccountProof + 57, // 95: types.AergoRPCService.CreateAccount:output_type -> types.Account + 70, // 96: types.AergoRPCService.GetAccounts:output_type -> types.AccountList + 57, // 97: types.AergoRPCService.LockAccount:output_type -> types.Account + 57, // 98: types.AergoRPCService.UnlockAccount:output_type -> types.Account + 57, // 99: types.AergoRPCService.ImportAccount:output_type -> types.Account + 9, // 100: types.AergoRPCService.ExportAccount:output_type -> types.SingleBytes + 9, // 101: types.AergoRPCService.ExportAccountKeystore:output_type -> types.SingleBytes + 9, // 102: types.AergoRPCService.QueryContract:output_type -> types.SingleBytes + 71, // 103: types.AergoRPCService.QueryContractState:output_type -> types.StateQueryProof + 14, // 104: types.AergoRPCService.GetPeers:output_type -> types.PeerList + 33, // 105: types.AergoRPCService.GetVotes:output_type -> types.VoteList + 31, // 106: types.AergoRPCService.GetAccountVotes:output_type -> types.AccountVoteInfo + 28, // 107: types.AergoRPCService.GetStaking:output_type -> types.Staking + 36, // 108: types.AergoRPCService.GetNameInfo:output_type -> types.NameInfo + 58, // 109: types.AergoRPCService.ListEventStream:output_type -> types.Event + 41, // 110: types.AergoRPCService.ListEvents:output_type -> types.EventList + 39, // 111: types.AergoRPCService.GetServerInfo:output_type -> types.ServerInfo + 42, // 112: types.AergoRPCService.GetConsensusInfo:output_type -> types.ConsensusInfo + 44, // 113: types.AergoRPCService.GetEnterpriseConfig:output_type -> types.EnterpriseConfig + 72, // 114: types.AergoRPCService.GetConfChangeProgress:output_type -> types.ConfChangeProgress + 72, // [72:115] is the sub-list for method output_type + 29, // [29:72] is the sub-list for method input_type + 29, // [29:29] is the sub-list for extension type_name + 29, // [29:29] is the sub-list for extension extendee + 0, // [0:29] is the sub-list for field type_name } func init() { file_rpc_proto_init() } @@ -3492,7 +3567,7 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BlockBodyPaged); i { + switch v := v.(*BlockNumberParam); i { case 0: return &v.state case 1: @@ -3504,7 +3579,7 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BlockBodyParams); i { + switch v := v.(*BlockBodyPaged); i { case 0: return &v.state case 1: @@ -3516,7 +3591,7 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BlockHeaderList); i { + switch v := v.(*BlockBodyParams); i { case 0: return &v.state case 1: @@ -3528,7 +3603,7 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BlockMetadata); i { + switch v := v.(*BlockHeaderList); i { case 0: return &v.state case 1: @@ -3540,7 +3615,7 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BlockMetadataList); i { + switch v := v.(*BlockMetadata); i { case 0: return &v.state case 1: @@ -3552,7 +3627,7 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CommitResult); i { + switch v := v.(*BlockMetadataList); i { case 0: return &v.state case 1: @@ -3564,7 +3639,7 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CommitResultList); i { + switch v := v.(*CommitResult); i { case 0: return &v.state case 1: @@ -3576,7 +3651,7 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VerifyResult); i { + switch v := v.(*CommitResultList); i { case 0: return &v.state case 1: @@ -3588,7 +3663,7 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Personal); i { + switch v := v.(*VerifyResult); i { case 0: return &v.state case 1: @@ -3600,7 +3675,7 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ImportFormat); i { + switch v := v.(*Personal); i { case 0: return &v.state case 1: @@ -3612,7 +3687,7 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Staking); i { + switch v := v.(*ImportFormat); i { case 0: return &v.state case 1: @@ -3624,7 +3699,7 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Vote); i { + switch v := v.(*Staking); i { case 0: return &v.state case 1: @@ -3636,7 +3711,7 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VoteParams); i { + switch v := v.(*Vote); i { case 0: return &v.state case 1: @@ -3648,7 +3723,7 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AccountVoteInfo); i { + switch v := v.(*VoteParams); i { case 0: return &v.state case 1: @@ -3660,7 +3735,7 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VoteInfo); i { + switch v := v.(*AccountVoteInfo); i { case 0: return &v.state case 1: @@ -3672,7 +3747,7 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VoteList); i { + switch v := v.(*VoteInfo); i { case 0: return &v.state case 1: @@ -3684,7 +3759,7 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NodeReq); i { + switch v := v.(*VoteList); i { case 0: return &v.state case 1: @@ -3696,7 +3771,7 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Name); i { + switch v := v.(*NodeReq); i { case 0: return &v.state case 1: @@ -3708,7 +3783,7 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NameInfo); i { + switch v := v.(*Name); i { case 0: return &v.state case 1: @@ -3720,7 +3795,7 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PeersParams); i { + switch v := v.(*NameInfo); i { case 0: return &v.state case 1: @@ -3732,7 +3807,7 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*KeyParams); i { + switch v := v.(*PeersParams); i { case 0: return &v.state case 1: @@ -3744,7 +3819,7 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ServerInfo); i { + switch v := v.(*KeyParams); i { case 0: return &v.state case 1: @@ -3756,7 +3831,7 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ConfigItem); i { + switch v := v.(*ServerInfo); i { case 0: return &v.state case 1: @@ -3768,7 +3843,7 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EventList); i { + switch v := v.(*ConfigItem); i { case 0: return &v.state case 1: @@ -3780,7 +3855,7 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ConsensusInfo); i { + switch v := v.(*EventList); i { case 0: return &v.state case 1: @@ -3792,7 +3867,7 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EnterpriseConfigKey); i { + switch v := v.(*ConsensusInfo); i { case 0: return &v.state case 1: @@ -3804,6 +3879,18 @@ func file_rpc_proto_init() { } } file_rpc_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EnterpriseConfigKey); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*EnterpriseConfig); i { case 0: return &v.state @@ -3822,7 +3909,7 @@ func file_rpc_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_rpc_proto_rawDesc, NumEnums: 2, - NumMessages: 45, + NumMessages: 47, NumExtensions: 0, NumServices: 1, }, diff --git a/types/rpc_grpc.pb.go b/types/rpc_grpc.pb.go index bf583d44a..0950dcea8 100644 --- a/types/rpc_grpc.pb.go +++ b/types/rpc_grpc.pb.go @@ -34,6 +34,7 @@ const ( AergoRPCService_GetTX_FullMethodName = "/types.AergoRPCService/GetTX" AergoRPCService_GetBlockTX_FullMethodName = "/types.AergoRPCService/GetBlockTX" AergoRPCService_GetReceipt_FullMethodName = "/types.AergoRPCService/GetReceipt" + AergoRPCService_GetInternalOperations_FullMethodName = "/types.AergoRPCService/GetInternalOperations" AergoRPCService_GetABI_FullMethodName = "/types.AergoRPCService/GetABI" AergoRPCService_SendTX_FullMethodName = "/types.AergoRPCService/SendTX" AergoRPCService_SignTX_FullMethodName = "/types.AergoRPCService/SignTX" @@ -97,6 +98,8 @@ type AergoRPCServiceClient interface { GetBlockTX(ctx context.Context, in *SingleBytes, opts ...grpc.CallOption) (*TxInBlock, error) // Return transaction receipt, queried by transaction hash GetReceipt(ctx context.Context, in *SingleBytes, opts ...grpc.CallOption) (*Receipt, error) + // Return internal operations, queried by block number + GetInternalOperations(ctx context.Context, in *BlockNumberParam, opts ...grpc.CallOption) (*SingleBytes, error) // Return ABI stored at contract address GetABI(ctx context.Context, in *SingleBytes, opts ...grpc.CallOption) (*ABI, error) // Sign and send a transaction from an unlocked account @@ -342,6 +345,15 @@ func (c *aergoRPCServiceClient) GetReceipt(ctx context.Context, in *SingleBytes, return out, nil } +func (c *aergoRPCServiceClient) GetInternalOperations(ctx context.Context, in *BlockNumberParam, opts ...grpc.CallOption) (*SingleBytes, error) { + out := new(SingleBytes) + err := c.cc.Invoke(ctx, AergoRPCService_GetInternalOperations_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *aergoRPCServiceClient) GetABI(ctx context.Context, in *SingleBytes, opts ...grpc.CallOption) (*ABI, error) { out := new(ABI) err := c.cc.Invoke(ctx, AergoRPCService_GetABI_FullMethodName, in, out, opts...) @@ -642,6 +654,8 @@ type AergoRPCServiceServer interface { GetBlockTX(context.Context, *SingleBytes) (*TxInBlock, error) // Return transaction receipt, queried by transaction hash GetReceipt(context.Context, *SingleBytes) (*Receipt, error) + // Return internal operations, queried by block number + GetInternalOperations(context.Context, *BlockNumberParam) (*SingleBytes, error) // Return ABI stored at contract address GetABI(context.Context, *SingleBytes) (*ABI, error) // Sign and send a transaction from an unlocked account @@ -748,6 +762,9 @@ func (UnimplementedAergoRPCServiceServer) GetBlockTX(context.Context, *SingleByt func (UnimplementedAergoRPCServiceServer) GetReceipt(context.Context, *SingleBytes) (*Receipt, error) { return nil, status.Errorf(codes.Unimplemented, "method GetReceipt not implemented") } +func (UnimplementedAergoRPCServiceServer) GetInternalOperations(context.Context, *BlockNumberParam) (*SingleBytes, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetInternalOperations not implemented") +} func (UnimplementedAergoRPCServiceServer) GetABI(context.Context, *SingleBytes) (*ABI, error) { return nil, status.Errorf(codes.Unimplemented, "method GetABI not implemented") } @@ -1118,6 +1135,24 @@ func _AergoRPCService_GetReceipt_Handler(srv interface{}, ctx context.Context, d return interceptor(ctx, in, info, handler) } +func _AergoRPCService_GetInternalOperations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BlockNumberParam) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AergoRPCServiceServer).GetInternalOperations(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AergoRPCService_GetInternalOperations_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AergoRPCServiceServer).GetInternalOperations(ctx, req.(*BlockNumberParam)) + } + return interceptor(ctx, in, info, handler) +} + func _AergoRPCService_GetABI_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(SingleBytes) if err := dec(in); err != nil { @@ -1666,6 +1701,10 @@ var AergoRPCService_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetReceipt", Handler: _AergoRPCService_GetReceipt_Handler, }, + { + MethodName: "GetInternalOperations", + Handler: _AergoRPCService_GetInternalOperations_Handler, + }, { MethodName: "GetABI", Handler: _AergoRPCService_GetABI_Handler, diff --git a/types/state_test.go b/types/state_test.go index f8fa90dd4..e8643ddd7 100644 --- a/types/state_test.go +++ b/types/state_test.go @@ -1,6 +1,8 @@ package types import ( + "fmt" + "github.com/stretchr/testify/assert" "testing" "github.com/aergoio/aergo/v2/internal/enc/proto" @@ -42,3 +44,34 @@ func TestStateClone(t *testing.T) { } } + +var sampleAddress = "AmQHDFX45YMxrhN35S6csRweFK3WEAUCRWP78bHJguKCu28NjHzb" +var emptyAddress = "1111111111111111111111111111111111111111111111111111" + +var ( + sample1KeyB58 = "47TFXngxf7PcjMZTXqNAUoPYiPLra52pEwVJ9r94uRhwQE33s9kicaUpkiP9vYhhmbwKfH3M7" + sample1Key = "aa529b171489a18125a054e6661aa57593be3c1e6416974746f3172c25bcba6959dd93ba013b5e3726ab60e2db5c2a767968907176" + sample1Addr = "AmMLMVLzjUQEm16HDWd5QfxdRj45kLgNSYKTuLG3su3H6ngNf9QQ" +) + +func TestToAccountID(t *testing.T) { + zeroBytes := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + tests := []struct { + name string + account []byte + want AccountID + }{ + {"sample", ToAddress(sampleAddress), ToAccountID(ToAddress(sampleAddress))}, + {"zeros", Address(zeroBytes), + ToAccountID(zeroBytes)}, + {"empty", ToAddress(emptyAddress), ToAccountID([]byte{})}, + {"nil", ToAddress(emptyAddress), ToAccountID(nil)}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + address := Address(tt.account) + fmt.Printf("Address %s , account %s", EncodeAddress(address), tt.want.String()) + assert.Equalf(t, tt.want, ToAccountID(tt.account), "ToAccountID(%v)", tt.account) + }) + } +} diff --git a/types/utils/byteutils.go b/types/utils/byteutils.go new file mode 100644 index 000000000..1ef189f62 --- /dev/null +++ b/types/utils/byteutils.go @@ -0,0 +1,33 @@ +package utils + +import ( + "bytes" + "encoding/binary" + "fmt" +) + +// PrimitiveToByteArray return byte array from a primitive type. It should not be used for non-primitive types. +func PrimitiveToByteArray(data interface{}) ([]byte, error) { + buf := new(bytes.Buffer) + err := binary.Write(buf, binary.LittleEndian, data) + if err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +func ToByteArrayOrEmpty(data interface{}) []byte { + byteArray, err := PrimitiveToByteArray(data) + if err != nil { + return make([]byte, 0) + } else { + return byteArray + } +} + +func ToUint64(b []byte) (uint64, error) { + if len(b) < 8 { + return 0, fmt.Errorf("invalid input") + } + return binary.LittleEndian.Uint64(b), nil +} diff --git a/types/utils/byteutils_test.go b/types/utils/byteutils_test.go new file mode 100644 index 000000000..c9189d32b --- /dev/null +++ b/types/utils/byteutils_test.go @@ -0,0 +1,31 @@ +package utils + +import "testing" + +func TestToUint64(t *testing.T) { + type args struct { + b []byte + } + tests := []struct { + name string + args args + want uint64 + wantErr bool + }{ + {"nil", args{nil}, 0, true}, + {"short", args{[]byte{1, 0, 0, 0}}, 0, true}, + {"257", args{[]byte{1, 1, 0, 0, 0, 0, 0, 0}}, 257, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ToUint64(tt.args.b) + if (err != nil) != tt.wantErr { + t.Errorf("ToUint64() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("ToUint64() got = %v, want %v", got, tt.want) + } + }) + } +}