From 2e2d463064ff0ec4a3add9e4dd4baddc852976d9 Mon Sep 17 00:00:00 2001 From: codchen Date: Fri, 17 Nov 2023 11:58:57 +0800 Subject: [PATCH 01/39] Expose parent on CacheKV (#352) ## Describe your changes and provide context For EVM getProof endpoint, we'd need to call functions on the underlying iavl store, so we'd need a way to expose the parent store from a cachekv ## Testing performed to validate your change --- store/cachekv/store.go | 4 ++++ store/cachekv/store_test.go | 3 +++ 2 files changed, 7 insertions(+) diff --git a/store/cachekv/store.go b/store/cachekv/store.go index 06d491d04..e4177f767 100644 --- a/store/cachekv/store.go +++ b/store/cachekv/store.go @@ -359,3 +359,7 @@ func (store *Store) isDeleted(key string) bool { _, ok := store.deleted.Load(key) return ok } + +func (store *Store) GetParent() types.KVStore { + return store.parent +} diff --git a/store/cachekv/store_test.go b/store/cachekv/store_test.go index 3a6d5ab53..65c3f4eaa 100644 --- a/store/cachekv/store_test.go +++ b/store/cachekv/store_test.go @@ -62,6 +62,9 @@ func TestCacheKVStore(t *testing.T) { st.Write() require.Empty(t, st.Get(keyFmt(1)), "Expected `key1` to be empty") require.Empty(t, mem.Get(keyFmt(1)), "Expected `key1` to be empty") + + // GetParent returns parent store + require.NotNil(t, st.GetParent()) } func TestCacheKVStoreNoNilSet(t *testing.T) { From f7a3c0ed6ceb29bc46b5ad5f9e970a16c4fe71e0 Mon Sep 17 00:00:00 2001 From: codchen Date: Wed, 22 Nov 2023 13:15:36 +0800 Subject: [PATCH 02/39] Set TxIndex before generating dependencies (#358) ## Describe your changes and provide context We need to make `TxIndex` available during dependency generation so that we can derive the corresponding temporary intermediate account and coinbase account for the message ## Testing performed to validate your change --- x/accesscontrol/keeper/keeper.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/accesscontrol/keeper/keeper.go b/x/accesscontrol/keeper/keeper.go index f047f2c46..869e616b2 100644 --- a/x/accesscontrol/keeper/keeper.go +++ b/x/accesscontrol/keeper/keeper.go @@ -588,6 +588,7 @@ func (k Keeper) BuildDependencyDag(ctx sdk.Context, txDecoder sdk.TxDecoder, ant // add Access ops for msg for anteMsg dependencyDag.AddAccessOpsForMsg(acltypes.ANTE_MSG_INDEX, txIndex, anteAccessOpsList) + ctx = ctx.WithTxIndex(txIndex) msgs := tx.GetMsgs() for messageIndex, msg := range msgs { if types.IsGovMessage(msg) { From cf9890479f1737c8a56b632abebb30e5d7608692 Mon Sep 17 00:00:00 2001 From: codchen Date: Mon, 4 Dec 2023 21:20:44 +0800 Subject: [PATCH 03/39] change DeliverTx to take typed tx (#360) - To avoid multiple deserialization, as well as adding cached values to sdk.Tx - Add new acl constants for evm subprefixes - Add a new bank send method that doesn't automatically create accounts unit tests & local sei integration --- baseapp/abci.go | 13 +- baseapp/baseapp.go | 22 +- baseapp/deliver_tx_test.go | 33 +- baseapp/msg_service_router_test.go | 15 +- baseapp/test_helpers.go | 16 +- proto/cosmos/accesscontrol/constants.proto | 17 +- server/mock/app.go | 12 +- simapp/app.go | 7 +- types/accesscontrol/constants.pb.go | 426 +++++++++++---------- types/accesscontrol/resource.go | 25 ++ x/accesscontrol/keeper/keeper.go | 10 +- x/accesscontrol/keeper/keeper_test.go | 139 +++---- x/bank/keeper/send.go | 23 +- x/genutil/gentx.go | 5 +- 14 files changed, 428 insertions(+), 335 deletions(-) diff --git a/baseapp/abci.go b/baseapp/abci.go index 6d168eb33..db69946f5 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -220,7 +220,12 @@ func (app *BaseApp) CheckTx(ctx context.Context, req *abci.RequestCheckTx) (*abc } sdkCtx := app.getContextForTx(mode, req.Tx) - gInfo, result, _, priority, err := app.runTx(sdkCtx, mode, req.Tx) + tx, err := app.txDecoder(req.Tx) + if err != nil { + res := sdkerrors.ResponseCheckTx(err, 0, 0, app.trace) + return &res, err + } + gInfo, result, _, priority, err := app.runTx(sdkCtx, mode, tx, sha256.Sum256(req.Tx)) if err != nil { res := sdkerrors.ResponseCheckTx(err, gInfo.GasWanted, gInfo.GasUsed, app.trace) return &res, err @@ -256,9 +261,7 @@ func (app *BaseApp) DeliverTxBatch(ctx sdk.Context, req sdk.DeliverTxBatchReques // Otherwise, the ResponseDeliverTx will contain relevant error information. // Regardless of tx execution outcome, the ResponseDeliverTx will contain relevant // gas execution context. -// TODO: (occ) this is the function called from sei-chain to perform execution of a transaction. -// We'd likely replace this with an execution tasks that is scheduled by the OCC scheduler -func (app *BaseApp) DeliverTx(ctx sdk.Context, req abci.RequestDeliverTx) (res abci.ResponseDeliverTx) { +func (app *BaseApp) DeliverTx(ctx sdk.Context, req abci.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res abci.ResponseDeliverTx) { defer telemetry.MeasureSince(time.Now(), "abci", "deliver_tx") defer func() { for _, streamingListener := range app.abciListeners { @@ -278,7 +281,7 @@ func (app *BaseApp) DeliverTx(ctx sdk.Context, req abci.RequestDeliverTx) (res a telemetry.SetGauge(float32(gInfo.GasWanted), "tx", "gas", "wanted") }() - gInfo, result, anteEvents, _, err := app.runTx(ctx.WithTxBytes(req.Tx).WithVoteInfos(app.voteInfos), runTxModeDeliver, req.Tx) + gInfo, result, anteEvents, _, err := app.runTx(ctx.WithTxBytes(req.Tx).WithVoteInfos(app.voteInfos), runTxModeDeliver, tx, checksum) if err != nil { resultStr = "failed" // if we have a result, use those events instead of just the anteEvents diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 1f61d37b2..a330f6f19 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -2,7 +2,6 @@ package baseapp import ( "context" - "crypto/sha256" "fmt" "reflect" "strings" @@ -802,8 +801,7 @@ func (app *BaseApp) getContextForTx(mode runTxMode, txBytes []byte) sdk.Context // cacheTxContext returns a new context based off of the provided context with // a branched multi-store. -// TODO: (occ) This is an example of where we wrap the multistore with a cache multistore, and then return a modified context using that multistore -func (app *BaseApp) cacheTxContext(ctx sdk.Context, txBytes []byte) (sdk.Context, sdk.CacheMultiStore) { +func (app *BaseApp) cacheTxContext(ctx sdk.Context, checksum [32]byte) (sdk.Context, sdk.CacheMultiStore) { ms := ctx.MultiStore() // TODO: https://github.com/cosmos/cosmos-sdk/issues/2824 msCache := ms.CacheMultiStore() @@ -811,7 +809,7 @@ func (app *BaseApp) cacheTxContext(ctx sdk.Context, txBytes []byte) (sdk.Context msCache = msCache.SetTracingContext( sdk.TraceContext( map[string]interface{}{ - "txHash": fmt.Sprintf("%X", sha256.Sum256(txBytes)), + "txHash": fmt.Sprintf("%X", checksum), }, ), ).(sdk.CacheMultiStore) @@ -827,8 +825,7 @@ func (app *BaseApp) cacheTxContext(ctx sdk.Context, txBytes []byte) (sdk.Context // Note, gas execution info is always returned. A reference to a Result is // returned if the tx does not run out of gas and if all the messages are valid // and execute successfully. An error is returned otherwise. -func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, txBytes []byte) (gInfo sdk.GasInfo, result *sdk.Result, anteEvents []abci.Event, priority int64, err error) { - +func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [32]byte) (gInfo sdk.GasInfo, result *sdk.Result, anteEvents []abci.Event, priority int64, err error) { defer telemetry.MeasureThroughputSinceWithLabels( telemetry.TxCount, []metrics.Label{ @@ -852,7 +849,7 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, txBytes []byte) (gInf spanCtx, span := app.TracingInfo.StartWithContext("RunTx", ctx.TraceSpanContext()) defer span.End() ctx = ctx.WithTraceSpanContext(spanCtx) - span.SetAttributes(attribute.String("txHash", fmt.Sprintf("%X", sha256.Sum256(txBytes)))) + span.SetAttributes(attribute.String("txHash", fmt.Sprintf("%X", checksum))) } // NOTE: GasWanted should be returned by the AnteHandler. GasUsed is @@ -875,9 +872,8 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, txBytes []byte) (gInf gInfo = sdk.GasInfo{GasWanted: gasWanted, GasUsed: ctx.GasMeter().GasConsumed()} }() - tx, err := app.txDecoder(txBytes) - if err != nil { - return sdk.GasInfo{}, nil, nil, 0, err + if tx == nil { + return sdk.GasInfo{}, nil, nil, 0, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "tx decode error") } msgs := tx.GetMsgs() @@ -904,7 +900,7 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, txBytes []byte) (gInf // NOTE: Alternatively, we could require that AnteHandler ensures that // writes do not happen if aborted/failed. This may have some // performance benefits, but it'll be more difficult to get right. - anteCtx, msCache = app.cacheTxContext(ctx, txBytes) + anteCtx, msCache = app.cacheTxContext(ctx, checksum) anteCtx = anteCtx.WithEventManager(sdk.NewEventManager()) newCtx, err := app.anteHandler(anteCtx, tx, mode == runTxModeSimulate) @@ -959,7 +955,7 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, txBytes []byte) (gInf // Create a new Context based off of the existing Context with a MultiStore branch // in case message processing fails. At this point, the MultiStore // is a branch of a branch. - runMsgCtx, msCache := app.cacheTxContext(ctx, txBytes) + runMsgCtx, msCache := app.cacheTxContext(ctx, checksum) // Attempt to execute all messages and only update state if all messages pass // and we're in DeliverTx. Note, runMsgs will never return a reference to a @@ -1021,7 +1017,7 @@ func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, mode runTxMode) (*s err error ) - msgCtx, msgMsCache := app.cacheTxContext(ctx, []byte{}) + msgCtx, msgMsCache := app.cacheTxContext(ctx, [32]byte{}) msgCtx = msgCtx.WithMessageIndex(i) startTime := time.Now() diff --git a/baseapp/deliver_tx_test.go b/baseapp/deliver_tx_test.go index 0e144e4a7..11e451c36 100644 --- a/baseapp/deliver_tx_test.go +++ b/baseapp/deliver_tx_test.go @@ -3,6 +3,7 @@ package baseapp import ( "bytes" "context" + "crypto/sha256" "encoding/binary" "fmt" "math/rand" @@ -228,7 +229,8 @@ func TestWithRouter(t *testing.T) { txBytes, err := codec.Marshal(tx) require.NoError(t, err) - res := app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}) + decoded, _ := app.txDecoder(txBytes) + res := app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}, decoded, sha256.Sum256(txBytes)) require.True(t, res.IsOK(), fmt.Sprintf("%v", res)) } @@ -434,7 +436,8 @@ func TestMultiMsgDeliverTx(t *testing.T) { tx := newTxCounter(0, 0, 1, 2) txBytes, err := codec.Marshal(tx) require.NoError(t, err) - res := app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}) + decoded, _ := app.txDecoder(txBytes) + res := app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}, decoded, sha256.Sum256(txBytes)) require.True(t, res.IsOK(), fmt.Sprintf("%v", res)) store := app.deliverState.ctx.KVStore(capKey1) @@ -454,7 +457,8 @@ func TestMultiMsgDeliverTx(t *testing.T) { tx.Msgs = append(tx.Msgs, msgCounter2{1}) txBytes, err = codec.Marshal(tx) require.NoError(t, err) - res = app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}) + decoded, _ = app.txDecoder(txBytes) + res = app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}, decoded, sha256.Sum256(txBytes)) require.True(t, res.IsOK(), fmt.Sprintf("%v", res)) store = app.deliverState.ctx.KVStore(capKey1) @@ -651,9 +655,8 @@ func TestRunInvalidTransaction(t *testing.T) { txBytes, err := newCdc.Marshal(tx) require.NoError(t, err) - res := app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}) - require.EqualValues(t, sdkerrors.ErrTxDecode.ABCICode(), res.Code) - require.EqualValues(t, sdkerrors.ErrTxDecode.Codespace(), res.Codespace) + _, err = app.txDecoder(txBytes) + require.NotNil(t, err) } } @@ -922,7 +925,8 @@ func TestBaseAppAnteHandler(t *testing.T) { tx.setFailOnAnte(true) txBytes, err := cdc.Marshal(tx) require.NoError(t, err) - res := app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}) + decoded, _ := app.txDecoder(txBytes) + res := app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}, decoded, sha256.Sum256(txBytes)) require.Empty(t, res.Events) require.False(t, res.IsOK(), fmt.Sprintf("%v", res)) @@ -938,7 +942,8 @@ func TestBaseAppAnteHandler(t *testing.T) { txBytes, err = cdc.Marshal(tx) require.NoError(t, err) - res = app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}) + decoded, _ = app.txDecoder(txBytes) + res = app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}, decoded, sha256.Sum256(txBytes)) // should emit ante event require.NotEmpty(t, res.Events) require.False(t, res.IsOK(), fmt.Sprintf("%v", res)) @@ -955,7 +960,8 @@ func TestBaseAppAnteHandler(t *testing.T) { txBytes, err = cdc.Marshal(tx) require.NoError(t, err) - res = app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}) + decoded, _ = app.txDecoder(txBytes) + res = app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}, decoded, sha256.Sum256(txBytes)) require.NotEmpty(t, res.Events) require.True(t, res.IsOK(), fmt.Sprintf("%v", res)) @@ -1032,7 +1038,7 @@ func TestGasConsumptionBadTx(t *testing.T) { txBytes, err := cdc.Marshal(tx) require.NoError(t, err) - res := app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}) + res := app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}, tx, sha256.Sum256(txBytes)) require.False(t, res.IsOK(), fmt.Sprintf("%v", res)) // removed the block gas exceeded because of removal of block gas meter, gasWanted < max block gas is still fulfilled by various other checks @@ -1498,7 +1504,8 @@ func TestDeliverTx(t *testing.T) { txBytes, err := codec.Marshal(tx) require.NoError(t, err) - res := app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}) + decoded, _ := app.txDecoder(txBytes) + res := app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}, decoded, sha256.Sum256(txBytes)) require.True(t, res.IsOK(), fmt.Sprintf("%v", res)) events := res.GetEvents() require.Len(t, events, 3, "should contain ante handler, message type and counter events respectively") @@ -1700,12 +1707,12 @@ func setupBaseAppWithSnapshots(t *testing.T, blocks uint, blockTxs int, options value := make([]byte, 10000) _, err := r.Read(value) require.NoError(t, err) - tx.Msgs = append(tx.Msgs, msgKeyValue{Key: key, Value: value}) + tx.Msgs = append(tx.Msgs, &msgKeyValue{Key: key, Value: value}) keyCounter++ } txBytes, err := codec.Marshal(tx) require.NoError(t, err) - resp := app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}) + resp := app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}, tx, sha256.Sum256(txBytes)) require.True(t, resp.IsOK(), "%v", resp.String()) } app.EndBlock(app.deliverState.ctx, abci.RequestEndBlock{Height: height}) diff --git a/baseapp/msg_service_router_test.go b/baseapp/msg_service_router_test.go index 6c504aba0..0cd6bf385 100644 --- a/baseapp/msg_service_router_test.go +++ b/baseapp/msg_service_router_test.go @@ -2,6 +2,7 @@ package baseapp_test import ( "context" + "crypto/sha256" "testing" "github.com/stretchr/testify/require" @@ -73,7 +74,8 @@ func TestMsgService(t *testing.T) { encCfg := simapp.MakeTestEncodingConfig() testdata.RegisterInterfaces(encCfg.InterfaceRegistry) db := dbm.NewMemDB() - app := baseapp.NewBaseApp("test", log.NewTestingLogger(t), db, encCfg.TxConfig.TxDecoder(), nil, &testutil.TestAppOpts{}) + decoder := encCfg.TxConfig.TxDecoder() + app := baseapp.NewBaseApp("test", log.NewTestingLogger(t), db, decoder, nil, &testutil.TestAppOpts{}) app.SetInterfaceRegistry(encCfg.InterfaceRegistry) testdata.RegisterMsgServer( app.MsgServiceRouter(), @@ -81,10 +83,15 @@ func TestMsgService(t *testing.T) { ) app.SetFinalizeBlocker(func(ctx sdk.Context, req *abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { txResults := []*abci.ExecTxResult{} - for _, tx := range req.Txs { + for _, txbz := range req.Txs { + tx, err := decoder(txbz) + if err != nil { + txResults = append(txResults, &abci.ExecTxResult{}) + continue + } deliverTxResp := app.DeliverTx(ctx, abci.RequestDeliverTx{ - Tx: tx, - }) + Tx: txbz, + }, tx, sha256.Sum256(txbz)) txResults = append(txResults, &abci.ExecTxResult{ Code: deliverTxResp.Code, Data: deliverTxResp.Data, diff --git a/baseapp/test_helpers.go b/baseapp/test_helpers.go index d8b114395..3980c2f65 100644 --- a/baseapp/test_helpers.go +++ b/baseapp/test_helpers.go @@ -1,6 +1,8 @@ package baseapp import ( + "crypto/sha256" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -15,7 +17,7 @@ func (app *BaseApp) Check(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, *sdk return sdk.GasInfo{}, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "%s", err) } ctx := app.checkState.ctx.WithTxBytes(bz).WithVoteInfos(app.voteInfos).WithConsensusParams(app.GetConsensusParams(app.checkState.ctx)) - gasInfo, result, _, _, err := app.runTx(ctx, runTxModeCheck, bz) + gasInfo, result, _, _, err := app.runTx(ctx, runTxModeCheck, tx, sha256.Sum256(bz)) if len(ctx.MultiStore().GetEvents()) > 0 { panic("Expected checkTx events to be empty") } @@ -25,7 +27,11 @@ func (app *BaseApp) Check(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, *sdk func (app *BaseApp) Simulate(txBytes []byte) (sdk.GasInfo, *sdk.Result, error) { ctx := app.checkState.ctx.WithTxBytes(txBytes).WithVoteInfos(app.voteInfos).WithConsensusParams(app.GetConsensusParams(app.checkState.ctx)) ctx, _ = ctx.CacheContext() - gasInfo, result, _, _, err := app.runTx(ctx, runTxModeSimulate, txBytes) + tx, err := app.txDecoder(txBytes) + if err != nil { + return sdk.GasInfo{}, nil, err + } + gasInfo, result, _, _, err := app.runTx(ctx, runTxModeSimulate, tx, sha256.Sum256(txBytes)) if len(ctx.MultiStore().GetEvents()) > 0 { panic("Expected simulate events to be empty") } @@ -39,7 +45,11 @@ func (app *BaseApp) Deliver(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, *s return sdk.GasInfo{}, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "%s", err) } ctx := app.deliverState.ctx.WithTxBytes(bz).WithVoteInfos(app.voteInfos).WithConsensusParams(app.GetConsensusParams(app.deliverState.ctx)) - gasInfo, result, _, _, err := app.runTx(ctx, runTxModeDeliver, bz) + decoded, err := app.txDecoder(bz) + if err != nil { + return sdk.GasInfo{}, &sdk.Result{}, err + } + gasInfo, result, _, _, err := app.runTx(ctx, runTxModeDeliver, decoded, sha256.Sum256(bz)) return gasInfo, result, err } diff --git a/proto/cosmos/accesscontrol/constants.proto b/proto/cosmos/accesscontrol/constants.proto index f8c977a73..01ed4f299 100644 --- a/proto/cosmos/accesscontrol/constants.proto +++ b/proto/cosmos/accesscontrol/constants.proto @@ -133,8 +133,21 @@ enum ResourceType { reserved 94; KV_BANK_DEFERRED_MODULE_TX_INDEX = 95; // child of KV_BANK_DEFERRED - KV_DEX_MEM_CONTRACTS_TO_PROCESS = 96; // child of KV_DEX_MEM - KV_DEX_MEM_DOWNSTREAM_CONTRACTS = 97; // child of KV_DEX_MEM + KV_EVM = 96; // child of KV + KV_EVM_BALANCE = 97; // child of KV_EVM; deprecated + KV_EVM_TRANSIENT = 98; // child of KV_EVM + KV_EVM_ACCOUNT_TRANSIENT = 99; // child of KV_EVM + KV_EVM_MODULE_TRANSIENT = 100; // child of KV_EVM + KV_EVM_NONCE = 101; // child of KV_EVM + KV_EVM_RECEIPT = 102; // child of KV_EVM + KV_EVM_S2E = 103; // child of KV_EVM + KV_EVM_E2S = 104; // child of KV_EVM + KV_EVM_CODE_HASH = 105; // child of KV_EVM + KV_EVM_CODE = 106; // child of KV_EVM + KV_EVM_CODE_SIZE = 107; // child of KV_EVM + + KV_DEX_MEM_CONTRACTS_TO_PROCESS = 108; // child of KV_DEX_MEM + KV_DEX_MEM_DOWNSTREAM_CONTRACTS = 109; // child of KV_DEX_MEM } enum WasmMessageSubtype { diff --git a/server/mock/app.go b/server/mock/app.go index 959bce012..5aacd477d 100644 --- a/server/mock/app.go +++ b/server/mock/app.go @@ -2,6 +2,7 @@ package mock import ( "context" + "crypto/sha256" "encoding/json" "errors" "fmt" @@ -39,10 +40,15 @@ func NewApp(rootDir string, logger log.Logger) (abci.Application, error) { baseApp.SetInitChainer(InitChainer(capKeyMainStore)) baseApp.SetFinalizeBlocker(func(ctx sdk.Context, req *abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { txResults := []*abci.ExecTxResult{} - for _, tx := range req.Txs { + for _, txbz := range req.Txs { + tx, err := decodeTx(txbz) + if err != nil { + txResults = append(txResults, &abci.ExecTxResult{}) + continue + } deliverTxResp := baseApp.DeliverTx(ctx, abci.RequestDeliverTx{ - Tx: tx, - }) + Tx: txbz, + }, tx, sha256.Sum256(txbz)) txResults = append(txResults, &abci.ExecTxResult{ Code: deliverTxResp.Code, Data: deliverTxResp.Data, diff --git a/simapp/app.go b/simapp/app.go index 4c0af924c..cb4b031c3 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -2,6 +2,7 @@ package simapp import ( "context" + "crypto/sha256" "encoding/json" "fmt" "io" @@ -515,9 +516,13 @@ func (app *SimApp) FinalizeBlocker(ctx sdk.Context, req *abci.RequestFinalizeBlo txResults := []*abci.ExecTxResult{} for i, tx := range req.Txs { ctx = ctx.WithContext(context.WithValue(ctx.Context(), ante.ContextKeyTxIndexKey, i)) + if typedTxs[i] == nil { + txResults = append(txResults, &abci.ExecTxResult{}) // empty result + continue + } deliverTxResp := app.DeliverTx(ctx, abci.RequestDeliverTx{ Tx: tx, - }) + }, typedTxs[i], sha256.Sum256(tx)) txResults = append(txResults, &abci.ExecTxResult{ Code: deliverTxResp.Code, Data: deliverTxResp.Data, diff --git a/types/accesscontrol/constants.pb.go b/types/accesscontrol/constants.pb.go index c310dc868..939ad80de 100644 --- a/types/accesscontrol/constants.pb.go +++ b/types/accesscontrol/constants.pb.go @@ -195,105 +195,129 @@ const ( ResourceType_KV_DEX_SHORT_ORDER_COUNT ResourceType = 92 ResourceType_KV_BANK_DEFERRED ResourceType = 93 ResourceType_KV_BANK_DEFERRED_MODULE_TX_INDEX ResourceType = 95 - ResourceType_KV_DEX_MEM_CONTRACTS_TO_PROCESS ResourceType = 96 - ResourceType_KV_DEX_MEM_DOWNSTREAM_CONTRACTS ResourceType = 97 + ResourceType_KV_EVM ResourceType = 96 + ResourceType_KV_EVM_BALANCE ResourceType = 97 + ResourceType_KV_EVM_TRANSIENT ResourceType = 98 + ResourceType_KV_EVM_ACCOUNT_TRANSIENT ResourceType = 99 + ResourceType_KV_EVM_MODULE_TRANSIENT ResourceType = 100 + ResourceType_KV_EVM_NONCE ResourceType = 101 + ResourceType_KV_EVM_RECEIPT ResourceType = 102 + ResourceType_KV_EVM_S2E ResourceType = 103 + ResourceType_KV_EVM_E2S ResourceType = 104 + ResourceType_KV_EVM_CODE_HASH ResourceType = 105 + ResourceType_KV_EVM_CODE ResourceType = 106 + ResourceType_KV_EVM_CODE_SIZE ResourceType = 107 + ResourceType_KV_DEX_MEM_CONTRACTS_TO_PROCESS ResourceType = 108 + ResourceType_KV_DEX_MEM_DOWNSTREAM_CONTRACTS ResourceType = 109 ) var ResourceType_name = map[int32]string{ - 0: "ANY", - 1: "KV", - 2: "Mem", - 3: "DexMem", - 4: "KV_BANK", - 5: "KV_STAKING", - 6: "KV_WASM", - 7: "KV_ORACLE", - 8: "KV_DEX", - 9: "KV_EPOCH", - 10: "KV_TOKENFACTORY", - 11: "KV_ORACLE_VOTE_TARGETS", - 12: "KV_ORACLE_AGGREGATE_VOTES", - 13: "KV_ORACLE_FEEDERS", - 14: "KV_STAKING_DELEGATION", - 15: "KV_STAKING_VALIDATOR", - 16: "KV_AUTH", - 17: "KV_AUTH_ADDRESS_STORE", - 18: "KV_BANK_SUPPLY", - 19: "KV_BANK_DENOM", - 20: "KV_BANK_BALANCES", - 21: "KV_TOKENFACTORY_DENOM", - 22: "KV_TOKENFACTORY_METADATA", - 23: "KV_TOKENFACTORY_ADMIN", - 24: "KV_TOKENFACTORY_CREATOR", - 25: "KV_ORACLE_EXCHANGE_RATE", - 26: "KV_ORACLE_VOTE_PENALTY_COUNTER", - 27: "KV_ORACLE_PRICE_SNAPSHOT", - 28: "KV_STAKING_VALIDATION_POWER", - 29: "KV_STAKING_TOTAL_POWER", - 30: "KV_STAKING_VALIDATORS_CON_ADDR", - 31: "KV_STAKING_UNBONDING_DELEGATION", - 32: "KV_STAKING_UNBONDING_DELEGATION_VAL", - 33: "KV_STAKING_REDELEGATION", - 34: "KV_STAKING_REDELEGATION_VAL_SRC", - 35: "KV_STAKING_REDELEGATION_VAL_DST", - 36: "KV_STAKING_REDELEGATION_QUEUE", - 37: "KV_STAKING_VALIDATOR_QUEUE", - 38: "KV_STAKING_HISTORICAL_INFO", - 39: "KV_STAKING_UNBONDING", - 41: "KV_STAKING_VALIDATORS_BY_POWER", - 40: "KV_DISTRIBUTION", - 42: "KV_DISTRIBUTION_FEE_POOL", - 43: "KV_DISTRIBUTION_PROPOSER_KEY", - 44: "KV_DISTRIBUTION_OUTSTANDING_REWARDS", - 45: "KV_DISTRIBUTION_DELEGATOR_WITHDRAW_ADDR", - 46: "KV_DISTRIBUTION_DELEGATOR_STARTING_INFO", - 47: "KV_DISTRIBUTION_VAL_HISTORICAL_REWARDS", - 48: "KV_DISTRIBUTION_VAL_CURRENT_REWARDS", - 49: "KV_DISTRIBUTION_VAL_ACCUM_COMMISSION", - 50: "KV_DISTRIBUTION_SLASH_EVENT", - 51: "KV_DEX_CONTRACT_LONGBOOK", - 52: "KV_DEX_CONTRACT_SHORTBOOK", - 53: "KV_DEX_SETTLEMENT", - 54: "KV_DEX_PAIR_PREFIX", - 55: "KV_DEX_TWAP", - 56: "KV_DEX_PRICE", - 57: "KV_DEX_SETTLEMENT_ENTRY", - 58: "KV_DEX_REGISTERED_PAIR", - 60: "KV_DEX_ORDER", - 61: "KV_DEX_CANCEL", - 62: "KV_DEX_ACCOUNT_ACTIVE_ORDERS", - 64: "KV_DEX_ASSET_LIST", - 65: "KV_DEX_NEXT_ORDER_ID", - 66: "KV_DEX_NEXT_SETTLEMENT_ID", - 67: "KV_DEX_MATCH_RESULT", - 68: "KV_DEX_SETTLEMENT_ORDER_ID", - 69: "KV_DEX_ORDER_BOOK", - 71: "KV_ACCESSCONTROL", - 72: "KV_ACCESSCONTROL_WASM_DEPENDENCY_MAPPING", - 73: "KV_WASM_CODE", - 74: "KV_WASM_CONTRACT_ADDRESS", - 75: "KV_WASM_CONTRACT_STORE", - 76: "KV_WASM_SEQUENCE_KEY", - 77: "KV_WASM_CONTRACT_CODE_HISTORY", - 78: "KV_WASM_CONTRACT_BY_CODE_ID", - 79: "KV_WASM_PINNED_CODE_INDEX", - 80: "KV_AUTH_GLOBAL_ACCOUNT_NUMBER", - 81: "KV_AUTHZ", - 82: "KV_FEEGRANT", - 83: "KV_FEEGRANT_ALLOWANCE", - 84: "KV_SLASHING", - 85: "KV_SLASHING_VAL_SIGNING_INFO", - 86: "KV_SLASHING_ADDR_PUBKEY_RELATION_KEY", - 87: "KV_DEX_MEM_ORDER", - 88: "KV_DEX_MEM_CANCEL", - 89: "KV_DEX_MEM_DEPOSIT", - 90: "KV_DEX_CONTRACT", - 91: "KV_DEX_LONG_ORDER_COUNT", - 92: "KV_DEX_SHORT_ORDER_COUNT", - 93: "KV_BANK_DEFERRED", - 95: "KV_BANK_DEFERRED_MODULE_TX_INDEX", - 96: "KV_DEX_MEM_CONTRACTS_TO_PROCESS", - 97: "KV_DEX_MEM_DOWNSTREAM_CONTRACTS", + 0: "ANY", + 1: "KV", + 2: "Mem", + 3: "DexMem", + 4: "KV_BANK", + 5: "KV_STAKING", + 6: "KV_WASM", + 7: "KV_ORACLE", + 8: "KV_DEX", + 9: "KV_EPOCH", + 10: "KV_TOKENFACTORY", + 11: "KV_ORACLE_VOTE_TARGETS", + 12: "KV_ORACLE_AGGREGATE_VOTES", + 13: "KV_ORACLE_FEEDERS", + 14: "KV_STAKING_DELEGATION", + 15: "KV_STAKING_VALIDATOR", + 16: "KV_AUTH", + 17: "KV_AUTH_ADDRESS_STORE", + 18: "KV_BANK_SUPPLY", + 19: "KV_BANK_DENOM", + 20: "KV_BANK_BALANCES", + 21: "KV_TOKENFACTORY_DENOM", + 22: "KV_TOKENFACTORY_METADATA", + 23: "KV_TOKENFACTORY_ADMIN", + 24: "KV_TOKENFACTORY_CREATOR", + 25: "KV_ORACLE_EXCHANGE_RATE", + 26: "KV_ORACLE_VOTE_PENALTY_COUNTER", + 27: "KV_ORACLE_PRICE_SNAPSHOT", + 28: "KV_STAKING_VALIDATION_POWER", + 29: "KV_STAKING_TOTAL_POWER", + 30: "KV_STAKING_VALIDATORS_CON_ADDR", + 31: "KV_STAKING_UNBONDING_DELEGATION", + 32: "KV_STAKING_UNBONDING_DELEGATION_VAL", + 33: "KV_STAKING_REDELEGATION", + 34: "KV_STAKING_REDELEGATION_VAL_SRC", + 35: "KV_STAKING_REDELEGATION_VAL_DST", + 36: "KV_STAKING_REDELEGATION_QUEUE", + 37: "KV_STAKING_VALIDATOR_QUEUE", + 38: "KV_STAKING_HISTORICAL_INFO", + 39: "KV_STAKING_UNBONDING", + 41: "KV_STAKING_VALIDATORS_BY_POWER", + 40: "KV_DISTRIBUTION", + 42: "KV_DISTRIBUTION_FEE_POOL", + 43: "KV_DISTRIBUTION_PROPOSER_KEY", + 44: "KV_DISTRIBUTION_OUTSTANDING_REWARDS", + 45: "KV_DISTRIBUTION_DELEGATOR_WITHDRAW_ADDR", + 46: "KV_DISTRIBUTION_DELEGATOR_STARTING_INFO", + 47: "KV_DISTRIBUTION_VAL_HISTORICAL_REWARDS", + 48: "KV_DISTRIBUTION_VAL_CURRENT_REWARDS", + 49: "KV_DISTRIBUTION_VAL_ACCUM_COMMISSION", + 50: "KV_DISTRIBUTION_SLASH_EVENT", + 51: "KV_DEX_CONTRACT_LONGBOOK", + 52: "KV_DEX_CONTRACT_SHORTBOOK", + 53: "KV_DEX_SETTLEMENT", + 54: "KV_DEX_PAIR_PREFIX", + 55: "KV_DEX_TWAP", + 56: "KV_DEX_PRICE", + 57: "KV_DEX_SETTLEMENT_ENTRY", + 58: "KV_DEX_REGISTERED_PAIR", + 60: "KV_DEX_ORDER", + 61: "KV_DEX_CANCEL", + 62: "KV_DEX_ACCOUNT_ACTIVE_ORDERS", + 64: "KV_DEX_ASSET_LIST", + 65: "KV_DEX_NEXT_ORDER_ID", + 66: "KV_DEX_NEXT_SETTLEMENT_ID", + 67: "KV_DEX_MATCH_RESULT", + 68: "KV_DEX_SETTLEMENT_ORDER_ID", + 69: "KV_DEX_ORDER_BOOK", + 71: "KV_ACCESSCONTROL", + 72: "KV_ACCESSCONTROL_WASM_DEPENDENCY_MAPPING", + 73: "KV_WASM_CODE", + 74: "KV_WASM_CONTRACT_ADDRESS", + 75: "KV_WASM_CONTRACT_STORE", + 76: "KV_WASM_SEQUENCE_KEY", + 77: "KV_WASM_CONTRACT_CODE_HISTORY", + 78: "KV_WASM_CONTRACT_BY_CODE_ID", + 79: "KV_WASM_PINNED_CODE_INDEX", + 80: "KV_AUTH_GLOBAL_ACCOUNT_NUMBER", + 81: "KV_AUTHZ", + 82: "KV_FEEGRANT", + 83: "KV_FEEGRANT_ALLOWANCE", + 84: "KV_SLASHING", + 85: "KV_SLASHING_VAL_SIGNING_INFO", + 86: "KV_SLASHING_ADDR_PUBKEY_RELATION_KEY", + 87: "KV_DEX_MEM_ORDER", + 88: "KV_DEX_MEM_CANCEL", + 89: "KV_DEX_MEM_DEPOSIT", + 90: "KV_DEX_CONTRACT", + 91: "KV_DEX_LONG_ORDER_COUNT", + 92: "KV_DEX_SHORT_ORDER_COUNT", + 93: "KV_BANK_DEFERRED", + 95: "KV_BANK_DEFERRED_MODULE_TX_INDEX", + 96: "KV_EVM", + 97: "KV_EVM_BALANCE", + 98: "KV_EVM_TRANSIENT", + 99: "KV_EVM_ACCOUNT_TRANSIENT", + 100: "KV_EVM_MODULE_TRANSIENT", + 101: "KV_EVM_NONCE", + 102: "KV_EVM_RECEIPT", + 103: "KV_EVM_S2E", + 104: "KV_EVM_E2S", + 105: "KV_EVM_CODE_HASH", + 106: "KV_EVM_CODE", + 107: "KV_EVM_CODE_SIZE", + 108: "KV_DEX_MEM_CONTRACTS_TO_PROCESS", + 109: "KV_DEX_MEM_DOWNSTREAM_CONTRACTS", } var ResourceType_value = map[string]int32{ @@ -389,8 +413,20 @@ var ResourceType_value = map[string]int32{ "KV_DEX_SHORT_ORDER_COUNT": 92, "KV_BANK_DEFERRED": 93, "KV_BANK_DEFERRED_MODULE_TX_INDEX": 95, - "KV_DEX_MEM_CONTRACTS_TO_PROCESS": 96, - "KV_DEX_MEM_DOWNSTREAM_CONTRACTS": 97, + "KV_EVM": 96, + "KV_EVM_BALANCE": 97, + "KV_EVM_TRANSIENT": 98, + "KV_EVM_ACCOUNT_TRANSIENT": 99, + "KV_EVM_MODULE_TRANSIENT": 100, + "KV_EVM_NONCE": 101, + "KV_EVM_RECEIPT": 102, + "KV_EVM_S2E": 103, + "KV_EVM_E2S": 104, + "KV_EVM_CODE_HASH": 105, + "KV_EVM_CODE": 106, + "KV_EVM_CODE_SIZE": 107, + "KV_DEX_MEM_CONTRACTS_TO_PROCESS": 108, + "KV_DEX_MEM_DOWNSTREAM_CONTRACTS": 109, } func (x ResourceType) String() string { @@ -438,98 +474,104 @@ func init() { } var fileDescriptor_36568f7561081112 = []byte{ - // 1487 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x57, 0xdb, 0x76, 0x1b, 0xb7, - 0x15, 0x95, 0x2c, 0x4a, 0xa2, 0x20, 0xd9, 0x3e, 0x86, 0xe5, 0xab, 0x64, 0xda, 0x91, 0xd5, 0xd8, - 0x55, 0x1c, 0x29, 0x8e, 0x7b, 0x4d, 0xda, 0xa6, 0xe0, 0xe0, 0x90, 0x1c, 0x71, 0x06, 0x18, 0x02, - 0x18, 0x5e, 0xdc, 0x36, 0xa8, 0xc4, 0x72, 0xa5, 0x59, 0x8d, 0x44, 0x2f, 0x91, 0xee, 0x6a, 0xbf, - 0xa1, 0x2f, 0xfd, 0x94, 0x7e, 0x46, 0x1f, 0xf3, 0xd8, 0xc7, 0x2e, 0xfb, 0x47, 0xba, 0x30, 0x03, - 0xd2, 0xc3, 0x89, 0x5c, 0x3f, 0x49, 0x3c, 0x7b, 0xe3, 0x0c, 0xce, 0x3e, 0xb7, 0x19, 0xb2, 0x3f, - 0x1c, 0x4f, 0xce, 0xc6, 0x93, 0xa3, 0x93, 0xe1, 0x70, 0x34, 0x99, 0x0c, 0xc7, 0xe7, 0xd3, 0x8b, - 0xf1, 0x77, 0x47, 0xc3, 0xf1, 0xf9, 0x64, 0x7a, 0x72, 0x3e, 0x9d, 0x1c, 0xbe, 0xba, 0x18, 0x4f, - 0xc7, 0x74, 0x37, 0x67, 0x1d, 0x2e, 0xb0, 0x0e, 0xff, 0xfa, 0xfc, 0x74, 0x34, 0x3d, 0x79, 0x7e, - 0xf0, 0x05, 0x21, 0x2c, 0x03, 0xcc, 0xdf, 0x5f, 0x8d, 0xe8, 0x26, 0x59, 0x4f, 0x45, 0x5b, 0xc8, - 0x9e, 0x80, 0x25, 0x5a, 0x25, 0x15, 0x85, 0x8c, 0xc3, 0x32, 0xdd, 0x20, 0xab, 0x3d, 0x15, 0x1a, - 0x84, 0x2b, 0x94, 0x90, 0xb5, 0x40, 0xc6, 0x71, 0x68, 0x60, 0xe5, 0xe0, 0x1f, 0x57, 0xc8, 0x4e, - 0x7e, 0x58, 0xbe, 0x1a, 0x5d, 0x9c, 0x4c, 0xbf, 0x1d, 0x9f, 0xeb, 0xd1, 0x77, 0xa3, 0xe1, 0x74, - 0x7c, 0x91, 0x79, 0xab, 0x92, 0x8a, 0x90, 0x02, 0x61, 0x89, 0xae, 0x91, 0x2b, 0xc7, 0x1d, 0x58, - 0xa6, 0xb7, 0xc8, 0x8d, 0xe3, 0x8e, 0xad, 0x63, 0xd0, 0x7a, 0xf1, 0xb9, 0x65, 0x9c, 0x2b, 0xd4, - 0x1a, 0xae, 0xd0, 0x1a, 0xb9, 0x7f, 0xdc, 0xb1, 0x11, 0x8a, 0xa6, 0x69, 0xd9, 0x44, 0x61, 0x23, - 0xec, 0x23, 0x9f, 0xe3, 0x2b, 0xf4, 0x1e, 0xb9, 0xa5, 0x51, 0x70, 0x54, 0xe5, 0xa3, 0x15, 0xba, - 0x47, 0x6a, 0x1e, 0x7a, 0xdf, 0xf1, 0x55, 0xba, 0x4d, 0x20, 0x90, 0xc2, 0x28, 0x16, 0x98, 0xb9, - 0x75, 0x8d, 0xde, 0x27, 0xb7, 0x8f, 0x3b, 0x36, 0x46, 0xad, 0x59, 0x13, 0x6d, 0x20, 0x05, 0x0f, - 0x4d, 0x28, 0x05, 0x8b, 0x60, 0xdd, 0x61, 0x81, 0x14, 0xda, 0x30, 0x61, 0xac, 0x36, 0x2a, 0x14, - 0x4d, 0x6b, 0xa4, 0x6d, 0x61, 0x1f, 0xaa, 0xf4, 0x36, 0xa1, 0x73, 0x6f, 0x0a, 0x1b, 0xa8, 0x50, - 0x04, 0x08, 0x1b, 0x07, 0xff, 0xda, 0x26, 0x5b, 0x6a, 0x34, 0x19, 0xbf, 0xbe, 0x18, 0x8e, 0xb2, - 0xf0, 0xd7, 0xc9, 0x0a, 0x13, 0x83, 0x3c, 0xfa, 0x76, 0x17, 0x96, 0x9d, 0x21, 0x1e, 0x9d, 0xe5, - 0x22, 0xf2, 0xd1, 0xdf, 0xdc, 0xff, 0x2b, 0x4e, 0xf2, 0x76, 0xd7, 0xd6, 0x99, 0x68, 0x43, 0x85, - 0x5e, 0x23, 0xa4, 0xdd, 0xb5, 0xda, 0xb0, 0x76, 0x28, 0x9a, 0xb0, 0xea, 0xc1, 0x1e, 0xd3, 0x31, - 0xac, 0xd1, 0xab, 0x64, 0xa3, 0xdd, 0xb5, 0x52, 0xb1, 0x20, 0x42, 0x58, 0x77, 0x4e, 0xda, 0x5d, - 0xcb, 0xb3, 0x3b, 0x6d, 0x91, 0x6a, 0xbb, 0x6b, 0x31, 0x91, 0x41, 0x0b, 0x36, 0xe8, 0x4d, 0x72, - 0xbd, 0xdd, 0xb5, 0x46, 0xb6, 0x51, 0x34, 0x58, 0x60, 0xa4, 0x1a, 0x00, 0x71, 0x21, 0xcd, 0x4f, - 0xdb, 0xae, 0x34, 0x68, 0x0d, 0x53, 0x4d, 0x34, 0x1a, 0x36, 0xe9, 0x03, 0x72, 0xef, 0x1d, 0xc6, - 0x9a, 0x4d, 0x85, 0x4d, 0x66, 0x72, 0x96, 0x86, 0x2d, 0x97, 0xb5, 0x77, 0x70, 0x03, 0x91, 0xa3, - 0xd2, 0x70, 0xd5, 0x65, 0xe5, 0xdd, 0x65, 0x2d, 0xc7, 0xc8, 0x9d, 0x0a, 0xa5, 0x80, 0x6b, 0xf4, - 0x2e, 0xd9, 0x2e, 0x40, 0x5d, 0x16, 0x85, 0x9c, 0x19, 0xa9, 0xe0, 0xba, 0x8f, 0x88, 0xa5, 0xa6, - 0x05, 0xe0, 0x3d, 0xb8, 0x1f, 0xb3, 0xbc, 0x58, 0x6d, 0xa4, 0x42, 0xb8, 0x41, 0x29, 0xb9, 0xe6, - 0x65, 0xb1, 0x3a, 0x4d, 0x92, 0x68, 0x00, 0x94, 0xde, 0x20, 0x57, 0x67, 0x36, 0x8e, 0x42, 0xc6, - 0x70, 0xd3, 0xa5, 0x76, 0x66, 0xaa, 0xb3, 0x88, 0x89, 0x00, 0x35, 0x6c, 0x7b, 0xbf, 0x45, 0x01, - 0xfc, 0x81, 0x5b, 0x74, 0x97, 0xdc, 0x2d, 0x43, 0x31, 0x1a, 0xc6, 0x99, 0x61, 0x70, 0xfb, 0xb2, - 0x83, 0x8c, 0xc7, 0xa1, 0x80, 0x3b, 0x74, 0x87, 0xdc, 0x29, 0x43, 0x81, 0xc2, 0x2c, 0xaa, 0xbb, - 0x1e, 0xf4, 0x0a, 0x61, 0x3f, 0x68, 0x31, 0xd1, 0x44, 0xab, 0x98, 0x41, 0xb8, 0xe7, 0x4a, 0xb4, - 0xa4, 0x7c, 0x82, 0x82, 0x45, 0x66, 0x60, 0x03, 0x99, 0x0a, 0x83, 0x0a, 0xee, 0xfb, 0x6b, 0x79, - 0x4e, 0xa2, 0xc2, 0x00, 0xad, 0x16, 0x2c, 0xd1, 0x2d, 0x69, 0x60, 0x87, 0x3e, 0x24, 0x3b, 0x3f, - 0x94, 0x33, 0x94, 0xc2, 0x26, 0xb2, 0x87, 0x0a, 0x76, 0x7d, 0x72, 0x67, 0x04, 0x23, 0x0d, 0x8b, - 0x3c, 0xf6, 0xc0, 0x3f, 0xfe, 0x07, 0xb9, 0xd0, 0xae, 0xe4, 0x33, 0xd9, 0xa1, 0x46, 0x1f, 0x93, - 0x87, 0x05, 0x4e, 0x2a, 0xea, 0xae, 0x1b, 0x16, 0x93, 0xfa, 0x90, 0x3e, 0x21, 0x8f, 0x3f, 0x40, - 0x72, 0xde, 0xe1, 0x91, 0x57, 0x63, 0x46, 0x54, 0x58, 0xf0, 0xf2, 0x51, 0xe9, 0x51, 0x45, 0xd0, - 0x9d, 0xb6, 0x5a, 0x05, 0xb0, 0xf7, 0x21, 0x12, 0xd7, 0x06, 0x1e, 0xd3, 0x8f, 0xc8, 0x83, 0xf7, - 0x91, 0x3a, 0x29, 0xa6, 0x08, 0xfb, 0x6e, 0xb0, 0x5c, 0x16, 0xbb, 0xc7, 0x7f, 0x54, 0xc2, 0x5b, - 0xa1, 0xab, 0xbe, 0x30, 0x60, 0x91, 0x0d, 0x45, 0x43, 0xc2, 0xc7, 0xa5, 0x3a, 0x9e, 0x87, 0x0c, - 0x4f, 0xde, 0xaf, 0x6a, 0x7d, 0xe0, 0x95, 0xff, 0xb1, 0xef, 0x43, 0x1e, 0xba, 0x09, 0x52, 0x4f, - 0xb3, 0xf8, 0x9f, 0xfa, 0x4c, 0x17, 0x8d, 0xae, 0xa5, 0x6c, 0x22, 0x65, 0x04, 0x07, 0xf4, 0x11, - 0xd9, 0x2d, 0xa3, 0x89, 0x92, 0x89, 0xd4, 0xa8, 0x6c, 0x1b, 0x07, 0xf0, 0x89, 0xcf, 0xc2, 0x02, - 0x43, 0xa6, 0xc6, 0x8d, 0x2a, 0x9e, 0xcb, 0xd0, 0x63, 0x8a, 0x6b, 0x78, 0x46, 0x3f, 0x21, 0x4f, - 0xca, 0x44, 0xaf, 0x90, 0x54, 0xb6, 0x17, 0x9a, 0x16, 0x57, 0xac, 0x97, 0x17, 0xc0, 0xa7, 0xff, - 0x9f, 0xac, 0x0d, 0x53, 0xc6, 0x39, 0xcf, 0x54, 0x39, 0xa4, 0x07, 0xe4, 0xe3, 0x32, 0xd9, 0x65, - 0xa5, 0x20, 0xdf, 0xec, 0x16, 0x47, 0x97, 0x5d, 0xd7, 0x71, 0x83, 0x54, 0x29, 0x14, 0x66, 0x4e, - 0xfc, 0x8c, 0x3e, 0x25, 0xfb, 0x97, 0x11, 0x59, 0x10, 0xa4, 0xb1, 0xcd, 0x56, 0x8e, 0xd6, 0x4e, - 0xc1, 0xe7, 0xbe, 0x1b, 0x16, 0x98, 0x3a, 0x62, 0xba, 0x65, 0xb1, 0x8b, 0xc2, 0xc0, 0xe7, 0x33, - 0x89, 0xb1, 0x6f, 0xe7, 0x83, 0x3a, 0x92, 0xa2, 0x59, 0x97, 0xb2, 0x0d, 0x2f, 0xfc, 0xb0, 0x5b, - 0x40, 0x75, 0x4b, 0x2a, 0x93, 0xc1, 0x3f, 0xf1, 0xc3, 0xce, 0xc1, 0x1a, 0x8d, 0x89, 0x30, 0x76, - 0x3e, 0x7f, 0xea, 0xa6, 0xbe, 0x37, 0x27, 0x2c, 0x54, 0x7e, 0xcb, 0xc0, 0xcf, 0xe8, 0x75, 0xb2, - 0xe9, 0xed, 0xa6, 0xc7, 0x12, 0xf8, 0x39, 0x05, 0xb2, 0x35, 0x23, 0xba, 0x36, 0x86, 0x5f, 0xf8, - 0x76, 0x58, 0xf4, 0x68, 0x51, 0x18, 0x35, 0x80, 0x5f, 0xfa, 0xce, 0x75, 0xa0, 0xc2, 0x66, 0xa8, - 0x0d, 0x2a, 0xe4, 0xd9, 0x23, 0xe0, 0x8b, 0x82, 0x2b, 0xa9, 0x38, 0x2a, 0xf8, 0x95, 0x9f, 0x80, - 0xd9, 0xdd, 0xdd, 0xac, 0x8b, 0xe0, 0xd7, 0xb3, 0x8a, 0xc1, 0xbe, 0x93, 0xca, 0xcd, 0x13, 0xcb, - 0x02, 0x13, 0x76, 0x31, 0x3f, 0xa3, 0xe1, 0x37, 0x85, 0x88, 0x98, 0xd6, 0x68, 0x6c, 0x14, 0x6a, - 0x03, 0xbf, 0xf5, 0xb5, 0xed, 0xcc, 0x02, 0xfb, 0x26, 0xa7, 0xdb, 0x90, 0x03, 0x2b, 0x28, 0x94, - 0x21, 0x85, 0x5b, 0x87, 0x1c, 0xea, 0xf4, 0x0e, 0xb9, 0xe9, 0xe1, 0x98, 0x99, 0xa0, 0x65, 0x15, - 0xea, 0x34, 0x32, 0x10, 0xf8, 0x6e, 0x2a, 0x05, 0x3a, 0xf7, 0xcb, 0x0b, 0x17, 0xc9, 0x8d, 0x99, - 0xe2, 0xe8, 0x67, 0x38, 0x0b, 0x02, 0xd4, 0x3a, 0x4b, 0x89, 0x8c, 0xa0, 0x49, 0x9f, 0x91, 0xa7, - 0x65, 0x6b, 0xb6, 0x08, 0x2d, 0xc7, 0xc4, 0x2d, 0x7c, 0x11, 0x0c, 0x6c, 0xcc, 0x92, 0xc4, 0xb5, - 0x63, 0xcb, 0x4b, 0x95, 0xe1, 0x81, 0xe4, 0x08, 0xa1, 0x2f, 0x02, 0x6f, 0x29, 0x2d, 0xff, 0x63, - 0x2f, 0xfb, 0x22, 0x9a, 0xaf, 0x9e, 0xb6, 0x17, 0x26, 0xc3, 0x34, 0x76, 0x52, 0xb7, 0xde, 0xb3, - 0xde, 0x8b, 0xfc, 0xc4, 0x59, 0x3c, 0xe5, 0x1e, 0xe7, 0x4b, 0x7f, 0x00, 0xb1, 0x2f, 0xce, 0x45, - 0x4a, 0x7d, 0x90, 0xb3, 0x42, 0x0e, 0xc2, 0x8b, 0x9b, 0x11, 0x92, 0x50, 0x08, 0xe4, 0x1e, 0x13, - 0x6e, 0x93, 0x4b, 0xff, 0x88, 0x6c, 0x25, 0x36, 0x23, 0x59, 0xcf, 0x3b, 0x20, 0x4b, 0xab, 0x48, - 0xe3, 0x3a, 0x2a, 0x48, 0xfc, 0xb2, 0x77, 0x94, 0x97, 0xd0, 0xf1, 0x05, 0xd8, 0x40, 0x6c, 0x2a, - 0x26, 0x0c, 0x28, 0xbf, 0xc3, 0x66, 0x06, 0xcb, 0xa2, 0x48, 0xf6, 0x5c, 0xb1, 0x80, 0xf6, 0xdc, - 0xac, 0x59, 0x9c, 0x6c, 0xc6, 0x17, 0xcf, 0xcc, 0x90, 0x0f, 0xe0, 0xb0, 0x29, 0xe6, 0xbd, 0x9e, - 0xfa, 0xb6, 0x9c, 0x33, 0x9c, 0x82, 0x36, 0x49, 0xeb, 0x6d, 0x1c, 0x58, 0x85, 0x51, 0x3e, 0x6d, - 0x9d, 0x38, 0x5d, 0x9f, 0xc6, 0xac, 0x2c, 0x30, 0xf6, 0x15, 0xdb, 0x2b, 0xe4, 0xdc, 0x59, 0x7d, - 0xd5, 0xf6, 0x0b, 0xed, 0xe4, 0xcc, 0x1c, 0x13, 0xa9, 0x43, 0x03, 0x83, 0xd9, 0xc8, 0x2c, 0x34, - 0x27, 0xbc, 0x2c, 0x34, 0x90, 0x6b, 0x63, 0x5f, 0x3c, 0x99, 0x28, 0xf0, 0xbb, 0x42, 0xb3, 0x67, - 0x5d, 0xbc, 0x80, 0xfe, 0xbe, 0xf8, 0x7e, 0xc0, 0xdd, 0xbb, 0x9a, 0x42, 0x0e, 0x7f, 0xa0, 0xfb, - 0xe4, 0x51, 0xd9, 0x6a, 0x63, 0xc9, 0xd3, 0x08, 0xad, 0xe9, 0xfb, 0x54, 0x58, 0xbf, 0x84, 0xe6, - 0x57, 0xf7, 0xf7, 0xd1, 0xee, 0x4d, 0x30, 0x51, 0xd2, 0xd5, 0x25, 0xfc, 0xb1, 0x44, 0xe2, 0xb2, - 0x27, 0xb4, 0x51, 0xc8, 0x0a, 0x7c, 0x38, 0xd9, 0xab, 0x54, 0xbf, 0x84, 0x2f, 0xf7, 0x2a, 0xd5, - 0xaf, 0xe0, 0xab, 0xbd, 0x4a, 0xb5, 0x01, 0x8d, 0xbd, 0x4a, 0xf5, 0x6b, 0xf8, 0xfa, 0xe0, 0x19, - 0xa1, 0xbd, 0x93, 0xc9, 0x59, 0x3c, 0x9a, 0x4c, 0x4e, 0xbe, 0x19, 0xe9, 0xd7, 0xa7, 0x53, 0xf7, - 0xde, 0xb8, 0x41, 0x56, 0x3b, 0x29, 0x2a, 0xf7, 0xe6, 0xb8, 0x49, 0xd6, 0xb1, 0x8f, 0x41, 0x6a, - 0x10, 0x96, 0xeb, 0xc7, 0xff, 0x7e, 0x53, 0x5b, 0xfe, 0xfe, 0x4d, 0x6d, 0xf9, 0xbf, 0x6f, 0x6a, - 0xcb, 0xff, 0x7c, 0x5b, 0x5b, 0xfa, 0xfe, 0x6d, 0x6d, 0xe9, 0x3f, 0x6f, 0x6b, 0x4b, 0x2f, 0x3f, - 0xfb, 0xe6, 0xdb, 0xe9, 0x9f, 0x5f, 0x9f, 0x1e, 0x0e, 0xc7, 0x67, 0x47, 0xfe, 0x9b, 0x20, 0xff, - 0xf3, 0xe9, 0xe4, 0x4f, 0x7f, 0x39, 0x72, 0x4e, 0x4b, 0x1f, 0x09, 0xa7, 0x6b, 0xd9, 0xb7, 0xc1, - 0x8b, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x98, 0x43, 0x58, 0x88, 0x43, 0x0c, 0x00, 0x00, + // 1577 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x57, 0xd9, 0x7a, 0x1b, 0xb7, + 0x15, 0xb6, 0x6c, 0x59, 0x0b, 0xbc, 0x1d, 0xc3, 0xfb, 0x46, 0x3b, 0xb2, 0x1b, 0xbb, 0x8a, 0x23, + 0xc5, 0x76, 0xd7, 0xa4, 0x6d, 0x0a, 0x0e, 0x8e, 0xc8, 0x11, 0x67, 0x80, 0x11, 0x80, 0xe1, 0xe2, + 0xb6, 0x41, 0x25, 0x86, 0x75, 0xdc, 0x58, 0xa6, 0x3f, 0x91, 0xee, 0xd7, 0x3e, 0x43, 0x6f, 0xfa, + 0x10, 0x7d, 0x98, 0x5e, 0xe6, 0xb2, 0x97, 0xfd, 0xec, 0x17, 0xe9, 0x87, 0x99, 0x43, 0x7a, 0x38, + 0xb1, 0x93, 0x2b, 0x89, 0xe7, 0xff, 0x71, 0x00, 0xfc, 0x67, 0xc3, 0xb0, 0x7b, 0xc3, 0xf1, 0xe4, + 0x70, 0x3c, 0xd9, 0xde, 0x1f, 0x0e, 0x47, 0x93, 0xc9, 0x70, 0xfc, 0x72, 0x7a, 0x34, 0x7e, 0xb1, + 0x3d, 0x1c, 0xbf, 0x9c, 0x4c, 0xf7, 0x5f, 0x4e, 0x27, 0x5b, 0xaf, 0x8e, 0xc6, 0xd3, 0x31, 0xbf, + 0x59, 0xb2, 0xb6, 0x16, 0x58, 0x5b, 0x7f, 0x7b, 0x74, 0x30, 0x9a, 0xee, 0x3f, 0xda, 0xfc, 0x9c, + 0x31, 0x51, 0x00, 0xee, 0x1f, 0xaf, 0x46, 0xfc, 0x14, 0x5b, 0xcd, 0x55, 0x47, 0xe9, 0x9e, 0x82, + 0x63, 0x7c, 0x8d, 0x2d, 0x1b, 0x14, 0x12, 0x96, 0xf8, 0x3a, 0x3b, 0xd9, 0x33, 0xb1, 0x43, 0x38, + 0xce, 0x19, 0x5b, 0x89, 0x74, 0x9a, 0xc6, 0x0e, 0x4e, 0x6c, 0xfe, 0xf3, 0x38, 0xbb, 0x51, 0x2e, + 0xd6, 0xaf, 0x46, 0x47, 0xfb, 0xd3, 0xe7, 0xe3, 0x97, 0x76, 0xf4, 0x62, 0x34, 0x9c, 0x8e, 0x8f, + 0x0a, 0x6f, 0x6b, 0x6c, 0x59, 0x69, 0x85, 0x70, 0x8c, 0xaf, 0xb0, 0xe3, 0xbb, 0x7b, 0xb0, 0xc4, + 0x2f, 0xb1, 0xf3, 0xbb, 0x7b, 0xbe, 0x89, 0x51, 0xfb, 0xc9, 0x63, 0x2f, 0xa4, 0x34, 0x68, 0x2d, + 0x1c, 0xe7, 0x0d, 0x76, 0x7d, 0x77, 0xcf, 0x27, 0xa8, 0x5a, 0xae, 0xed, 0x33, 0x83, 0x3b, 0x71, + 0x1f, 0xe5, 0x1c, 0x3f, 0xc1, 0xaf, 0xb1, 0x4b, 0x16, 0x95, 0x44, 0x53, 0x5f, 0xba, 0xcc, 0x37, + 0x58, 0x83, 0xa0, 0x0f, 0x2d, 0x3f, 0xc9, 0x2f, 0x32, 0x88, 0xb4, 0x72, 0x46, 0x44, 0x6e, 0x6e, + 0x5d, 0xe1, 0xd7, 0xd9, 0xe5, 0xdd, 0x3d, 0x9f, 0xa2, 0xb5, 0xa2, 0x85, 0x3e, 0xd2, 0x4a, 0xc6, + 0x2e, 0xd6, 0x4a, 0x24, 0xb0, 0x1a, 0xb0, 0x48, 0x2b, 0xeb, 0x84, 0x72, 0xde, 0x3a, 0x13, 0xab, + 0x96, 0x77, 0xda, 0xb7, 0xb1, 0x0f, 0x6b, 0xfc, 0x32, 0xe3, 0x73, 0x6f, 0x06, 0x77, 0xd0, 0xa0, + 0x8a, 0x10, 0xd6, 0x37, 0xff, 0x7d, 0x99, 0x9d, 0x36, 0xa3, 0xc9, 0xf8, 0xf5, 0xd1, 0x70, 0x54, + 0x5c, 0x7f, 0x95, 0x9d, 0x10, 0x6a, 0x50, 0xde, 0xbe, 0xd3, 0x85, 0xa5, 0x60, 0x48, 0x47, 0x87, + 0xa5, 0x88, 0x72, 0xf4, 0xf7, 0xf0, 0xff, 0x89, 0x20, 0x79, 0xa7, 0xeb, 0x9b, 0x42, 0x75, 0x60, + 0x99, 0x9f, 0x65, 0xac, 0xd3, 0xf5, 0xd6, 0x89, 0x4e, 0xac, 0x5a, 0x70, 0x92, 0xc0, 0x9e, 0xb0, + 0x29, 0xac, 0xf0, 0x33, 0x6c, 0xbd, 0xd3, 0xf5, 0xda, 0x88, 0x28, 0x41, 0x58, 0x0d, 0x4e, 0x3a, + 0x5d, 0x2f, 0x8b, 0x33, 0x9d, 0x66, 0x6b, 0x9d, 0xae, 0xc7, 0x4c, 0x47, 0x6d, 0x58, 0xe7, 0x17, + 0xd8, 0xb9, 0x4e, 0xd7, 0x3b, 0xdd, 0x41, 0xb5, 0x23, 0x22, 0xa7, 0xcd, 0x00, 0x58, 0xb8, 0xd2, + 0x7c, 0xb5, 0xef, 0x6a, 0x87, 0xde, 0x09, 0xd3, 0x42, 0x67, 0xe1, 0x14, 0xbf, 0xc5, 0xae, 0xbd, + 0xc3, 0x44, 0xab, 0x65, 0xb0, 0x25, 0x5c, 0xc9, 0xb2, 0x70, 0x3a, 0x44, 0xed, 0x1d, 0xbc, 0x83, + 0x28, 0xd1, 0x58, 0x38, 0x13, 0xa2, 0xf2, 0xee, 0xb0, 0x5e, 0x62, 0x12, 0x56, 0xc5, 0x5a, 0xc1, + 0x59, 0x7e, 0x95, 0x5d, 0xac, 0x40, 0x5d, 0x91, 0xc4, 0x52, 0x38, 0x6d, 0xe0, 0x1c, 0xdd, 0x48, + 0xe4, 0xae, 0x0d, 0x40, 0x1e, 0xc2, 0x8f, 0x59, 0x5c, 0xbc, 0x75, 0xda, 0x20, 0x9c, 0xe7, 0x9c, + 0x9d, 0x25, 0x59, 0xbc, 0xcd, 0xb3, 0x2c, 0x19, 0x00, 0xe7, 0xe7, 0xd9, 0x99, 0x99, 0x4d, 0xa2, + 0xd2, 0x29, 0x5c, 0x08, 0xa1, 0x9d, 0x99, 0x9a, 0x22, 0x11, 0x2a, 0x42, 0x0b, 0x17, 0xc9, 0x6f, + 0x55, 0x00, 0x5a, 0x70, 0x89, 0xdf, 0x64, 0x57, 0xeb, 0x50, 0x8a, 0x4e, 0x48, 0xe1, 0x04, 0x5c, + 0x7e, 0xdf, 0x42, 0x21, 0xd3, 0x58, 0xc1, 0x15, 0x7e, 0x83, 0x5d, 0xa9, 0x43, 0x91, 0xc1, 0xe2, + 0x56, 0x57, 0x09, 0x24, 0x85, 0xb0, 0x1f, 0xb5, 0x85, 0x6a, 0xa1, 0x37, 0xc2, 0x21, 0x5c, 0x0b, + 0x29, 0x5a, 0x53, 0x3e, 0x43, 0x25, 0x12, 0x37, 0xf0, 0x91, 0xce, 0x95, 0x43, 0x03, 0xd7, 0xe9, + 0x58, 0xc4, 0xc9, 0x4c, 0x1c, 0xa1, 0xb7, 0x4a, 0x64, 0xb6, 0xad, 0x1d, 0xdc, 0xe0, 0xb7, 0xd9, + 0x8d, 0xef, 0xcb, 0x19, 0x6b, 0xe5, 0x33, 0xdd, 0x43, 0x03, 0x37, 0x29, 0xb8, 0x33, 0x82, 0xd3, + 0x4e, 0x24, 0x84, 0xdd, 0xa2, 0xed, 0xbf, 0x17, 0x0b, 0x1b, 0x52, 0xbe, 0x90, 0x1d, 0x1a, 0xfc, + 0x2e, 0xbb, 0x5d, 0xe1, 0xe4, 0xaa, 0x19, 0xaa, 0x61, 0x31, 0xa8, 0xb7, 0xf9, 0x7d, 0x76, 0xf7, + 0x47, 0x48, 0xc1, 0x3b, 0xdc, 0x21, 0x35, 0x66, 0x44, 0x83, 0x15, 0x2f, 0x1f, 0xd5, 0xb6, 0xaa, + 0x82, 0x61, 0xb5, 0xb7, 0x26, 0x82, 0x8d, 0x1f, 0x23, 0x49, 0xeb, 0xe0, 0x2e, 0xff, 0x88, 0xdd, + 0xfa, 0x10, 0x69, 0x2f, 0xc7, 0x1c, 0xe1, 0x5e, 0x68, 0x2c, 0xef, 0xbb, 0x3b, 0xe1, 0x3f, 0xa9, + 0xe1, 0xed, 0x38, 0x64, 0x5f, 0x1c, 0x89, 0xc4, 0xc7, 0x6a, 0x47, 0xc3, 0xc7, 0xb5, 0x3c, 0x9e, + 0x5f, 0x19, 0xee, 0x7f, 0x58, 0xd5, 0xe6, 0x80, 0x94, 0xff, 0x29, 0xd5, 0xa1, 0x8c, 0x43, 0x07, + 0x69, 0xe6, 0xc5, 0xfd, 0x1f, 0x50, 0xa4, 0xab, 0xc6, 0x50, 0x52, 0x3e, 0xd3, 0x3a, 0x81, 0x4d, + 0x7e, 0x87, 0xdd, 0xac, 0xa3, 0x99, 0xd1, 0x99, 0xb6, 0x68, 0x7c, 0x07, 0x07, 0xf0, 0x09, 0x45, + 0x61, 0x81, 0xa1, 0x73, 0x17, 0x5a, 0x95, 0x2c, 0x65, 0xe8, 0x09, 0x23, 0x2d, 0x3c, 0xe4, 0x9f, + 0xb0, 0xfb, 0x75, 0x22, 0x29, 0xa4, 0x8d, 0xef, 0xc5, 0xae, 0x2d, 0x8d, 0xe8, 0x95, 0x09, 0xf0, + 0xe9, 0x0f, 0x93, 0xad, 0x13, 0xc6, 0x05, 0xe7, 0x85, 0x2a, 0x5b, 0x7c, 0x93, 0x7d, 0x5c, 0x27, + 0x87, 0xa8, 0x54, 0xe4, 0x9b, 0x9d, 0x62, 0xfb, 0x7d, 0xc7, 0x0d, 0xdc, 0x28, 0x37, 0x06, 0x95, + 0x9b, 0x13, 0x3f, 0xe3, 0x0f, 0xd8, 0xbd, 0xf7, 0x11, 0x45, 0x14, 0xe5, 0xa9, 0x2f, 0x46, 0x8e, + 0xb5, 0x41, 0xc1, 0x47, 0x54, 0x0d, 0x0b, 0x4c, 0x9b, 0x08, 0xdb, 0xf6, 0xd8, 0x45, 0xe5, 0xe0, + 0xf1, 0x4c, 0x62, 0xec, 0xfb, 0x79, 0xa3, 0x4e, 0xb4, 0x6a, 0x35, 0xb5, 0xee, 0xc0, 0x13, 0x6a, + 0x76, 0x0b, 0xa8, 0x6d, 0x6b, 0xe3, 0x0a, 0xf8, 0x67, 0xd4, 0xec, 0x02, 0x6c, 0xd1, 0xb9, 0x04, + 0xd3, 0xe0, 0xf3, 0xe7, 0xa1, 0xeb, 0x93, 0x39, 0x13, 0xb1, 0xa1, 0x29, 0x03, 0xbf, 0xe0, 0xe7, + 0xd8, 0x29, 0xb2, 0xbb, 0x9e, 0xc8, 0xe0, 0x97, 0x1c, 0xd8, 0xe9, 0x19, 0x31, 0x94, 0x31, 0xfc, + 0x8a, 0xca, 0x61, 0xd1, 0xa3, 0x47, 0xe5, 0xcc, 0x00, 0x7e, 0x4d, 0x95, 0x1b, 0x40, 0x83, 0xad, + 0xd8, 0x3a, 0x34, 0x28, 0x8b, 0x2d, 0xe0, 0xf3, 0x8a, 0x2b, 0x6d, 0x24, 0x1a, 0xf8, 0x0d, 0x75, + 0xc0, 0xe2, 0xec, 0xa1, 0xd7, 0x25, 0xf0, 0xdb, 0x59, 0xc6, 0x60, 0x3f, 0x48, 0x15, 0xfa, 0x89, + 0x17, 0x91, 0x8b, 0xbb, 0x58, 0xae, 0xb1, 0xf0, 0xbb, 0xca, 0x8d, 0x84, 0xb5, 0xe8, 0x7c, 0x12, + 0x5b, 0x07, 0xbf, 0xa7, 0xdc, 0x0e, 0x66, 0x85, 0x7d, 0x57, 0xd2, 0x7d, 0x2c, 0x41, 0x54, 0x14, + 0x2a, 0x90, 0xca, 0xa9, 0x63, 0x09, 0x4d, 0x7e, 0x85, 0x5d, 0x20, 0x38, 0x15, 0x2e, 0x6a, 0x7b, + 0x83, 0x36, 0x4f, 0x1c, 0x44, 0x54, 0x4d, 0xb5, 0x8b, 0xce, 0xfd, 0xca, 0xca, 0x41, 0x4a, 0x63, + 0xa1, 0x38, 0x52, 0x0f, 0x17, 0x51, 0x84, 0xd6, 0x16, 0x21, 0xd1, 0x09, 0xb4, 0xf8, 0x43, 0xf6, + 0xa0, 0x6e, 0x2d, 0x06, 0xa1, 0x97, 0x98, 0x85, 0x81, 0xaf, 0xa2, 0x81, 0x4f, 0x45, 0x96, 0x85, + 0x72, 0x6c, 0x93, 0x54, 0x05, 0x1e, 0x69, 0x89, 0x10, 0x53, 0x12, 0x90, 0xa5, 0x36, 0xfc, 0x77, + 0x49, 0xf6, 0x45, 0xb4, 0x1c, 0x3d, 0x1d, 0x12, 0xa6, 0xc0, 0x2c, 0xee, 0xe5, 0x61, 0xbc, 0x17, + 0xb5, 0x97, 0x50, 0xc7, 0x59, 0x5c, 0x15, 0xb6, 0xa3, 0xd4, 0x1f, 0x40, 0x4a, 0xc9, 0xb9, 0x48, + 0x69, 0x0e, 0x4a, 0x56, 0x2c, 0x41, 0x91, 0xb8, 0x05, 0x21, 0x8b, 0x95, 0x42, 0x49, 0x98, 0x0a, + 0x93, 0x5c, 0xd3, 0x16, 0xc5, 0x48, 0x6c, 0x25, 0xba, 0x59, 0x56, 0x40, 0x11, 0x56, 0x95, 0xa7, + 0x4d, 0x34, 0x90, 0xd1, 0xb0, 0x0f, 0x94, 0xa7, 0xb0, 0x47, 0x09, 0xb8, 0x83, 0xd8, 0x32, 0x42, + 0x39, 0x30, 0x34, 0xc3, 0x66, 0x06, 0x2f, 0x92, 0x44, 0xf7, 0x42, 0xb2, 0x80, 0x25, 0x6e, 0x51, + 0x2c, 0x41, 0x36, 0x47, 0xc9, 0x33, 0x33, 0x94, 0x0d, 0x38, 0x6e, 0xa9, 0x79, 0xad, 0xe7, 0x54, + 0x96, 0x73, 0x46, 0x50, 0xd0, 0x67, 0x79, 0xb3, 0x83, 0x03, 0x6f, 0x30, 0x29, 0xbb, 0x6d, 0x10, + 0xa7, 0x4b, 0x61, 0x2c, 0xd2, 0x02, 0x53, 0xca, 0xd8, 0x5e, 0x25, 0xe6, 0xc1, 0x4a, 0x59, 0xdb, + 0xaf, 0x94, 0x53, 0x30, 0x4b, 0xcc, 0xb4, 0x8d, 0x1d, 0x0c, 0x66, 0x2d, 0xb3, 0x52, 0x9c, 0xf0, + 0xb4, 0x52, 0x40, 0xa1, 0x8c, 0x29, 0x79, 0x0a, 0x51, 0xe0, 0x0f, 0x95, 0x62, 0x2f, 0xaa, 0x78, + 0x01, 0xfd, 0x63, 0xf5, 0x7d, 0x20, 0xc3, 0x5b, 0xcd, 0xa0, 0x84, 0x3f, 0xf1, 0x7b, 0xec, 0x4e, + 0xdd, 0xea, 0x53, 0x2d, 0xf3, 0x04, 0xbd, 0xeb, 0x53, 0x28, 0x3c, 0x3d, 0xb0, 0xb0, 0x9b, 0xc2, + 0x9f, 0xe9, 0x39, 0x82, 0xdd, 0x74, 0xf6, 0xcc, 0x80, 0x7d, 0xf2, 0x1d, 0x6c, 0xce, 0x08, 0x65, + 0xe3, 0xd0, 0x28, 0x0e, 0xe8, 0x3c, 0xc1, 0x3a, 0x0b, 0xdc, 0x3b, 0x74, 0x48, 0x57, 0x09, 0xe8, + 0x6c, 0xbf, 0x39, 0xf8, 0x35, 0x25, 0x71, 0x00, 0x95, 0x0e, 0x5b, 0x8c, 0x2a, 0xdb, 0x1a, 0x8c, + 0x30, 0xce, 0x1c, 0xfc, 0x85, 0xde, 0x88, 0xc1, 0x66, 0x1f, 0x23, 0x3c, 0xab, 0xfc, 0xc6, 0xc7, + 0x16, 0xbe, 0xa9, 0x1c, 0xab, 0x4c, 0x4d, 0x61, 0xdb, 0xf0, 0x9c, 0x42, 0x3f, 0xb3, 0xc2, 0x5f, + 0xeb, 0x34, 0x1b, 0x3f, 0x45, 0xf8, 0x96, 0x06, 0xef, 0x3c, 0x5c, 0x14, 0x03, 0x1b, 0x5e, 0xbf, + 0x99, 0xd1, 0xa1, 0x16, 0xe1, 0x45, 0x8d, 0x24, 0x75, 0x4f, 0x59, 0x67, 0x50, 0x54, 0xf8, 0x70, + 0xb8, 0xb1, 0xbc, 0xf6, 0x05, 0x7c, 0xb1, 0xb1, 0xbc, 0xf6, 0x25, 0x7c, 0xb9, 0xb1, 0xbc, 0xb6, + 0x03, 0x3b, 0x1b, 0xcb, 0x6b, 0x5f, 0xc1, 0x57, 0x9b, 0x0f, 0x19, 0xef, 0xed, 0x4f, 0x0e, 0xd3, + 0xd1, 0x64, 0xb2, 0xff, 0x6c, 0x64, 0x5f, 0x1f, 0x4c, 0xc3, 0x5b, 0x79, 0x9d, 0x9d, 0xdc, 0xcb, + 0xd1, 0x84, 0xd7, 0xf2, 0x29, 0xb6, 0x8a, 0x7d, 0x8c, 0x72, 0x87, 0xb0, 0xd4, 0xdc, 0xfd, 0xcf, + 0x9b, 0xc6, 0xd2, 0x77, 0x6f, 0x1a, 0x4b, 0xff, 0x7b, 0xd3, 0x58, 0xfa, 0xd7, 0xdb, 0xc6, 0xb1, + 0xef, 0xde, 0x36, 0x8e, 0xfd, 0xf7, 0x6d, 0xe3, 0xd8, 0xd3, 0xcf, 0x9e, 0x3d, 0x9f, 0x7e, 0xf3, + 0xfa, 0x60, 0x6b, 0x38, 0x3e, 0xdc, 0xa6, 0xef, 0xa0, 0xf2, 0xcf, 0xa7, 0x93, 0xaf, 0xbf, 0xdd, + 0x0e, 0x4e, 0x6b, 0x1f, 0x46, 0x07, 0x2b, 0xc5, 0xf7, 0xd0, 0x93, 0xff, 0x07, 0x00, 0x00, 0xff, + 0xff, 0xbd, 0x5c, 0x9f, 0xd6, 0x37, 0x0d, 0x00, 0x00, } diff --git a/types/accesscontrol/resource.go b/types/accesscontrol/resource.go index 3ad944683..19cffa4b7 100644 --- a/types/accesscontrol/resource.go +++ b/types/accesscontrol/resource.go @@ -22,6 +22,7 @@ var ResourceTree = map[ResourceType]TreeNode{ ResourceType_KV_FEEGRANT, ResourceType_KV_SLASHING, ResourceType_KV_BANK_DEFERRED, + ResourceType_KV_EVM, }}, ResourceType_Mem: {ResourceType_ANY, []ResourceType{ ResourceType_DexMem, @@ -198,6 +199,30 @@ var ResourceTree = map[ResourceType]TreeNode{ ResourceType_KV_DEX_MEM_DEPOSIT: {ResourceType_KV_DEX, []ResourceType{}}, ResourceType_KV_DEX_MEM_CONTRACTS_TO_PROCESS: {ResourceType_KV_DEX, []ResourceType{}}, ResourceType_KV_DEX_MEM_DOWNSTREAM_CONTRACTS: {ResourceType_KV_DEX, []ResourceType{}}, + ResourceType_KV_EVM: {ResourceType_KV, []ResourceType{ + ResourceType_KV_EVM_BALANCE, + ResourceType_KV_EVM_TRANSIENT, + ResourceType_KV_EVM_ACCOUNT_TRANSIENT, + ResourceType_KV_EVM_MODULE_TRANSIENT, + ResourceType_KV_EVM_NONCE, + ResourceType_KV_EVM_RECEIPT, + ResourceType_KV_EVM_S2E, + ResourceType_KV_EVM_E2S, + ResourceType_KV_EVM_CODE_HASH, + ResourceType_KV_EVM_CODE, + ResourceType_KV_EVM_CODE_SIZE, + }}, + ResourceType_KV_EVM_BALANCE: {ResourceType_KV_EVM, []ResourceType{}}, + ResourceType_KV_EVM_TRANSIENT: {ResourceType_KV_EVM, []ResourceType{}}, + ResourceType_KV_EVM_ACCOUNT_TRANSIENT: {ResourceType_KV_EVM, []ResourceType{}}, + ResourceType_KV_EVM_MODULE_TRANSIENT: {ResourceType_KV_EVM, []ResourceType{}}, + ResourceType_KV_EVM_NONCE: {ResourceType_KV_EVM, []ResourceType{}}, + ResourceType_KV_EVM_RECEIPT: {ResourceType_KV_EVM, []ResourceType{}}, + ResourceType_KV_EVM_S2E: {ResourceType_KV_EVM, []ResourceType{}}, + ResourceType_KV_EVM_E2S: {ResourceType_KV_EVM, []ResourceType{}}, + ResourceType_KV_EVM_CODE_HASH: {ResourceType_KV_EVM, []ResourceType{}}, + ResourceType_KV_EVM_CODE: {ResourceType_KV_EVM, []ResourceType{}}, + ResourceType_KV_EVM_CODE_SIZE: {ResourceType_KV_EVM, []ResourceType{}}, } // This returns a slice of all resource types that are dependent to a specific resource type diff --git a/x/accesscontrol/keeper/keeper.go b/x/accesscontrol/keeper/keeper.go index 869e616b2..efbedb741 100644 --- a/x/accesscontrol/keeper/keeper.go +++ b/x/accesscontrol/keeper/keeper.go @@ -556,14 +556,14 @@ func (k Keeper) GenerateEstimatedWritesets(ctx sdk.Context, txDecoder sdk.TxDeco return writesets, nil } -func (k Keeper) BuildDependencyDag(ctx sdk.Context, txDecoder sdk.TxDecoder, anteDepGen sdk.AnteDepGenerator, txs [][]byte) (*types.Dag, error) { +func (k Keeper) BuildDependencyDag(ctx sdk.Context, anteDepGen sdk.AnteDepGenerator, txs []sdk.Tx) (*types.Dag, error) { defer MeasureBuildDagDuration(time.Now(), "BuildDependencyDag") // contains the latest msg index for a specific Access Operation dependencyDag := types.NewDag() - for txIndex, txBytes := range txs { - tx, err := txDecoder(txBytes) // TODO: results in repetitive decoding for txs with runtx decode (potential optimization) - if err != nil { - return nil, err + for txIndex, tx := range txs { + if tx == nil { + // this implies decoding error + return nil, sdkerrors.ErrTxDecode } // get the ante dependencies and add them to the dag anteDeps, err := anteDepGen([]acltypes.AccessOperation{}, tx, txIndex) diff --git a/x/accesscontrol/keeper/keeper_test.go b/x/accesscontrol/keeper/keeper_test.go index eaa659b2a..e077bdf6f 100644 --- a/x/accesscontrol/keeper/keeper_test.go +++ b/x/accesscontrol/keeper/keeper_test.go @@ -2000,13 +2000,11 @@ func TestBuildDependencyDag(t *testing.T) { txBuilder := simapp.MakeTestEncodingConfig().TxConfig.NewTxBuilder() err := txBuilder.SetMsgs(msgs...) require.NoError(t, err) - bz, err := simapp.MakeTestEncodingConfig().TxConfig.TxEncoder()(txBuilder.GetTx()) - require.NoError(t, err) - txs := [][]byte{ - bz, + txs := []sdk.Tx{ + txBuilder.GetTx(), } // ensure no errors creating dag - _, err = app.AccessControlKeeper.BuildDependencyDag(ctx, simapp.MakeTestEncodingConfig().TxConfig.TxDecoder(), app.GetAnteDepGenerator(), txs) + _, err = app.AccessControlKeeper.BuildDependencyDag(ctx, app.GetAnteDepGenerator(), txs) require.NoError(t, err) } @@ -2023,13 +2021,11 @@ func TestBuildDependencyDagWithGovMessage(t *testing.T) { txBuilder := simapp.MakeTestEncodingConfig().TxConfig.NewTxBuilder() err := txBuilder.SetMsgs(msgs...) require.NoError(t, err) - bz, err := simapp.MakeTestEncodingConfig().TxConfig.TxEncoder()(txBuilder.GetTx()) - require.NoError(t, err) - txs := [][]byte{ - bz, + txs := []sdk.Tx{ + txBuilder.GetTx(), } // ensure no errors creating dag - _, err = app.AccessControlKeeper.BuildDependencyDag(ctx, simapp.MakeTestEncodingConfig().TxConfig.TxDecoder(), app.GetAnteDepGenerator(), txs) + _, err = app.AccessControlKeeper.BuildDependencyDag(ctx, app.GetAnteDepGenerator(), txs) require.ErrorIs(t, err, types.ErrGovMsgInBlock) } @@ -2049,13 +2045,11 @@ func TestBuildDependencyDag_GovPropMessage(t *testing.T) { txBuilder := simapp.MakeTestEncodingConfig().TxConfig.NewTxBuilder() err := txBuilder.SetMsgs(msgs...) require.NoError(t, err) - bz, err := simapp.MakeTestEncodingConfig().TxConfig.TxEncoder()(txBuilder.GetTx()) - require.NoError(t, err) - txs := [][]byte{ - bz, + txs := []sdk.Tx{ + txBuilder.GetTx(), } // expect ErrGovMsgInBlock - _, err = app.AccessControlKeeper.BuildDependencyDag(ctx, simapp.MakeTestEncodingConfig().TxConfig.TxDecoder(), app.GetAnteDepGenerator(), txs) + _, err = app.AccessControlKeeper.BuildDependencyDag(ctx, app.GetAnteDepGenerator(), txs) require.EqualError(t, err, types.ErrGovMsgInBlock.Error()) } @@ -2073,13 +2067,11 @@ func TestBuildDependencyDag_GovDepositMessage(t *testing.T) { txBuilder := simapp.MakeTestEncodingConfig().TxConfig.NewTxBuilder() err := txBuilder.SetMsgs(msgs...) require.NoError(t, err) - bz, err := simapp.MakeTestEncodingConfig().TxConfig.TxEncoder()(txBuilder.GetTx()) - require.NoError(t, err) - txs := [][]byte{ - bz, + txs := []sdk.Tx{ + txBuilder.GetTx(), } // expect ErrGovMsgInBlock - _, err = app.AccessControlKeeper.BuildDependencyDag(ctx, simapp.MakeTestEncodingConfig().TxConfig.TxDecoder(), app.GetAnteDepGenerator(), txs) + _, err = app.AccessControlKeeper.BuildDependencyDag(ctx, app.GetAnteDepGenerator(), txs) require.EqualError(t, err, types.ErrGovMsgInBlock.Error()) } @@ -2100,49 +2092,28 @@ func TestBuildDependencyDag_MultipleTransactions(t *testing.T) { txBuilder := simapp.MakeTestEncodingConfig().TxConfig.NewTxBuilder() err := txBuilder.SetMsgs(msgs1...) require.NoError(t, err) - bz1, err := simapp.MakeTestEncodingConfig().TxConfig.TxEncoder()(txBuilder.GetTx()) - require.NoError(t, err) + tx1 := txBuilder.GetTx() err = txBuilder.SetMsgs(msgs2...) require.NoError(t, err) - bz2, err := simapp.MakeTestEncodingConfig().TxConfig.TxEncoder()(txBuilder.GetTx()) - require.NoError(t, err) + tx2 := txBuilder.GetTx() - txs := [][]byte{ - bz1, - bz2, + txs := []sdk.Tx{ + tx1, + tx2, } - _, err = app.AccessControlKeeper.BuildDependencyDag(ctx, simapp.MakeTestEncodingConfig().TxConfig.TxDecoder(), app.GetAnteDepGenerator(), txs) + _, err = app.AccessControlKeeper.BuildDependencyDag(ctx, app.GetAnteDepGenerator(), txs) require.NoError(t, err) mockAnteDepGenerator := func(_ []acltypes.AccessOperation, _ sdk.Tx, _ int) ([]acltypes.AccessOperation, error) { return nil, errors.New("Mocked error") } - _, err = app.AccessControlKeeper.BuildDependencyDag(ctx, simapp.MakeTestEncodingConfig().TxConfig.TxDecoder(), mockAnteDepGenerator, txs) + _, err = app.AccessControlKeeper.BuildDependencyDag(ctx, mockAnteDepGenerator, txs) require.ErrorContains(t, err, "Mocked error") } -func TestBuildDependencyDag_DecoderError(t *testing.T) { - // Set up a mocked app with a failing decoder - app := simapp.Setup(false) - ctx := app.BaseApp.NewContext(false, tmproto.Header{}) - - // Encode an invalid transaction - txs := [][]byte{ - []byte("invalid tx"), - } - - _, err := app.AccessControlKeeper.BuildDependencyDag( - ctx, - simapp.MakeTestEncodingConfig().TxConfig.TxDecoder(), - app.GetAnteDepGenerator(), - txs, - ) - require.Error(t, err) -} - -func BencharkAccessOpsBuildDependencyDag(b *testing.B) { +func BenchmarkAccessOpsBuildDependencyDag(b *testing.B) { app := simapp.Setup(false) ctx := app.BaseApp.NewContext(false, tmproto.Header{}) @@ -2158,30 +2129,30 @@ func BencharkAccessOpsBuildDependencyDag(b *testing.B) { txBuilder := simapp.MakeTestEncodingConfig().TxConfig.NewTxBuilder() _ = txBuilder.SetMsgs(msgs1...) - bz1, _ := simapp.MakeTestEncodingConfig().TxConfig.TxEncoder()(txBuilder.GetTx()) + tx1 := txBuilder.GetTx() _ = txBuilder.SetMsgs(msgs2...) - bz2, _ := simapp.MakeTestEncodingConfig().TxConfig.TxEncoder()(txBuilder.GetTx()) - - txs := [][]byte{ - bz1, - bz1, - bz1, - bz1, - bz1, - bz1, - bz2, - bz2, - bz2, - bz2, - bz2, - bz2, - bz2, - bz2, - bz2, - bz2, - bz2, - bz2, + tx2 := txBuilder.GetTx() + + txs := []sdk.Tx{ + tx1, + tx1, + tx1, + tx1, + tx1, + tx1, + tx2, + tx2, + tx2, + tx2, + tx2, + tx2, + tx2, + tx2, + tx2, + tx2, + tx2, + tx2, } mockAnteDepGenerator := func(_ []acltypes.AccessOperation, _ sdk.Tx, _ int) ([]acltypes.AccessOperation, error) { @@ -2237,7 +2208,7 @@ func BencharkAccessOpsBuildDependencyDag(b *testing.B) { for i := 0; i < b.N; i++ { _, _ = app.AccessControlKeeper.BuildDependencyDag( - ctx, simapp.MakeTestEncodingConfig().TxConfig.TxDecoder(), mockAnteDepGenerator, txs) + ctx, mockAnteDepGenerator, txs) } } @@ -2258,21 +2229,19 @@ func TestInvalidAccessOpsBuildDependencyDag(t *testing.T) { txBuilder := simapp.MakeTestEncodingConfig().TxConfig.NewTxBuilder() err := txBuilder.SetMsgs(msgs1...) require.NoError(t, err) - bz1, err := simapp.MakeTestEncodingConfig().TxConfig.TxEncoder()(txBuilder.GetTx()) - require.NoError(t, err) + tx1 := txBuilder.GetTx() err = txBuilder.SetMsgs(msgs2...) require.NoError(t, err) - bz2, err := simapp.MakeTestEncodingConfig().TxConfig.TxEncoder()(txBuilder.GetTx()) - require.NoError(t, err) + tx2 := txBuilder.GetTx() - txs := [][]byte{ - bz1, - bz2, - bz2, - bz2, - bz2, - bz2, + txs := []sdk.Tx{ + tx1, + tx2, + tx2, + tx2, + tx2, + tx2, } mockAnteDepGenerator := func(_ []acltypes.AccessOperation, _ sdk.Tx, _ int) ([]acltypes.AccessOperation, error) { @@ -2287,7 +2256,7 @@ func TestInvalidAccessOpsBuildDependencyDag(t *testing.T) { // ensure no errors creating dag _, err = app.AccessControlKeeper.BuildDependencyDag( - ctx, simapp.MakeTestEncodingConfig().TxConfig.TxDecoder(), mockAnteDepGenerator, txs) + ctx, mockAnteDepGenerator, txs) require.Error(t, err) mockAnteDepGenerator = func(_ []acltypes.AccessOperation, _ sdk.Tx, _ int) ([]acltypes.AccessOperation, error) { @@ -2303,7 +2272,7 @@ func TestInvalidAccessOpsBuildDependencyDag(t *testing.T) { // ensure no errors creating dag _, err = app.AccessControlKeeper.BuildDependencyDag( - ctx, simapp.MakeTestEncodingConfig().TxConfig.TxDecoder(), mockAnteDepGenerator, txs) + ctx, mockAnteDepGenerator, txs) require.NoError(t, err) } diff --git a/x/bank/keeper/send.go b/x/bank/keeper/send.go index 80fdb555b..a379fb969 100644 --- a/x/bank/keeper/send.go +++ b/x/bank/keeper/send.go @@ -16,6 +16,7 @@ type SendKeeper interface { InputOutputCoins(ctx sdk.Context, inputs []types.Input, outputs []types.Output) error SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error + SendCoinsWithoutAccCreation(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error GetParams(ctx sdk.Context) types.Params SetParams(ctx sdk.Context, params types.Params) @@ -131,13 +132,7 @@ func (k BaseSendKeeper) InputOutputCoins(ctx sdk.Context, inputs []types.Input, // SendCoins transfers amt coins from a sending account to a receiving account. // An error is returned upon failure. func (k BaseSendKeeper) SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error { - err := k.subUnlockedCoins(ctx, fromAddr, amt) - if err != nil { - return err - } - - err = k.addCoins(ctx, toAddr, amt) - if err != nil { + if err := k.SendCoinsWithoutAccCreation(ctx, fromAddr, toAddr, amt); err != nil { return err } @@ -151,6 +146,20 @@ func (k BaseSendKeeper) SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAd k.ak.SetAccount(ctx, k.ak.NewAccountWithAddress(ctx, toAddr)) } + return nil +} + +func (k BaseSendKeeper) SendCoinsWithoutAccCreation(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error { + err := k.subUnlockedCoins(ctx, fromAddr, amt) + if err != nil { + return err + } + + err = k.addCoins(ctx, toAddr, amt) + if err != nil { + return err + } + ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeTransfer, diff --git a/x/genutil/gentx.go b/x/genutil/gentx.go index 766b16cbf..9ef946f90 100644 --- a/x/genutil/gentx.go +++ b/x/genutil/gentx.go @@ -1,6 +1,7 @@ package genutil import ( + "crypto/sha256" "encoding/json" "fmt" @@ -87,7 +88,7 @@ func ValidateAccountInGenesis( return nil } -type deliverTxfn func(sdk.Context, abci.RequestDeliverTx) abci.ResponseDeliverTx +type deliverTxfn func(sdk.Context, abci.RequestDeliverTx, sdk.Tx, [32]byte) abci.ResponseDeliverTx // DeliverGenTxs iterates over all genesis txs, decodes each into a Tx and // invokes the provided deliverTxfn with the decoded Tx. It returns the result @@ -109,7 +110,7 @@ func DeliverGenTxs( panic(err) } - res := deliverTx(ctx, abci.RequestDeliverTx{Tx: bz}) + res := deliverTx(ctx, abci.RequestDeliverTx{Tx: bz}, tx, sha256.Sum256(bz)) if !res.IsOK() { panic(res.Log) } From 0a74f75ede454413a4715326c3d926a17db28d9d Mon Sep 17 00:00:00 2001 From: codchen Date: Sat, 16 Dec 2023 22:23:05 +0800 Subject: [PATCH 04/39] Integrate with pending txs in mempool (#381) Integrate with pending txs: - return `ResponseCheckTxV2` - add a new field `PendingTxChecker` field in Context integration with local sei --- baseapp/abci.go | 20 +++++++++++++------- baseapp/baseapp.go | 20 ++++++++++++++------ baseapp/test_helpers.go | 6 +++--- types/context.go | 42 +++++++++++++++++++++++++---------------- 4 files changed, 56 insertions(+), 32 deletions(-) diff --git a/baseapp/abci.go b/baseapp/abci.go index db69946f5..bb7d94fcb 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -203,7 +203,7 @@ func (app *BaseApp) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) (res abc // internal CheckTx state if the AnteHandler passes. Otherwise, the ResponseCheckTx // will contain releveant error information. Regardless of tx execution outcome, // the ResponseCheckTx will contain relevant gas execution context. -func (app *BaseApp) CheckTx(ctx context.Context, req *abci.RequestCheckTx) (*abci.ResponseCheckTx, error) { +func (app *BaseApp) CheckTx(ctx context.Context, req *abci.RequestCheckTx) (*abci.ResponseCheckTxV2, error) { defer telemetry.MeasureSince(time.Now(), "abci", "check_tx") var mode runTxMode @@ -223,19 +223,25 @@ func (app *BaseApp) CheckTx(ctx context.Context, req *abci.RequestCheckTx) (*abc tx, err := app.txDecoder(req.Tx) if err != nil { res := sdkerrors.ResponseCheckTx(err, 0, 0, app.trace) - return &res, err + return &abci.ResponseCheckTxV2{ResponseCheckTx: &res}, err } - gInfo, result, _, priority, err := app.runTx(sdkCtx, mode, tx, sha256.Sum256(req.Tx)) + gInfo, result, _, priority, pendingTxChecker, err := app.runTx(sdkCtx, mode, tx, sha256.Sum256(req.Tx)) if err != nil { res := sdkerrors.ResponseCheckTx(err, gInfo.GasWanted, gInfo.GasUsed, app.trace) - return &res, err + return &abci.ResponseCheckTxV2{ResponseCheckTx: &res}, err } - return &abci.ResponseCheckTx{ + res := &abci.ResponseCheckTxV2{ResponseCheckTx: &abci.ResponseCheckTx{ GasWanted: int64(gInfo.GasWanted), // TODO: Should type accept unsigned ints? Data: result.Data, Priority: priority, - }, nil + }} + if pendingTxChecker != nil { + res.IsPendingTransaction = true + res.Checker = pendingTxChecker + } + + return res, nil } // DeliverTxBatch executes multiple txs @@ -281,7 +287,7 @@ func (app *BaseApp) DeliverTx(ctx sdk.Context, req abci.RequestDeliverTx, tx sdk telemetry.SetGauge(float32(gInfo.GasWanted), "tx", "gas", "wanted") }() - gInfo, result, anteEvents, _, err := app.runTx(ctx.WithTxBytes(req.Tx).WithVoteInfos(app.voteInfos), runTxModeDeliver, tx, checksum) + gInfo, result, anteEvents, _, _, err := app.runTx(ctx.WithTxBytes(req.Tx).WithVoteInfos(app.voteInfos), runTxModeDeliver, tx, checksum) if err != nil { resultStr = "failed" // if we have a result, use those events instead of just the anteEvents diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index a330f6f19..c34761276 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -825,7 +825,14 @@ func (app *BaseApp) cacheTxContext(ctx sdk.Context, checksum [32]byte) (sdk.Cont // Note, gas execution info is always returned. A reference to a Result is // returned if the tx does not run out of gas and if all the messages are valid // and execute successfully. An error is returned otherwise. -func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [32]byte) (gInfo sdk.GasInfo, result *sdk.Result, anteEvents []abci.Event, priority int64, err error) { +func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [32]byte) ( + gInfo sdk.GasInfo, + result *sdk.Result, + anteEvents []abci.Event, + priority int64, + pendingTxChecker abci.PendingTxChecker, + err error, +) { defer telemetry.MeasureThroughputSinceWithLabels( telemetry.TxCount, []metrics.Label{ @@ -873,13 +880,13 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [ }() if tx == nil { - return sdk.GasInfo{}, nil, nil, 0, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "tx decode error") + return sdk.GasInfo{}, nil, nil, 0, nil, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "tx decode error") } msgs := tx.GetMsgs() if err := validateBasicTxMsgs(msgs); err != nil { - return sdk.GasInfo{}, nil, nil, 0, err + return sdk.GasInfo{}, nil, nil, 0, nil, err } if app.anteHandler != nil { @@ -924,7 +931,7 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [ // GasMeter expected to be set in AnteHandler gasWanted = ctx.GasMeter().Limit() if err != nil { - return gInfo, nil, nil, 0, err + return gInfo, nil, nil, 0, nil, err } // Dont need to validate in checkTx mode @@ -940,11 +947,12 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [ op.EmitValidationFailMetrics() } errMessage := fmt.Sprintf("Invalid Concurrent Execution antehandler missing %d access operations", len(missingAccessOps)) - return gInfo, nil, nil, 0, sdkerrors.Wrap(sdkerrors.ErrInvalidConcurrencyExecution, errMessage) + return gInfo, nil, nil, 0, nil, sdkerrors.Wrap(sdkerrors.ErrInvalidConcurrencyExecution, errMessage) } } priority = ctx.Priority() + pendingTxChecker = ctx.PendingTxChecker() msCache.Write() anteEvents = events.ToABCIEvents() if app.TracingEnabled { @@ -970,7 +978,7 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [ // append the events in the order of occurrence result.Events = append(anteEvents, result.Events...) } - return gInfo, result, anteEvents, priority, err + return gInfo, result, anteEvents, priority, pendingTxChecker, err } // runMsgs iterates through a list of messages and executes them with the provided diff --git a/baseapp/test_helpers.go b/baseapp/test_helpers.go index 3980c2f65..7652b078e 100644 --- a/baseapp/test_helpers.go +++ b/baseapp/test_helpers.go @@ -17,7 +17,7 @@ func (app *BaseApp) Check(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, *sdk return sdk.GasInfo{}, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "%s", err) } ctx := app.checkState.ctx.WithTxBytes(bz).WithVoteInfos(app.voteInfos).WithConsensusParams(app.GetConsensusParams(app.checkState.ctx)) - gasInfo, result, _, _, err := app.runTx(ctx, runTxModeCheck, tx, sha256.Sum256(bz)) + gasInfo, result, _, _, _, err := app.runTx(ctx, runTxModeCheck, tx, sha256.Sum256(bz)) if len(ctx.MultiStore().GetEvents()) > 0 { panic("Expected checkTx events to be empty") } @@ -31,7 +31,7 @@ func (app *BaseApp) Simulate(txBytes []byte) (sdk.GasInfo, *sdk.Result, error) { if err != nil { return sdk.GasInfo{}, nil, err } - gasInfo, result, _, _, err := app.runTx(ctx, runTxModeSimulate, tx, sha256.Sum256(txBytes)) + gasInfo, result, _, _, _, err := app.runTx(ctx, runTxModeSimulate, tx, sha256.Sum256(txBytes)) if len(ctx.MultiStore().GetEvents()) > 0 { panic("Expected simulate events to be empty") } @@ -49,7 +49,7 @@ func (app *BaseApp) Deliver(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, *s if err != nil { return sdk.GasInfo{}, &sdk.Result{}, err } - gasInfo, result, _, _, err := app.runTx(ctx, runTxModeDeliver, decoded, sha256.Sum256(bz)) + gasInfo, result, _, _, _, err := app.runTx(ctx, runTxModeDeliver, decoded, sha256.Sum256(bz)) return gasInfo, result, err } diff --git a/types/context.go b/types/context.go index 8ba51ef25..29731f88e 100644 --- a/types/context.go +++ b/types/context.go @@ -24,22 +24,23 @@ but please do not over-use it. We try to keep all data structured and standard additions here would be better just to add to the Context struct */ type Context struct { - ctx context.Context - ms MultiStore - header tmproto.Header - headerHash tmbytes.HexBytes - chainID string - txBytes []byte - logger log.Logger - voteInfo []abci.VoteInfo - gasMeter GasMeter - occEnabled bool - checkTx bool - recheckTx bool // if recheckTx == true, then checkTx must also be true - minGasPrice DecCoins - consParams *tmproto.ConsensusParams - eventManager *EventManager - priority int64 // The tx priority, only relevant in CheckTx + ctx context.Context + ms MultiStore + header tmproto.Header + headerHash tmbytes.HexBytes + chainID string + txBytes []byte + logger log.Logger + voteInfo []abci.VoteInfo + gasMeter GasMeter + occEnabled bool + checkTx bool + recheckTx bool // if recheckTx == true, then checkTx must also be true + minGasPrice DecCoins + consParams *tmproto.ConsensusParams + eventManager *EventManager + priority int64 // The tx priority, only relevant in CheckTx + pendingTxChecker abci.PendingTxChecker // Checker for pending transaction, only relevant in CheckTx txBlockingChannels acltypes.MessageAccessOpsChannelMapping txCompletionChannels acltypes.MessageAccessOpsChannelMapping @@ -116,6 +117,10 @@ func (c Context) Priority() int64 { return c.priority } +func (c Context) PendingTxChecker() abci.PendingTxChecker { + return c.pendingTxChecker +} + func (c Context) TxCompletionChannels() acltypes.MessageAccessOpsChannelMapping { return c.txCompletionChannels } @@ -349,6 +354,11 @@ func (c Context) WithTraceSpanContext(ctx context.Context) Context { return c } +func (c Context) WithPendingTxChecker(checker abci.PendingTxChecker) Context { + c.pendingTxChecker = checker + return c +} + // TODO: remove??? func (c Context) IsZero() bool { return c.ms == nil From e46f9a19593d5b8082b363cd80372186665edaa6 Mon Sep 17 00:00:00 2001 From: codchen Date: Wed, 20 Dec 2023 21:45:24 +0800 Subject: [PATCH 05/39] Add checkTx cb (#382) ## Describe your changes and provide context ## Testing performed to validate your change --- baseapp/baseapp.go | 15 ++++++++++++--- types/context.go | 10 ++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index c34761276..259b02f2b 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -157,8 +157,9 @@ type BaseApp struct { //nolint: maligned ChainID string - votesInfoLock sync.RWMutex - commitLock *sync.Mutex + votesInfoLock sync.RWMutex + commitLock *sync.Mutex + checkTxStateLock *sync.RWMutex compactionInterval uint64 @@ -274,7 +275,8 @@ func NewBaseApp( TracingInfo: &tracing.Info{ Tracer: &tr, }, - commitLock: &sync.Mutex{}, + commitLock: &sync.Mutex{}, + checkTxStateLock: &sync.RWMutex{}, } app.TracingInfo.SetContext(context.Background()) @@ -529,6 +531,8 @@ func (app *BaseApp) IsSealed() bool { return app.sealed } func (app *BaseApp) setCheckState(header tmproto.Header) { ms := app.cms.CacheMultiStore() ctx := sdk.NewContext(ms, header, true, app.logger).WithMinGasPrices(app.minGasPrices) + app.checkTxStateLock.Lock() + defer app.checkTxStateLock.Unlock() if app.checkState == nil { app.checkState = &state{ ms: ms, @@ -978,6 +982,9 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [ // append the events in the order of occurrence result.Events = append(anteEvents, result.Events...) } + if ctx.CheckTxCallback() != nil { + ctx.CheckTxCallback()(err) + } return gInfo, result, anteEvents, priority, pendingTxChecker, err } @@ -1168,5 +1175,7 @@ func (app *BaseApp) ReloadDB() error { } func (app *BaseApp) GetCheckCtx() sdk.Context { + app.checkTxStateLock.RLock() + defer app.checkTxStateLock.RUnlock() return app.checkState.ctx } diff --git a/types/context.go b/types/context.go index 29731f88e..2ee371e13 100644 --- a/types/context.go +++ b/types/context.go @@ -41,6 +41,7 @@ type Context struct { eventManager *EventManager priority int64 // The tx priority, only relevant in CheckTx pendingTxChecker abci.PendingTxChecker // Checker for pending transaction, only relevant in CheckTx + checkTxCallback func(error) // callback to make at the end of CheckTx. Input param is the error (nil-able) of `runMsgs` txBlockingChannels acltypes.MessageAccessOpsChannelMapping txCompletionChannels acltypes.MessageAccessOpsChannelMapping @@ -121,6 +122,10 @@ func (c Context) PendingTxChecker() abci.PendingTxChecker { return c.pendingTxChecker } +func (c Context) CheckTxCallback() func(error) { + return c.checkTxCallback +} + func (c Context) TxCompletionChannels() acltypes.MessageAccessOpsChannelMapping { return c.txCompletionChannels } @@ -359,6 +364,11 @@ func (c Context) WithPendingTxChecker(checker abci.PendingTxChecker) Context { return c } +func (c Context) WithCheckTxCallback(checkTxCallback func(error)) Context { + c.checkTxCallback = checkTxCallback + return c +} + // TODO: remove??? func (c Context) IsZero() bool { return c.ms == nil From 9401eb9a98aa58ec431f87f3ecdf5d92515a1a4b Mon Sep 17 00:00:00 2001 From: codchen Date: Thu, 28 Dec 2023 15:43:12 +0800 Subject: [PATCH 06/39] Add wei support in bank keeper (#386) ## Describe your changes and provide context Add two new bank keeper functions that allow sub-usei (i.e. wei) sending, where 1 usei = 10^12 wei: ``` SendCoinsAndWei(ctx sdk.Context, from sdk.AccAddress, to sdk.AccAddress, customEscrow sdk.AccAddress, denom string, amt sdk.Int, wei sdk.Int) error GetWeiBalance(ctx sdk.Context, addr sdk.AccAddress) sdk.Int ``` Any usei that is split as a result of wei sending will be stored in an escrow account, which can either be one that's specified by the caller or a default global escrow module account. ## Testing performed to validate your change unit test & local integration with sei-chain --- x/bank/keeper/keeper_test.go | 50 +++++++++++++++++++++++ x/bank/keeper/send.go | 77 ++++++++++++++++++++++++++++++++++++ x/bank/keeper/view.go | 15 +++++++ x/bank/types/key.go | 3 ++ 4 files changed, 145 insertions(+) diff --git a/x/bank/keeper/keeper_test.go b/x/bank/keeper/keeper_test.go index e2eec160a..25600f3f7 100644 --- a/x/bank/keeper/keeper_test.go +++ b/x/bank/keeper/keeper_test.go @@ -76,6 +76,7 @@ func (suite *IntegrationTestSuite) initKeepersWithmAccPerms(blockedAddrs map[str appCodec := simapp.MakeTestEncodingConfig().Marshaler maccPerms[holder] = nil + maccPerms[types.WeiEscrowName] = nil maccPerms[authtypes.Burner] = []string{authtypes.Burner} maccPerms[authtypes.Minter] = []string{authtypes.Minter} maccPerms[multiPerm] = []string{authtypes.Burner, authtypes.Minter, authtypes.Staking} @@ -108,6 +109,55 @@ func (suite *IntegrationTestSuite) SetupTest() { suite.queryClient = queryClient } +func (suite *IntegrationTestSuite) TestSendCoinsAndWei() { + ctx := suite.ctx + require := suite.Require() + authKeeper, keeper := suite.initKeepersWithmAccPerms(make(map[string]bool)) + amt := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))) + require.NoError(keeper.MintCoins(ctx, authtypes.Minter, amt)) + addr1 := sdk.AccAddress([]byte("addr1_______________")) + addr2 := sdk.AccAddress([]byte("addr2_______________")) + addr3 := sdk.AccAddress([]byte("addr3_______________")) + require.NoError(keeper.SendCoinsFromModuleToAccount(ctx, authtypes.Minter, addr1, amt)) + // should no-op if sending zero + require.NoError(keeper.SendCoinsAndWei(ctx, addr1, addr2, nil, sdk.DefaultBondDenom, sdk.ZeroInt(), sdk.ZeroInt())) + require.Equal(sdk.ZeroInt(), keeper.GetWeiBalance(ctx, addr1)) + require.Equal(sdk.ZeroInt(), keeper.GetWeiBalance(ctx, addr2)) + require.Equal(sdk.NewInt(100), keeper.GetBalance(ctx, addr1, sdk.DefaultBondDenom).Amount) + require.Equal(sdk.ZeroInt(), keeper.GetBalance(ctx, addr2, sdk.DefaultBondDenom).Amount) + require.Equal(sdk.ZeroInt(), keeper.GetBalance(ctx, authKeeper.GetModuleAddress(types.WeiEscrowName), sdk.DefaultBondDenom).Amount) + // should just do usei send if wei is zero + require.NoError(keeper.SendCoinsAndWei(ctx, addr1, addr3, nil, sdk.DefaultBondDenom, sdk.NewInt(50), sdk.ZeroInt())) + require.Equal(sdk.ZeroInt(), keeper.GetWeiBalance(ctx, addr1)) + require.Equal(sdk.ZeroInt(), keeper.GetWeiBalance(ctx, addr3)) + require.Equal(sdk.NewInt(50), keeper.GetBalance(ctx, addr1, sdk.DefaultBondDenom).Amount) + require.Equal(sdk.NewInt(50), keeper.GetBalance(ctx, addr3, sdk.DefaultBondDenom).Amount) + require.Equal(sdk.ZeroInt(), keeper.GetBalance(ctx, authKeeper.GetModuleAddress(types.WeiEscrowName), sdk.DefaultBondDenom).Amount) + // should return error if wei amount overflows + require.Error(keeper.SendCoinsAndWei(ctx, addr1, addr2, nil, sdk.DefaultBondDenom, sdk.ZeroInt(), sdk.NewInt(1_000_000_000_000))) + // sender gets escrowed one usei, recipient does not get redeemed + require.NoError(keeper.SendCoinsAndWei(ctx, addr1, addr2, nil, sdk.DefaultBondDenom, sdk.NewInt(1), sdk.NewInt(1))) + require.Equal(sdk.NewInt(999_999_999_999), keeper.GetWeiBalance(ctx, addr1)) + require.Equal(sdk.OneInt(), keeper.GetWeiBalance(ctx, addr2)) + require.Equal(sdk.NewInt(48), keeper.GetBalance(ctx, addr1, sdk.DefaultBondDenom).Amount) + require.Equal(sdk.OneInt(), keeper.GetBalance(ctx, addr2, sdk.DefaultBondDenom).Amount) + require.Equal(sdk.OneInt(), keeper.GetBalance(ctx, authKeeper.GetModuleAddress(types.WeiEscrowName), sdk.DefaultBondDenom).Amount) + // sender does not get escrowed due to sufficient wei balance, recipient does not get redeemed + require.NoError(keeper.SendCoinsAndWei(ctx, addr1, addr3, nil, sdk.DefaultBondDenom, sdk.NewInt(1), sdk.NewInt(999_999_999_999))) + require.Equal(sdk.ZeroInt(), keeper.GetWeiBalance(ctx, addr1)) + require.Equal(sdk.NewInt(999_999_999_999), keeper.GetWeiBalance(ctx, addr3)) + require.Equal(sdk.NewInt(47), keeper.GetBalance(ctx, addr1, sdk.DefaultBondDenom).Amount) + require.Equal(sdk.NewInt(51), keeper.GetBalance(ctx, addr3, sdk.DefaultBondDenom).Amount) + require.Equal(sdk.OneInt(), keeper.GetBalance(ctx, authKeeper.GetModuleAddress(types.WeiEscrowName), sdk.DefaultBondDenom).Amount) + // sender gets escrowed and recipient gets redeemed + require.NoError(keeper.SendCoinsAndWei(ctx, addr1, addr3, nil, sdk.DefaultBondDenom, sdk.NewInt(1), sdk.NewInt(2))) + require.Equal(sdk.NewInt(999_999_999_998), keeper.GetWeiBalance(ctx, addr1)) + require.Equal(sdk.NewInt(1), keeper.GetWeiBalance(ctx, addr3)) + require.Equal(sdk.NewInt(45), keeper.GetBalance(ctx, addr1, sdk.DefaultBondDenom).Amount) + require.Equal(sdk.NewInt(53), keeper.GetBalance(ctx, addr3, sdk.DefaultBondDenom).Amount) + require.Equal(sdk.OneInt(), keeper.GetBalance(ctx, authKeeper.GetModuleAddress(types.WeiEscrowName), sdk.DefaultBondDenom).Amount) +} + func (suite *IntegrationTestSuite) TestSupply() { ctx := suite.ctx diff --git a/x/bank/keeper/send.go b/x/bank/keeper/send.go index a379fb969..93ac398dd 100644 --- a/x/bank/keeper/send.go +++ b/x/bank/keeper/send.go @@ -1,7 +1,10 @@ package keeper import ( + "errors" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/store/prefix" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -17,6 +20,7 @@ type SendKeeper interface { InputOutputCoins(ctx sdk.Context, inputs []types.Input, outputs []types.Output) error SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error SendCoinsWithoutAccCreation(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error + SendCoinsAndWei(ctx sdk.Context, from sdk.AccAddress, to sdk.AccAddress, customEscrow sdk.AccAddress, denom string, amt sdk.Int, wei sdk.Int) error GetParams(ctx sdk.Context) types.Params SetParams(ctx sdk.Context, params types.Params) @@ -28,6 +32,7 @@ type SendKeeper interface { } var _ SendKeeper = (*BaseSendKeeper)(nil) +var MaxWeiBalance sdk.Int = sdk.NewInt(1_000_000_000_000) // BaseSendKeeper only allows transfers between accounts without the possibility of // creating coins. It implements the SendKeeper interface. @@ -275,6 +280,20 @@ func (k BaseSendKeeper) setBalance(ctx sdk.Context, addr sdk.AccAddress, balance return nil } +func (k BaseSendKeeper) setWeiBalance(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Int) error { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.WeiBalancesPrefix) + if amt.IsZero() { + store.Delete(addr) + return nil + } + val, err := amt.Marshal() + if err != nil { + return err + } + store.Set(addr, val) + return nil +} + // IsSendEnabledCoins checks the coins provide and returns an ErrSendDisabled if // any of the coins are not configured for sending. Returns nil if sending is enabled // for all provided coin @@ -297,3 +316,61 @@ func (k BaseSendKeeper) IsSendEnabledCoin(ctx sdk.Context, coin sdk.Coin) bool { func (k BaseSendKeeper) BlockedAddr(addr sdk.AccAddress) bool { return k.blockedAddrs[addr.String()] } + +func (k BaseSendKeeper) SendCoinsAndWei(ctx sdk.Context, from sdk.AccAddress, to sdk.AccAddress, customEscrow sdk.AccAddress, denom string, amt sdk.Int, wei sdk.Int) error { + if wei.Equal(sdk.ZeroInt()) { + if amt.Equal(sdk.ZeroInt()) { + return nil + } + return k.SendCoinsWithoutAccCreation(ctx, from, to, sdk.NewCoins(sdk.NewCoin(denom, amt))) + } + if wei.GTE(MaxWeiBalance) { + return errors.New("cannot send more than 10^12 wei") + } + escrow := customEscrow + if escrow == nil { + escrow = k.ak.GetModuleAddress(types.WeiEscrowName) + } + currentWeiBalanceFrom := k.GetWeiBalance(ctx, from) + postWeiBalanceFrom := currentWeiBalanceFrom.Sub(wei) + if postWeiBalanceFrom.GTE(sdk.ZeroInt()) { + if err := k.setWeiBalance(ctx, from, postWeiBalanceFrom); err != nil { + return err + } + } else { + if err := k.setWeiBalance(ctx, from, MaxWeiBalance.Add(postWeiBalanceFrom)); err != nil { + // postWeiBalanceFrom is negative + return err + } + // need to send one sei to escrow because wei balance is insufficient + if err := k.SendCoinsWithoutAccCreation(ctx, from, escrow, sdk.NewCoins(sdk.NewCoin(denom, sdk.OneInt()))); err != nil { + return err + } + } + currentWeiBalanceTo := k.GetWeiBalance(ctx, to) + postWeiBalanceTo := currentWeiBalanceTo.Add(wei) + if postWeiBalanceTo.LT(MaxWeiBalance) { + if err := k.setWeiBalance(ctx, to, postWeiBalanceTo); err != nil { + return err + } + } else { + if err := k.setWeiBalance(ctx, to, postWeiBalanceTo.Sub(MaxWeiBalance)); err != nil { + return err + } + // need to redeem one sei from escrow because wei balance overflowed + one := sdk.NewCoins(sdk.NewCoin(denom, sdk.OneInt())) + if err := k.SendCoinsWithoutAccCreation(ctx, escrow, to, one); err != nil { + if sdkerrors.ErrInsufficientFunds.Is(err) && customEscrow != nil { + // custom escrow does not have enough balance to redeem. Try the global escrow instead + if err := k.SendCoinsWithoutAccCreation(ctx, k.ak.GetModuleAddress(types.WeiEscrowName), to, one); err != nil { + return err + } + } + return err + } + } + if amt.GT(sdk.ZeroInt()) { + return k.SendCoinsWithoutAccCreation(ctx, from, to, sdk.NewCoins(sdk.NewCoin(denom, amt))) + } + return nil +} diff --git a/x/bank/keeper/view.go b/x/bank/keeper/view.go index d126ddd75..7f835ab2b 100644 --- a/x/bank/keeper/view.go +++ b/x/bank/keeper/view.go @@ -26,6 +26,7 @@ type ViewKeeper interface { GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin LockedCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins + GetWeiBalance(ctx sdk.Context, addr sdk.AccAddress) sdk.Int IterateAccountBalances(ctx sdk.Context, addr sdk.AccAddress, cb func(coin sdk.Coin) (stop bool)) IterateAllBalances(ctx sdk.Context, cb func(address sdk.AccAddress, coin sdk.Coin) (stop bool)) @@ -232,3 +233,17 @@ func (k BaseViewKeeper) getAccountStore(ctx sdk.Context, addr sdk.AccAddress) pr return prefix.NewStore(store, types.CreateAccountBalancesPrefix(addr)) } + +func (k BaseViewKeeper) GetWeiBalance(ctx sdk.Context, addr sdk.AccAddress) sdk.Int { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.WeiBalancesPrefix) + val := store.Get(addr) + if val == nil { + return sdk.ZeroInt() + } + res := new(sdk.Int) + if err := res.Unmarshal(val); err != nil { + // should never happen + panic(err) + } + return *res +} diff --git a/x/bank/types/key.go b/x/bank/types/key.go index 8b8c25a2d..146b30de1 100644 --- a/x/bank/types/key.go +++ b/x/bank/types/key.go @@ -21,10 +21,13 @@ const ( // QuerierRoute defines the module's query routing key QuerierRoute = ModuleName + + WeiEscrowName = "weiescrow" ) // KVStore keys var ( + WeiBalancesPrefix = []byte{0x04} // BalancesPrefix is the prefix for the account balances store. We use a byte // (instead of `[]byte("balances")` to save some disk space). DeferredCachePrefix = []byte{0x03} From a93cbc04a417cb7da23ac37babfce4be3e4681c5 Mon Sep 17 00:00:00 2001 From: codchen Date: Thu, 28 Dec 2023 16:16:12 +0800 Subject: [PATCH 07/39] Add ACL constants for Bank Wei prefix (#387) --- proto/cosmos/accesscontrol/constants.proto | 6 +- types/accesscontrol/constants.pb.go | 216 +++++++++++---------- types/accesscontrol/resource.go | 2 + x/accesscontrol/testutil/accesscontrol.go | 9 +- 4 files changed, 121 insertions(+), 112 deletions(-) diff --git a/proto/cosmos/accesscontrol/constants.proto b/proto/cosmos/accesscontrol/constants.proto index 01ed4f299..7df3e7d06 100644 --- a/proto/cosmos/accesscontrol/constants.proto +++ b/proto/cosmos/accesscontrol/constants.proto @@ -146,8 +146,10 @@ enum ResourceType { KV_EVM_CODE = 106; // child of KV_EVM KV_EVM_CODE_SIZE = 107; // child of KV_EVM - KV_DEX_MEM_CONTRACTS_TO_PROCESS = 108; // child of KV_DEX_MEM - KV_DEX_MEM_DOWNSTREAM_CONTRACTS = 109; // child of KV_DEX_MEM + KV_BANK_WEI_BALANCE = 108; // child of KV_BANK + + KV_DEX_MEM_CONTRACTS_TO_PROCESS = 109; // child of KV_DEX_MEM + KV_DEX_MEM_DOWNSTREAM_CONTRACTS = 110; // child of KV_DEX_MEM } enum WasmMessageSubtype { diff --git a/types/accesscontrol/constants.pb.go b/types/accesscontrol/constants.pb.go index 939ad80de..799d51d50 100644 --- a/types/accesscontrol/constants.pb.go +++ b/types/accesscontrol/constants.pb.go @@ -207,8 +207,9 @@ const ( ResourceType_KV_EVM_CODE_HASH ResourceType = 105 ResourceType_KV_EVM_CODE ResourceType = 106 ResourceType_KV_EVM_CODE_SIZE ResourceType = 107 - ResourceType_KV_DEX_MEM_CONTRACTS_TO_PROCESS ResourceType = 108 - ResourceType_KV_DEX_MEM_DOWNSTREAM_CONTRACTS ResourceType = 109 + ResourceType_KV_BANK_WEI_BALANCE ResourceType = 108 + ResourceType_KV_DEX_MEM_CONTRACTS_TO_PROCESS ResourceType = 109 + ResourceType_KV_DEX_MEM_DOWNSTREAM_CONTRACTS ResourceType = 110 ) var ResourceType_name = map[int32]string{ @@ -316,8 +317,9 @@ var ResourceType_name = map[int32]string{ 105: "KV_EVM_CODE_HASH", 106: "KV_EVM_CODE", 107: "KV_EVM_CODE_SIZE", - 108: "KV_DEX_MEM_CONTRACTS_TO_PROCESS", - 109: "KV_DEX_MEM_DOWNSTREAM_CONTRACTS", + 108: "KV_BANK_WEI_BALANCE", + 109: "KV_DEX_MEM_CONTRACTS_TO_PROCESS", + 110: "KV_DEX_MEM_DOWNSTREAM_CONTRACTS", } var ResourceType_value = map[string]int32{ @@ -425,8 +427,9 @@ var ResourceType_value = map[string]int32{ "KV_EVM_CODE_HASH": 105, "KV_EVM_CODE": 106, "KV_EVM_CODE_SIZE": 107, - "KV_DEX_MEM_CONTRACTS_TO_PROCESS": 108, - "KV_DEX_MEM_DOWNSTREAM_CONTRACTS": 109, + "KV_BANK_WEI_BALANCE": 108, + "KV_DEX_MEM_CONTRACTS_TO_PROCESS": 109, + "KV_DEX_MEM_DOWNSTREAM_CONTRACTS": 110, } func (x ResourceType) String() string { @@ -474,104 +477,105 @@ func init() { } var fileDescriptor_36568f7561081112 = []byte{ - // 1577 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x57, 0xd9, 0x7a, 0x1b, 0xb7, - 0x15, 0xb6, 0x6c, 0x59, 0x0b, 0xbc, 0x1d, 0xc3, 0xfb, 0x46, 0x3b, 0xb2, 0x1b, 0xbb, 0x8a, 0x23, - 0xc5, 0x76, 0xd7, 0xa4, 0x6d, 0x0a, 0x0e, 0x8e, 0xc8, 0x11, 0x67, 0x80, 0x11, 0x80, 0xe1, 0xe2, - 0xb6, 0x41, 0x25, 0x86, 0x75, 0xdc, 0x58, 0xa6, 0x3f, 0x91, 0xee, 0xd7, 0x3e, 0x43, 0x6f, 0xfa, - 0x10, 0x7d, 0x98, 0x5e, 0xe6, 0xb2, 0x97, 0xfd, 0xec, 0x17, 0xe9, 0x87, 0x99, 0x43, 0x7a, 0x38, - 0xb1, 0x93, 0x2b, 0x89, 0xe7, 0xff, 0x71, 0x00, 0xfc, 0x67, 0xc3, 0xb0, 0x7b, 0xc3, 0xf1, 0xe4, - 0x70, 0x3c, 0xd9, 0xde, 0x1f, 0x0e, 0x47, 0x93, 0xc9, 0x70, 0xfc, 0x72, 0x7a, 0x34, 0x7e, 0xb1, - 0x3d, 0x1c, 0xbf, 0x9c, 0x4c, 0xf7, 0x5f, 0x4e, 0x27, 0x5b, 0xaf, 0x8e, 0xc6, 0xd3, 0x31, 0xbf, - 0x59, 0xb2, 0xb6, 0x16, 0x58, 0x5b, 0x7f, 0x7b, 0x74, 0x30, 0x9a, 0xee, 0x3f, 0xda, 0xfc, 0x9c, - 0x31, 0x51, 0x00, 0xee, 0x1f, 0xaf, 0x46, 0xfc, 0x14, 0x5b, 0xcd, 0x55, 0x47, 0xe9, 0x9e, 0x82, - 0x63, 0x7c, 0x8d, 0x2d, 0x1b, 0x14, 0x12, 0x96, 0xf8, 0x3a, 0x3b, 0xd9, 0x33, 0xb1, 0x43, 0x38, - 0xce, 0x19, 0x5b, 0x89, 0x74, 0x9a, 0xc6, 0x0e, 0x4e, 0x6c, 0xfe, 0xf3, 0x38, 0xbb, 0x51, 0x2e, - 0xd6, 0xaf, 0x46, 0x47, 0xfb, 0xd3, 0xe7, 0xe3, 0x97, 0x76, 0xf4, 0x62, 0x34, 0x9c, 0x8e, 0x8f, - 0x0a, 0x6f, 0x6b, 0x6c, 0x59, 0x69, 0x85, 0x70, 0x8c, 0xaf, 0xb0, 0xe3, 0xbb, 0x7b, 0xb0, 0xc4, - 0x2f, 0xb1, 0xf3, 0xbb, 0x7b, 0xbe, 0x89, 0x51, 0xfb, 0xc9, 0x63, 0x2f, 0xa4, 0x34, 0x68, 0x2d, - 0x1c, 0xe7, 0x0d, 0x76, 0x7d, 0x77, 0xcf, 0x27, 0xa8, 0x5a, 0xae, 0xed, 0x33, 0x83, 0x3b, 0x71, - 0x1f, 0xe5, 0x1c, 0x3f, 0xc1, 0xaf, 0xb1, 0x4b, 0x16, 0x95, 0x44, 0x53, 0x5f, 0xba, 0xcc, 0x37, - 0x58, 0x83, 0xa0, 0x0f, 0x2d, 0x3f, 0xc9, 0x2f, 0x32, 0x88, 0xb4, 0x72, 0x46, 0x44, 0x6e, 0x6e, - 0x5d, 0xe1, 0xd7, 0xd9, 0xe5, 0xdd, 0x3d, 0x9f, 0xa2, 0xb5, 0xa2, 0x85, 0x3e, 0xd2, 0x4a, 0xc6, - 0x2e, 0xd6, 0x4a, 0x24, 0xb0, 0x1a, 0xb0, 0x48, 0x2b, 0xeb, 0x84, 0x72, 0xde, 0x3a, 0x13, 0xab, - 0x96, 0x77, 0xda, 0xb7, 0xb1, 0x0f, 0x6b, 0xfc, 0x32, 0xe3, 0x73, 0x6f, 0x06, 0x77, 0xd0, 0xa0, - 0x8a, 0x10, 0xd6, 0x37, 0xff, 0x7d, 0x99, 0x9d, 0x36, 0xa3, 0xc9, 0xf8, 0xf5, 0xd1, 0x70, 0x54, - 0x5c, 0x7f, 0x95, 0x9d, 0x10, 0x6a, 0x50, 0xde, 0xbe, 0xd3, 0x85, 0xa5, 0x60, 0x48, 0x47, 0x87, - 0xa5, 0x88, 0x72, 0xf4, 0xf7, 0xf0, 0xff, 0x89, 0x20, 0x79, 0xa7, 0xeb, 0x9b, 0x42, 0x75, 0x60, - 0x99, 0x9f, 0x65, 0xac, 0xd3, 0xf5, 0xd6, 0x89, 0x4e, 0xac, 0x5a, 0x70, 0x92, 0xc0, 0x9e, 0xb0, - 0x29, 0xac, 0xf0, 0x33, 0x6c, 0xbd, 0xd3, 0xf5, 0xda, 0x88, 0x28, 0x41, 0x58, 0x0d, 0x4e, 0x3a, - 0x5d, 0x2f, 0x8b, 0x33, 0x9d, 0x66, 0x6b, 0x9d, 0xae, 0xc7, 0x4c, 0x47, 0x6d, 0x58, 0xe7, 0x17, - 0xd8, 0xb9, 0x4e, 0xd7, 0x3b, 0xdd, 0x41, 0xb5, 0x23, 0x22, 0xa7, 0xcd, 0x00, 0x58, 0xb8, 0xd2, - 0x7c, 0xb5, 0xef, 0x6a, 0x87, 0xde, 0x09, 0xd3, 0x42, 0x67, 0xe1, 0x14, 0xbf, 0xc5, 0xae, 0xbd, - 0xc3, 0x44, 0xab, 0x65, 0xb0, 0x25, 0x5c, 0xc9, 0xb2, 0x70, 0x3a, 0x44, 0xed, 0x1d, 0xbc, 0x83, - 0x28, 0xd1, 0x58, 0x38, 0x13, 0xa2, 0xf2, 0xee, 0xb0, 0x5e, 0x62, 0x12, 0x56, 0xc5, 0x5a, 0xc1, - 0x59, 0x7e, 0x95, 0x5d, 0xac, 0x40, 0x5d, 0x91, 0xc4, 0x52, 0x38, 0x6d, 0xe0, 0x1c, 0xdd, 0x48, - 0xe4, 0xae, 0x0d, 0x40, 0x1e, 0xc2, 0x8f, 0x59, 0x5c, 0xbc, 0x75, 0xda, 0x20, 0x9c, 0xe7, 0x9c, - 0x9d, 0x25, 0x59, 0xbc, 0xcd, 0xb3, 0x2c, 0x19, 0x00, 0xe7, 0xe7, 0xd9, 0x99, 0x99, 0x4d, 0xa2, - 0xd2, 0x29, 0x5c, 0x08, 0xa1, 0x9d, 0x99, 0x9a, 0x22, 0x11, 0x2a, 0x42, 0x0b, 0x17, 0xc9, 0x6f, - 0x55, 0x00, 0x5a, 0x70, 0x89, 0xdf, 0x64, 0x57, 0xeb, 0x50, 0x8a, 0x4e, 0x48, 0xe1, 0x04, 0x5c, - 0x7e, 0xdf, 0x42, 0x21, 0xd3, 0x58, 0xc1, 0x15, 0x7e, 0x83, 0x5d, 0xa9, 0x43, 0x91, 0xc1, 0xe2, - 0x56, 0x57, 0x09, 0x24, 0x85, 0xb0, 0x1f, 0xb5, 0x85, 0x6a, 0xa1, 0x37, 0xc2, 0x21, 0x5c, 0x0b, - 0x29, 0x5a, 0x53, 0x3e, 0x43, 0x25, 0x12, 0x37, 0xf0, 0x91, 0xce, 0x95, 0x43, 0x03, 0xd7, 0xe9, - 0x58, 0xc4, 0xc9, 0x4c, 0x1c, 0xa1, 0xb7, 0x4a, 0x64, 0xb6, 0xad, 0x1d, 0xdc, 0xe0, 0xb7, 0xd9, - 0x8d, 0xef, 0xcb, 0x19, 0x6b, 0xe5, 0x33, 0xdd, 0x43, 0x03, 0x37, 0x29, 0xb8, 0x33, 0x82, 0xd3, - 0x4e, 0x24, 0x84, 0xdd, 0xa2, 0xed, 0xbf, 0x17, 0x0b, 0x1b, 0x52, 0xbe, 0x90, 0x1d, 0x1a, 0xfc, - 0x2e, 0xbb, 0x5d, 0xe1, 0xe4, 0xaa, 0x19, 0xaa, 0x61, 0x31, 0xa8, 0xb7, 0xf9, 0x7d, 0x76, 0xf7, - 0x47, 0x48, 0xc1, 0x3b, 0xdc, 0x21, 0x35, 0x66, 0x44, 0x83, 0x15, 0x2f, 0x1f, 0xd5, 0xb6, 0xaa, - 0x82, 0x61, 0xb5, 0xb7, 0x26, 0x82, 0x8d, 0x1f, 0x23, 0x49, 0xeb, 0xe0, 0x2e, 0xff, 0x88, 0xdd, - 0xfa, 0x10, 0x69, 0x2f, 0xc7, 0x1c, 0xe1, 0x5e, 0x68, 0x2c, 0xef, 0xbb, 0x3b, 0xe1, 0x3f, 0xa9, - 0xe1, 0xed, 0x38, 0x64, 0x5f, 0x1c, 0x89, 0xc4, 0xc7, 0x6a, 0x47, 0xc3, 0xc7, 0xb5, 0x3c, 0x9e, - 0x5f, 0x19, 0xee, 0x7f, 0x58, 0xd5, 0xe6, 0x80, 0x94, 0xff, 0x29, 0xd5, 0xa1, 0x8c, 0x43, 0x07, - 0x69, 0xe6, 0xc5, 0xfd, 0x1f, 0x50, 0xa4, 0xab, 0xc6, 0x50, 0x52, 0x3e, 0xd3, 0x3a, 0x81, 0x4d, - 0x7e, 0x87, 0xdd, 0xac, 0xa3, 0x99, 0xd1, 0x99, 0xb6, 0x68, 0x7c, 0x07, 0x07, 0xf0, 0x09, 0x45, - 0x61, 0x81, 0xa1, 0x73, 0x17, 0x5a, 0x95, 0x2c, 0x65, 0xe8, 0x09, 0x23, 0x2d, 0x3c, 0xe4, 0x9f, - 0xb0, 0xfb, 0x75, 0x22, 0x29, 0xa4, 0x8d, 0xef, 0xc5, 0xae, 0x2d, 0x8d, 0xe8, 0x95, 0x09, 0xf0, - 0xe9, 0x0f, 0x93, 0xad, 0x13, 0xc6, 0x05, 0xe7, 0x85, 0x2a, 0x5b, 0x7c, 0x93, 0x7d, 0x5c, 0x27, - 0x87, 0xa8, 0x54, 0xe4, 0x9b, 0x9d, 0x62, 0xfb, 0x7d, 0xc7, 0x0d, 0xdc, 0x28, 0x37, 0x06, 0x95, - 0x9b, 0x13, 0x3f, 0xe3, 0x0f, 0xd8, 0xbd, 0xf7, 0x11, 0x45, 0x14, 0xe5, 0xa9, 0x2f, 0x46, 0x8e, - 0xb5, 0x41, 0xc1, 0x47, 0x54, 0x0d, 0x0b, 0x4c, 0x9b, 0x08, 0xdb, 0xf6, 0xd8, 0x45, 0xe5, 0xe0, - 0xf1, 0x4c, 0x62, 0xec, 0xfb, 0x79, 0xa3, 0x4e, 0xb4, 0x6a, 0x35, 0xb5, 0xee, 0xc0, 0x13, 0x6a, - 0x76, 0x0b, 0xa8, 0x6d, 0x6b, 0xe3, 0x0a, 0xf8, 0x67, 0xd4, 0xec, 0x02, 0x6c, 0xd1, 0xb9, 0x04, - 0xd3, 0xe0, 0xf3, 0xe7, 0xa1, 0xeb, 0x93, 0x39, 0x13, 0xb1, 0xa1, 0x29, 0x03, 0xbf, 0xe0, 0xe7, - 0xd8, 0x29, 0xb2, 0xbb, 0x9e, 0xc8, 0xe0, 0x97, 0x1c, 0xd8, 0xe9, 0x19, 0x31, 0x94, 0x31, 0xfc, - 0x8a, 0xca, 0x61, 0xd1, 0xa3, 0x47, 0xe5, 0xcc, 0x00, 0x7e, 0x4d, 0x95, 0x1b, 0x40, 0x83, 0xad, - 0xd8, 0x3a, 0x34, 0x28, 0x8b, 0x2d, 0xe0, 0xf3, 0x8a, 0x2b, 0x6d, 0x24, 0x1a, 0xf8, 0x0d, 0x75, - 0xc0, 0xe2, 0xec, 0xa1, 0xd7, 0x25, 0xf0, 0xdb, 0x59, 0xc6, 0x60, 0x3f, 0x48, 0x15, 0xfa, 0x89, - 0x17, 0x91, 0x8b, 0xbb, 0x58, 0xae, 0xb1, 0xf0, 0xbb, 0xca, 0x8d, 0x84, 0xb5, 0xe8, 0x7c, 0x12, - 0x5b, 0x07, 0xbf, 0xa7, 0xdc, 0x0e, 0x66, 0x85, 0x7d, 0x57, 0xd2, 0x7d, 0x2c, 0x41, 0x54, 0x14, - 0x2a, 0x90, 0xca, 0xa9, 0x63, 0x09, 0x4d, 0x7e, 0x85, 0x5d, 0x20, 0x38, 0x15, 0x2e, 0x6a, 0x7b, - 0x83, 0x36, 0x4f, 0x1c, 0x44, 0x54, 0x4d, 0xb5, 0x8b, 0xce, 0xfd, 0xca, 0xca, 0x41, 0x4a, 0x63, - 0xa1, 0x38, 0x52, 0x0f, 0x17, 0x51, 0x84, 0xd6, 0x16, 0x21, 0xd1, 0x09, 0xb4, 0xf8, 0x43, 0xf6, - 0xa0, 0x6e, 0x2d, 0x06, 0xa1, 0x97, 0x98, 0x85, 0x81, 0xaf, 0xa2, 0x81, 0x4f, 0x45, 0x96, 0x85, - 0x72, 0x6c, 0x93, 0x54, 0x05, 0x1e, 0x69, 0x89, 0x10, 0x53, 0x12, 0x90, 0xa5, 0x36, 0xfc, 0x77, - 0x49, 0xf6, 0x45, 0xb4, 0x1c, 0x3d, 0x1d, 0x12, 0xa6, 0xc0, 0x2c, 0xee, 0xe5, 0x61, 0xbc, 0x17, - 0xb5, 0x97, 0x50, 0xc7, 0x59, 0x5c, 0x15, 0xb6, 0xa3, 0xd4, 0x1f, 0x40, 0x4a, 0xc9, 0xb9, 0x48, - 0x69, 0x0e, 0x4a, 0x56, 0x2c, 0x41, 0x91, 0xb8, 0x05, 0x21, 0x8b, 0x95, 0x42, 0x49, 0x98, 0x0a, - 0x93, 0x5c, 0xd3, 0x16, 0xc5, 0x48, 0x6c, 0x25, 0xba, 0x59, 0x56, 0x40, 0x11, 0x56, 0x95, 0xa7, - 0x4d, 0x34, 0x90, 0xd1, 0xb0, 0x0f, 0x94, 0xa7, 0xb0, 0x47, 0x09, 0xb8, 0x83, 0xd8, 0x32, 0x42, - 0x39, 0x30, 0x34, 0xc3, 0x66, 0x06, 0x2f, 0x92, 0x44, 0xf7, 0x42, 0xb2, 0x80, 0x25, 0x6e, 0x51, - 0x2c, 0x41, 0x36, 0x47, 0xc9, 0x33, 0x33, 0x94, 0x0d, 0x38, 0x6e, 0xa9, 0x79, 0xad, 0xe7, 0x54, - 0x96, 0x73, 0x46, 0x50, 0xd0, 0x67, 0x79, 0xb3, 0x83, 0x03, 0x6f, 0x30, 0x29, 0xbb, 0x6d, 0x10, - 0xa7, 0x4b, 0x61, 0x2c, 0xd2, 0x02, 0x53, 0xca, 0xd8, 0x5e, 0x25, 0xe6, 0xc1, 0x4a, 0x59, 0xdb, - 0xaf, 0x94, 0x53, 0x30, 0x4b, 0xcc, 0xb4, 0x8d, 0x1d, 0x0c, 0x66, 0x2d, 0xb3, 0x52, 0x9c, 0xf0, - 0xb4, 0x52, 0x40, 0xa1, 0x8c, 0x29, 0x79, 0x0a, 0x51, 0xe0, 0x0f, 0x95, 0x62, 0x2f, 0xaa, 0x78, - 0x01, 0xfd, 0x63, 0xf5, 0x7d, 0x20, 0xc3, 0x5b, 0xcd, 0xa0, 0x84, 0x3f, 0xf1, 0x7b, 0xec, 0x4e, - 0xdd, 0xea, 0x53, 0x2d, 0xf3, 0x04, 0xbd, 0xeb, 0x53, 0x28, 0x3c, 0x3d, 0xb0, 0xb0, 0x9b, 0xc2, - 0x9f, 0xe9, 0x39, 0x82, 0xdd, 0x74, 0xf6, 0xcc, 0x80, 0x7d, 0xf2, 0x1d, 0x6c, 0xce, 0x08, 0x65, - 0xe3, 0xd0, 0x28, 0x0e, 0xe8, 0x3c, 0xc1, 0x3a, 0x0b, 0xdc, 0x3b, 0x74, 0x48, 0x57, 0x09, 0xe8, - 0x6c, 0xbf, 0x39, 0xf8, 0x35, 0x25, 0x71, 0x00, 0x95, 0x0e, 0x5b, 0x8c, 0x2a, 0xdb, 0x1a, 0x8c, - 0x30, 0xce, 0x1c, 0xfc, 0x85, 0xde, 0x88, 0xc1, 0x66, 0x1f, 0x23, 0x3c, 0xab, 0xfc, 0xc6, 0xc7, - 0x16, 0xbe, 0xa9, 0x1c, 0xab, 0x4c, 0x4d, 0x61, 0xdb, 0xf0, 0x9c, 0x42, 0x3f, 0xb3, 0xc2, 0x5f, - 0xeb, 0x34, 0x1b, 0x3f, 0x45, 0xf8, 0x96, 0x06, 0xef, 0x3c, 0x5c, 0x14, 0x03, 0x1b, 0x5e, 0xbf, - 0x99, 0xd1, 0xa1, 0x16, 0xe1, 0x45, 0x8d, 0x24, 0x75, 0x4f, 0x59, 0x67, 0x50, 0x54, 0xf8, 0x70, - 0xb8, 0xb1, 0xbc, 0xf6, 0x05, 0x7c, 0xb1, 0xb1, 0xbc, 0xf6, 0x25, 0x7c, 0xb9, 0xb1, 0xbc, 0xb6, - 0x03, 0x3b, 0x1b, 0xcb, 0x6b, 0x5f, 0xc1, 0x57, 0x9b, 0x0f, 0x19, 0xef, 0xed, 0x4f, 0x0e, 0xd3, - 0xd1, 0x64, 0xb2, 0xff, 0x6c, 0x64, 0x5f, 0x1f, 0x4c, 0xc3, 0x5b, 0x79, 0x9d, 0x9d, 0xdc, 0xcb, - 0xd1, 0x84, 0xd7, 0xf2, 0x29, 0xb6, 0x8a, 0x7d, 0x8c, 0x72, 0x87, 0xb0, 0xd4, 0xdc, 0xfd, 0xcf, - 0x9b, 0xc6, 0xd2, 0x77, 0x6f, 0x1a, 0x4b, 0xff, 0x7b, 0xd3, 0x58, 0xfa, 0xd7, 0xdb, 0xc6, 0xb1, - 0xef, 0xde, 0x36, 0x8e, 0xfd, 0xf7, 0x6d, 0xe3, 0xd8, 0xd3, 0xcf, 0x9e, 0x3d, 0x9f, 0x7e, 0xf3, - 0xfa, 0x60, 0x6b, 0x38, 0x3e, 0xdc, 0xa6, 0xef, 0xa0, 0xf2, 0xcf, 0xa7, 0x93, 0xaf, 0xbf, 0xdd, - 0x0e, 0x4e, 0x6b, 0x1f, 0x46, 0x07, 0x2b, 0xc5, 0xf7, 0xd0, 0x93, 0xff, 0x07, 0x00, 0x00, 0xff, - 0xff, 0xbd, 0x5c, 0x9f, 0xd6, 0x37, 0x0d, 0x00, 0x00, + // 1586 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x57, 0x59, 0x77, 0x1b, 0xb7, + 0x15, 0x96, 0x6c, 0x59, 0x0b, 0xbc, 0x5d, 0xc3, 0xfb, 0x26, 0x3b, 0xb2, 0x1b, 0xbb, 0x8a, 0x23, + 0xc5, 0x76, 0xd7, 0xa4, 0x6d, 0x0a, 0x0e, 0xae, 0xc8, 0x11, 0x67, 0x80, 0x11, 0x80, 0xe1, 0xe2, + 0xb6, 0x41, 0x25, 0x86, 0x75, 0xdc, 0x58, 0xa2, 0x8f, 0x48, 0xf7, 0xb4, 0xbf, 0xa1, 0x2f, 0xfd, + 0x43, 0x7d, 0xef, 0x63, 0x1e, 0xfb, 0xd8, 0x63, 0xff, 0x91, 0x1e, 0xcc, 0x5c, 0xd2, 0xc3, 0x89, + 0x9d, 0x3c, 0x49, 0xbc, 0xdf, 0x87, 0x0b, 0xe0, 0xbb, 0x1b, 0x86, 0xdd, 0x1f, 0x8c, 0xc6, 0x87, + 0xa3, 0xf1, 0xf6, 0xfe, 0x60, 0x30, 0x1c, 0x8f, 0x07, 0xa3, 0xa3, 0xc9, 0xf1, 0xe8, 0xe5, 0xf6, + 0x60, 0x74, 0x34, 0x9e, 0xec, 0x1f, 0x4d, 0xc6, 0x5b, 0xaf, 0x8e, 0x47, 0x93, 0x11, 0xbf, 0x55, + 0xb2, 0xb6, 0xe6, 0x58, 0x5b, 0x7f, 0x7b, 0x7c, 0x30, 0x9c, 0xec, 0x3f, 0xde, 0xfc, 0x9c, 0x31, + 0x51, 0x00, 0xee, 0x1f, 0xaf, 0x86, 0xfc, 0x34, 0x5b, 0xc9, 0x55, 0x5b, 0xe9, 0xae, 0x82, 0x05, + 0xbe, 0xca, 0x96, 0x0c, 0x0a, 0x09, 0x8b, 0x7c, 0x8d, 0x9d, 0xea, 0x9a, 0xd8, 0x21, 0x9c, 0xe0, + 0x8c, 0x2d, 0x47, 0x3a, 0x4d, 0x63, 0x07, 0x27, 0x37, 0xff, 0x79, 0x82, 0xdd, 0x2c, 0x17, 0xeb, + 0x57, 0xc3, 0xe3, 0xfd, 0xc9, 0x8b, 0xd1, 0x91, 0x1d, 0xbe, 0x1c, 0x0e, 0x26, 0xa3, 0xe3, 0xc2, + 0xdb, 0x2a, 0x5b, 0x52, 0x5a, 0x21, 0x2c, 0xf0, 0x65, 0x76, 0x62, 0x77, 0x0f, 0x16, 0xf9, 0x65, + 0x76, 0x61, 0x77, 0xcf, 0x37, 0x30, 0x6a, 0x3d, 0x7d, 0xe2, 0x85, 0x94, 0x06, 0xad, 0x85, 0x13, + 0x7c, 0x9d, 0xdd, 0xd8, 0xdd, 0xf3, 0x09, 0xaa, 0xa6, 0x6b, 0xf9, 0xcc, 0xe0, 0x4e, 0xdc, 0x43, + 0x39, 0xc3, 0x4f, 0xf2, 0xeb, 0xec, 0xb2, 0x45, 0x25, 0xd1, 0xd4, 0x97, 0x2e, 0xf1, 0x0d, 0xb6, + 0x4e, 0xd0, 0x87, 0x96, 0x9f, 0xe2, 0x97, 0x18, 0x44, 0x5a, 0x39, 0x23, 0x22, 0x37, 0xb3, 0x2e, + 0xf3, 0x1b, 0xec, 0xca, 0xee, 0x9e, 0x4f, 0xd1, 0x5a, 0xd1, 0x44, 0x1f, 0x69, 0x25, 0x63, 0x17, + 0x6b, 0x25, 0x12, 0x58, 0x09, 0x58, 0xa4, 0x95, 0x75, 0x42, 0x39, 0x6f, 0x9d, 0x89, 0x55, 0xd3, + 0x3b, 0xed, 0x5b, 0xd8, 0x83, 0x55, 0x7e, 0x85, 0xf1, 0x99, 0x37, 0x83, 0x3b, 0x68, 0x50, 0x45, + 0x08, 0x6b, 0x9b, 0xff, 0xbe, 0xc2, 0xce, 0x98, 0xe1, 0x78, 0xf4, 0xfa, 0x78, 0x30, 0x2c, 0xae, + 0xbf, 0xc2, 0x4e, 0x0a, 0xd5, 0x2f, 0x6f, 0xdf, 0xee, 0xc0, 0x62, 0x30, 0xa4, 0xc3, 0xc3, 0x52, + 0x44, 0x39, 0xfc, 0x7b, 0xf8, 0xff, 0x64, 0x90, 0xbc, 0xdd, 0xf1, 0x0d, 0xa1, 0xda, 0xb0, 0xc4, + 0xcf, 0x31, 0xd6, 0xee, 0x78, 0xeb, 0x44, 0x3b, 0x56, 0x4d, 0x38, 0x45, 0x60, 0x57, 0xd8, 0x14, + 0x96, 0xf9, 0x59, 0xb6, 0xd6, 0xee, 0x78, 0x6d, 0x44, 0x94, 0x20, 0xac, 0x04, 0x27, 0xed, 0x8e, + 0x97, 0xc5, 0x99, 0xce, 0xb0, 0xd5, 0x76, 0xc7, 0x63, 0xa6, 0xa3, 0x16, 0xac, 0xf1, 0x8b, 0xec, + 0x7c, 0xbb, 0xe3, 0x9d, 0x6e, 0xa3, 0xda, 0x11, 0x91, 0xd3, 0xa6, 0x0f, 0x2c, 0x5c, 0x69, 0xb6, + 0xda, 0x77, 0xb4, 0x43, 0xef, 0x84, 0x69, 0xa2, 0xb3, 0x70, 0x9a, 0xdf, 0x66, 0xd7, 0xdf, 0x61, + 0xa2, 0xd9, 0x34, 0xd8, 0x14, 0xae, 0x64, 0x59, 0x38, 0x13, 0xa2, 0xf6, 0x0e, 0xde, 0x41, 0x94, + 0x68, 0x2c, 0x9c, 0x0d, 0x51, 0x79, 0x77, 0x58, 0x2f, 0x31, 0x09, 0xab, 0x62, 0xad, 0xe0, 0x1c, + 0xbf, 0xc6, 0x2e, 0x55, 0xa0, 0x8e, 0x48, 0x62, 0x29, 0x9c, 0x36, 0x70, 0x9e, 0x6e, 0x24, 0x72, + 0xd7, 0x02, 0x20, 0x0f, 0xe1, 0xc7, 0x34, 0x2e, 0xde, 0x3a, 0x6d, 0x10, 0x2e, 0x70, 0xce, 0xce, + 0x91, 0x2c, 0xde, 0xe6, 0x59, 0x96, 0xf4, 0x81, 0xf3, 0x0b, 0xec, 0xec, 0xd4, 0x26, 0x51, 0xe9, + 0x14, 0x2e, 0x86, 0xd0, 0x4e, 0x4d, 0x0d, 0x91, 0x08, 0x15, 0xa1, 0x85, 0x4b, 0xe4, 0xb7, 0x2a, + 0x00, 0x2d, 0xb8, 0xcc, 0x6f, 0xb1, 0x6b, 0x75, 0x28, 0x45, 0x27, 0xa4, 0x70, 0x02, 0xae, 0xbc, + 0x6f, 0xa1, 0x90, 0x69, 0xac, 0xe0, 0x2a, 0xbf, 0xc9, 0xae, 0xd6, 0xa1, 0xc8, 0x60, 0x71, 0xab, + 0x6b, 0x04, 0x92, 0x42, 0xd8, 0x8b, 0x5a, 0x42, 0x35, 0xd1, 0x1b, 0xe1, 0x10, 0xae, 0x87, 0x14, + 0xad, 0x29, 0x9f, 0xa1, 0x12, 0x89, 0xeb, 0xfb, 0x48, 0xe7, 0xca, 0xa1, 0x81, 0x1b, 0x74, 0x2c, + 0xe2, 0x64, 0x26, 0x8e, 0xd0, 0x5b, 0x25, 0x32, 0xdb, 0xd2, 0x0e, 0x6e, 0xf2, 0x3b, 0xec, 0xe6, + 0xf7, 0xe5, 0x8c, 0xb5, 0xf2, 0x99, 0xee, 0xa2, 0x81, 0x5b, 0x14, 0xdc, 0x29, 0xc1, 0x69, 0x27, + 0x12, 0xc2, 0x6e, 0xd3, 0xf6, 0xdf, 0x8b, 0x85, 0x0d, 0x29, 0x5f, 0xc8, 0x0e, 0xeb, 0xfc, 0x1e, + 0xbb, 0x53, 0xe1, 0xe4, 0xaa, 0x11, 0xaa, 0x61, 0x3e, 0xa8, 0x77, 0xf8, 0x03, 0x76, 0xef, 0x47, + 0x48, 0xc1, 0x3b, 0xdc, 0x25, 0x35, 0xa6, 0x44, 0x83, 0x15, 0x2f, 0x1f, 0xd5, 0xb6, 0xaa, 0x82, + 0x61, 0xb5, 0xb7, 0x26, 0x82, 0x8d, 0x1f, 0x23, 0x49, 0xeb, 0xe0, 0x1e, 0xff, 0x88, 0xdd, 0xfe, + 0x10, 0x69, 0x2f, 0xc7, 0x1c, 0xe1, 0x7e, 0x68, 0x2c, 0xef, 0xbb, 0x3b, 0xe1, 0x3f, 0xa9, 0xe1, + 0xad, 0x38, 0x64, 0x5f, 0x1c, 0x89, 0xc4, 0xc7, 0x6a, 0x47, 0xc3, 0xc7, 0xb5, 0x3c, 0x9e, 0x5d, + 0x19, 0x1e, 0x7c, 0x58, 0xd5, 0x46, 0x9f, 0x94, 0xff, 0x29, 0xd5, 0xa1, 0x8c, 0x43, 0x07, 0x69, + 0xe4, 0xc5, 0xfd, 0x1f, 0x52, 0xa4, 0xab, 0xc6, 0x50, 0x52, 0x3e, 0xd3, 0x3a, 0x81, 0x4d, 0x7e, + 0x97, 0xdd, 0xaa, 0xa3, 0x99, 0xd1, 0x99, 0xb6, 0x68, 0x7c, 0x1b, 0xfb, 0xf0, 0x09, 0x45, 0x61, + 0x8e, 0xa1, 0x73, 0x17, 0x5a, 0x95, 0x2c, 0x65, 0xe8, 0x0a, 0x23, 0x2d, 0x3c, 0xe2, 0x9f, 0xb0, + 0x07, 0x75, 0x22, 0x29, 0xa4, 0x8d, 0xef, 0xc6, 0xae, 0x25, 0x8d, 0xe8, 0x96, 0x09, 0xf0, 0xe9, + 0x0f, 0x93, 0xad, 0x13, 0xc6, 0x05, 0xe7, 0x85, 0x2a, 0x5b, 0x7c, 0x93, 0x7d, 0x5c, 0x27, 0x87, + 0xa8, 0x54, 0xe4, 0x9b, 0x9e, 0x62, 0xfb, 0x7d, 0xc7, 0x0d, 0xdc, 0x28, 0x37, 0x06, 0x95, 0x9b, + 0x11, 0x3f, 0xe3, 0x0f, 0xd9, 0xfd, 0xf7, 0x11, 0x45, 0x14, 0xe5, 0xa9, 0x2f, 0x46, 0x8e, 0xb5, + 0x41, 0xc1, 0xc7, 0x54, 0x0d, 0x73, 0x4c, 0x9b, 0x08, 0xdb, 0xf2, 0xd8, 0x41, 0xe5, 0xe0, 0xc9, + 0x54, 0x62, 0xec, 0xf9, 0x59, 0xa3, 0x4e, 0xb4, 0x6a, 0x36, 0xb4, 0x6e, 0xc3, 0x53, 0x6a, 0x76, + 0x73, 0xa8, 0x6d, 0x69, 0xe3, 0x0a, 0xf8, 0x67, 0xd4, 0xec, 0x02, 0x6c, 0xd1, 0xb9, 0x04, 0xd3, + 0xe0, 0xf3, 0xe7, 0xa1, 0xeb, 0x93, 0x39, 0x13, 0xb1, 0xa1, 0x29, 0x03, 0xbf, 0xe0, 0xe7, 0xd9, + 0x69, 0xb2, 0xbb, 0xae, 0xc8, 0xe0, 0x97, 0x1c, 0xd8, 0x99, 0x29, 0x31, 0x94, 0x31, 0xfc, 0x8a, + 0xca, 0x61, 0xde, 0xa3, 0x47, 0xe5, 0x4c, 0x1f, 0x7e, 0x4d, 0x95, 0x1b, 0x40, 0x83, 0xcd, 0xd8, + 0x3a, 0x34, 0x28, 0x8b, 0x2d, 0xe0, 0xf3, 0x8a, 0x2b, 0x6d, 0x24, 0x1a, 0xf8, 0x0d, 0x75, 0xc0, + 0xe2, 0xec, 0xa1, 0xd7, 0x25, 0xf0, 0xdb, 0x69, 0xc6, 0x60, 0x2f, 0x48, 0x15, 0xfa, 0x89, 0x17, + 0x91, 0x8b, 0x3b, 0x58, 0xae, 0xb1, 0xf0, 0xbb, 0xca, 0x8d, 0x84, 0xb5, 0xe8, 0x7c, 0x12, 0x5b, + 0x07, 0xbf, 0xa7, 0xdc, 0x0e, 0x66, 0x85, 0x3d, 0x57, 0xd2, 0x7d, 0x2c, 0x41, 0x54, 0x14, 0x2a, + 0x90, 0xca, 0xa9, 0x63, 0x09, 0x0d, 0x7e, 0x95, 0x5d, 0x24, 0x38, 0x15, 0x2e, 0x6a, 0x79, 0x83, + 0x36, 0x4f, 0x1c, 0x44, 0x54, 0x4d, 0xb5, 0x8b, 0xce, 0xfc, 0xca, 0xca, 0x41, 0x4a, 0x63, 0xa1, + 0x38, 0x52, 0x0f, 0x17, 0x51, 0x84, 0xd6, 0x16, 0x21, 0xd1, 0x09, 0x34, 0xf9, 0x23, 0xf6, 0xb0, + 0x6e, 0x2d, 0x06, 0xa1, 0x97, 0x98, 0x85, 0x81, 0xaf, 0xa2, 0xbe, 0x4f, 0x45, 0x96, 0x85, 0x72, + 0x6c, 0x91, 0x54, 0x05, 0x1e, 0x69, 0x89, 0x10, 0x53, 0x12, 0x90, 0xa5, 0x36, 0xfc, 0x77, 0x49, + 0xf6, 0x79, 0xb4, 0x1c, 0x3d, 0x6d, 0x12, 0xa6, 0xc0, 0x2c, 0xee, 0xe5, 0x61, 0xbc, 0x17, 0xb5, + 0x97, 0x50, 0xc7, 0x99, 0x5f, 0x15, 0xb6, 0xa3, 0xd4, 0xef, 0x43, 0x4a, 0xc9, 0x39, 0x4f, 0x69, + 0xf4, 0x4b, 0x56, 0x2c, 0x41, 0x91, 0xb8, 0x05, 0x21, 0x8b, 0x95, 0x42, 0x49, 0x98, 0x0a, 0x93, + 0x5c, 0xd3, 0x16, 0xc5, 0x48, 0x6c, 0x26, 0xba, 0x51, 0x56, 0x40, 0x11, 0x56, 0x95, 0xa7, 0x0d, + 0x34, 0x90, 0xd1, 0xb0, 0x0f, 0x94, 0x67, 0xb0, 0x47, 0x09, 0xb8, 0x83, 0xd8, 0x34, 0x42, 0x39, + 0x30, 0x34, 0xc3, 0xa6, 0x06, 0x2f, 0x92, 0x44, 0x77, 0x43, 0xb2, 0x80, 0x25, 0x6e, 0x51, 0x2c, + 0x41, 0x36, 0x47, 0xc9, 0x33, 0x35, 0x94, 0x0d, 0x38, 0x6e, 0xaa, 0x59, 0xad, 0xe7, 0x54, 0x96, + 0x33, 0x46, 0x50, 0xd0, 0x67, 0x79, 0xa3, 0x8d, 0x7d, 0x6f, 0x30, 0x29, 0xbb, 0x6d, 0x10, 0xa7, + 0x43, 0x61, 0x2c, 0xd2, 0x02, 0x53, 0xca, 0xd8, 0x6e, 0x25, 0xe6, 0xc1, 0x4a, 0x59, 0xdb, 0xab, + 0x94, 0x53, 0x30, 0x4b, 0xcc, 0xb4, 0x8d, 0x1d, 0xf4, 0xa7, 0x2d, 0xb3, 0x52, 0x9c, 0xf0, 0xac, + 0x52, 0x40, 0xa1, 0x8c, 0x29, 0x79, 0x0a, 0x51, 0xe0, 0x0f, 0x95, 0x62, 0x2f, 0xaa, 0x78, 0x0e, + 0xfd, 0x63, 0xf5, 0x7d, 0x20, 0xc3, 0x5b, 0xcd, 0xa0, 0x84, 0x3f, 0xf1, 0xfb, 0xec, 0x6e, 0xdd, + 0xea, 0x53, 0x2d, 0xf3, 0x04, 0xbd, 0xeb, 0x51, 0x28, 0x3c, 0x3d, 0xb0, 0xb0, 0x93, 0xc2, 0x9f, + 0xe9, 0x39, 0x82, 0x9d, 0x74, 0xfa, 0xcc, 0x80, 0x7d, 0xf2, 0x1d, 0x6c, 0xce, 0x08, 0x65, 0xe3, + 0xd0, 0x28, 0x0e, 0xe8, 0x3c, 0xc1, 0x3a, 0x0d, 0xdc, 0x3b, 0x74, 0x40, 0x57, 0x09, 0xe8, 0x74, + 0xbf, 0x19, 0xf8, 0x35, 0x25, 0x71, 0x00, 0x95, 0x0e, 0x5b, 0x0c, 0x2b, 0xdb, 0x1a, 0x8c, 0x30, + 0xce, 0x1c, 0xfc, 0x85, 0xde, 0x88, 0xc1, 0x66, 0x9f, 0x20, 0x3c, 0xaf, 0xfc, 0xc6, 0x27, 0x16, + 0xbe, 0xa9, 0x1c, 0xab, 0x4c, 0x4d, 0x61, 0x5b, 0xf0, 0x82, 0x42, 0x3f, 0xb5, 0xc2, 0x5f, 0xeb, + 0x34, 0x1b, 0x3f, 0x43, 0xf8, 0x96, 0x6a, 0xbb, 0x50, 0xa6, 0x8b, 0xf1, 0xec, 0xb2, 0x2f, 0x69, + 0x22, 0xcf, 0xe2, 0x48, 0xc1, 0xb1, 0xe1, 0x59, 0x9c, 0x19, 0x1d, 0x8a, 0x14, 0x0e, 0x6b, 0x24, + 0xa9, 0xbb, 0xca, 0x3a, 0x83, 0xa2, 0xc2, 0x87, 0xa3, 0x8d, 0xa5, 0xd5, 0x2f, 0xe0, 0x8b, 0x8d, + 0xa5, 0xd5, 0x2f, 0xe1, 0xcb, 0x8d, 0xa5, 0xd5, 0x1d, 0xd8, 0xd9, 0x58, 0x5a, 0xfd, 0x0a, 0xbe, + 0xda, 0x7c, 0xc4, 0x78, 0x77, 0x7f, 0x7c, 0x98, 0x0e, 0xc7, 0xe3, 0xfd, 0xe7, 0x43, 0xfb, 0xfa, + 0x60, 0x12, 0x1e, 0xd1, 0x6b, 0xec, 0xd4, 0x5e, 0x8e, 0x26, 0x3c, 0xa3, 0x4f, 0xb3, 0x15, 0xec, + 0x61, 0x94, 0x3b, 0x84, 0xc5, 0xc6, 0xee, 0x7f, 0xde, 0xac, 0x2f, 0x7e, 0xf7, 0x66, 0x7d, 0xf1, + 0x7f, 0x6f, 0xd6, 0x17, 0xff, 0xf5, 0x76, 0x7d, 0xe1, 0xbb, 0xb7, 0xeb, 0x0b, 0xff, 0x7d, 0xbb, + 0xbe, 0xf0, 0xec, 0xb3, 0xe7, 0x2f, 0x26, 0xdf, 0xbc, 0x3e, 0xd8, 0x1a, 0x8c, 0x0e, 0xb7, 0xe9, + 0x03, 0xa9, 0xfc, 0xf3, 0xe9, 0xf8, 0xeb, 0x6f, 0xb7, 0x83, 0xd3, 0xda, 0x17, 0xd3, 0xc1, 0x72, + 0xf1, 0xa1, 0xf4, 0xf4, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0x26, 0x61, 0xa3, 0xab, 0x50, 0x0d, + 0x00, 0x00, } diff --git a/types/accesscontrol/resource.go b/types/accesscontrol/resource.go index 19cffa4b7..5bbe30e61 100644 --- a/types/accesscontrol/resource.go +++ b/types/accesscontrol/resource.go @@ -32,12 +32,14 @@ var ResourceTree = map[ResourceType]TreeNode{ ResourceType_KV_BANK_SUPPLY, ResourceType_KV_BANK_DENOM, ResourceType_KV_BANK_BALANCES, + ResourceType_KV_BANK_WEI_BALANCE, }}, ResourceType_KV_BANK_SUPPLY: {ResourceType_KV_BANK, []ResourceType{}}, ResourceType_KV_BANK_DENOM: {ResourceType_KV_BANK, []ResourceType{}}, ResourceType_KV_BANK_BALANCES: {ResourceType_KV_BANK, []ResourceType{}}, ResourceType_KV_BANK_DEFERRED: {ResourceType_KV, []ResourceType{ResourceType_KV_BANK_DEFERRED_MODULE_TX_INDEX}}, ResourceType_KV_BANK_DEFERRED_MODULE_TX_INDEX: {ResourceType_KV_BANK_DEFERRED, []ResourceType{}}, + ResourceType_KV_BANK_WEI_BALANCE: {ResourceType_KV_BANK, []ResourceType{}}, ResourceType_KV_STAKING: {ResourceType_KV, []ResourceType{ ResourceType_KV_STAKING_DELEGATION, ResourceType_KV_STAKING_VALIDATOR, diff --git a/x/accesscontrol/testutil/accesscontrol.go b/x/accesscontrol/testutil/accesscontrol.go index 29e25e867..2be4ecc95 100644 --- a/x/accesscontrol/testutil/accesscontrol.go +++ b/x/accesscontrol/testutil/accesscontrol.go @@ -23,10 +23,11 @@ var TestingStoreKeyToResourceTypePrefixMap = acltypes.StoreKeyToResourceTypePref acltypes.ResourceType_Mem: acltypes.EmptyPrefix, }, banktypes.StoreKey: { - acltypes.ResourceType_KV_BANK: acltypes.EmptyPrefix, - acltypes.ResourceType_KV_BANK_BALANCES: banktypes.BalancesPrefix, - acltypes.ResourceType_KV_BANK_SUPPLY: banktypes.SupplyKey, - acltypes.ResourceType_KV_BANK_DENOM: banktypes.DenomMetadataPrefix, + acltypes.ResourceType_KV_BANK: acltypes.EmptyPrefix, + acltypes.ResourceType_KV_BANK_BALANCES: banktypes.BalancesPrefix, + acltypes.ResourceType_KV_BANK_SUPPLY: banktypes.SupplyKey, + acltypes.ResourceType_KV_BANK_DENOM: banktypes.DenomMetadataPrefix, + acltypes.ResourceType_KV_BANK_WEI_BALANCE: banktypes.WeiBalancesPrefix, }, banktypes.DeferredCacheStoreKey: { acltypes.ResourceType_KV_BANK_DEFERRED: acltypes.EmptyPrefix, From a85e9b47f437957ee1e2b26d1abc28885c07fda0 Mon Sep 17 00:00:00 2001 From: Steven Landers Date: Thu, 4 Jan 2024 10:58:37 -0500 Subject: [PATCH 08/39] [EVM] Add pending nonce support (#390) - Adding an expiration handler callback that lets the mempool - https://github.com/sei-protocol/sei-tendermint/pull/179 - e2e testing with hardhat tests --- baseapp/abci.go | 5 +++-- baseapp/baseapp.go | 12 +++++++----- baseapp/test_helpers.go | 6 +++--- types/context.go | 10 ++++++++++ 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/baseapp/abci.go b/baseapp/abci.go index bb7d94fcb..8a7c789e9 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -225,7 +225,7 @@ func (app *BaseApp) CheckTx(ctx context.Context, req *abci.RequestCheckTx) (*abc res := sdkerrors.ResponseCheckTx(err, 0, 0, app.trace) return &abci.ResponseCheckTxV2{ResponseCheckTx: &res}, err } - gInfo, result, _, priority, pendingTxChecker, err := app.runTx(sdkCtx, mode, tx, sha256.Sum256(req.Tx)) + gInfo, result, _, priority, pendingTxChecker, expireTxHandler, err := app.runTx(sdkCtx, mode, tx, sha256.Sum256(req.Tx)) if err != nil { res := sdkerrors.ResponseCheckTx(err, gInfo.GasWanted, gInfo.GasUsed, app.trace) return &abci.ResponseCheckTxV2{ResponseCheckTx: &res}, err @@ -240,6 +240,7 @@ func (app *BaseApp) CheckTx(ctx context.Context, req *abci.RequestCheckTx) (*abc res.IsPendingTransaction = true res.Checker = pendingTxChecker } + res.ExpireTxHandler = expireTxHandler return res, nil } @@ -287,7 +288,7 @@ func (app *BaseApp) DeliverTx(ctx sdk.Context, req abci.RequestDeliverTx, tx sdk telemetry.SetGauge(float32(gInfo.GasWanted), "tx", "gas", "wanted") }() - gInfo, result, anteEvents, _, _, err := app.runTx(ctx.WithTxBytes(req.Tx).WithVoteInfos(app.voteInfos), runTxModeDeliver, tx, checksum) + gInfo, result, anteEvents, _, _, _, err := app.runTx(ctx.WithTxBytes(req.Tx).WithVoteInfos(app.voteInfos), runTxModeDeliver, tx, checksum) if err != nil { resultStr = "failed" // if we have a result, use those events instead of just the anteEvents diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 259b02f2b..ca79049db 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -835,6 +835,7 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [ anteEvents []abci.Event, priority int64, pendingTxChecker abci.PendingTxChecker, + expireHandler abci.ExpireTxHandler, err error, ) { defer telemetry.MeasureThroughputSinceWithLabels( @@ -884,13 +885,13 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [ }() if tx == nil { - return sdk.GasInfo{}, nil, nil, 0, nil, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "tx decode error") + return sdk.GasInfo{}, nil, nil, 0, nil, nil, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "tx decode error") } msgs := tx.GetMsgs() if err := validateBasicTxMsgs(msgs); err != nil { - return sdk.GasInfo{}, nil, nil, 0, nil, err + return sdk.GasInfo{}, nil, nil, 0, nil, nil, err } if app.anteHandler != nil { @@ -935,7 +936,7 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [ // GasMeter expected to be set in AnteHandler gasWanted = ctx.GasMeter().Limit() if err != nil { - return gInfo, nil, nil, 0, nil, err + return gInfo, nil, nil, 0, nil, nil, err } // Dont need to validate in checkTx mode @@ -951,12 +952,13 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [ op.EmitValidationFailMetrics() } errMessage := fmt.Sprintf("Invalid Concurrent Execution antehandler missing %d access operations", len(missingAccessOps)) - return gInfo, nil, nil, 0, nil, sdkerrors.Wrap(sdkerrors.ErrInvalidConcurrencyExecution, errMessage) + return gInfo, nil, nil, 0, nil, nil, sdkerrors.Wrap(sdkerrors.ErrInvalidConcurrencyExecution, errMessage) } } priority = ctx.Priority() pendingTxChecker = ctx.PendingTxChecker() + expireHandler = ctx.ExpireTxHandler() msCache.Write() anteEvents = events.ToABCIEvents() if app.TracingEnabled { @@ -985,7 +987,7 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [ if ctx.CheckTxCallback() != nil { ctx.CheckTxCallback()(err) } - return gInfo, result, anteEvents, priority, pendingTxChecker, err + return gInfo, result, anteEvents, priority, pendingTxChecker, expireHandler, err } // runMsgs iterates through a list of messages and executes them with the provided diff --git a/baseapp/test_helpers.go b/baseapp/test_helpers.go index 7652b078e..1cc05327a 100644 --- a/baseapp/test_helpers.go +++ b/baseapp/test_helpers.go @@ -17,7 +17,7 @@ func (app *BaseApp) Check(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, *sdk return sdk.GasInfo{}, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "%s", err) } ctx := app.checkState.ctx.WithTxBytes(bz).WithVoteInfos(app.voteInfos).WithConsensusParams(app.GetConsensusParams(app.checkState.ctx)) - gasInfo, result, _, _, _, err := app.runTx(ctx, runTxModeCheck, tx, sha256.Sum256(bz)) + gasInfo, result, _, _, _, _, err := app.runTx(ctx, runTxModeCheck, tx, sha256.Sum256(bz)) if len(ctx.MultiStore().GetEvents()) > 0 { panic("Expected checkTx events to be empty") } @@ -31,7 +31,7 @@ func (app *BaseApp) Simulate(txBytes []byte) (sdk.GasInfo, *sdk.Result, error) { if err != nil { return sdk.GasInfo{}, nil, err } - gasInfo, result, _, _, _, err := app.runTx(ctx, runTxModeSimulate, tx, sha256.Sum256(txBytes)) + gasInfo, result, _, _, _, _, err := app.runTx(ctx, runTxModeSimulate, tx, sha256.Sum256(txBytes)) if len(ctx.MultiStore().GetEvents()) > 0 { panic("Expected simulate events to be empty") } @@ -49,7 +49,7 @@ func (app *BaseApp) Deliver(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, *s if err != nil { return sdk.GasInfo{}, &sdk.Result{}, err } - gasInfo, result, _, _, _, err := app.runTx(ctx, runTxModeDeliver, decoded, sha256.Sum256(bz)) + gasInfo, result, _, _, _, _, err := app.runTx(ctx, runTxModeDeliver, decoded, sha256.Sum256(bz)) return gasInfo, result, err } diff --git a/types/context.go b/types/context.go index 2ee371e13..25d1a33fb 100644 --- a/types/context.go +++ b/types/context.go @@ -42,6 +42,7 @@ type Context struct { priority int64 // The tx priority, only relevant in CheckTx pendingTxChecker abci.PendingTxChecker // Checker for pending transaction, only relevant in CheckTx checkTxCallback func(error) // callback to make at the end of CheckTx. Input param is the error (nil-able) of `runMsgs` + expireTxHandler func() // callback that the mempool invokes when a tx is expired txBlockingChannels acltypes.MessageAccessOpsChannelMapping txCompletionChannels acltypes.MessageAccessOpsChannelMapping @@ -118,6 +119,10 @@ func (c Context) Priority() int64 { return c.priority } +func (c Context) ExpireTxHandler() abci.ExpireTxHandler { + return c.expireTxHandler +} + func (c Context) PendingTxChecker() abci.PendingTxChecker { return c.pendingTxChecker } @@ -369,6 +374,11 @@ func (c Context) WithCheckTxCallback(checkTxCallback func(error)) Context { return c } +func (c Context) WithExpireTxHandler(expireTxHandler func()) Context { + c.expireTxHandler = expireTxHandler + return c +} + // TODO: remove??? func (c Context) IsZero() bool { return c.ms == nil From b809302cfbd23f8ef0b661afecab1ab65563cb57 Mon Sep 17 00:00:00 2001 From: codchen Date: Thu, 11 Jan 2024 10:29:02 +0800 Subject: [PATCH 09/39] rebase --- go.mod | 4 ++-- go.sum | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 7b80d0536..084aff912 100644 --- a/go.mod +++ b/go.mod @@ -19,6 +19,7 @@ require ( github.com/gogo/protobuf v1.3.3 github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.3 + github.com/google/btree v1.1.2 github.com/gorilla/handlers v1.5.1 github.com/gorilla/mux v1.8.0 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 @@ -97,7 +98,6 @@ require ( github.com/golang/glog v1.1.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/snappy v0.0.4 // indirect - github.com/google/btree v1.1.2 // indirect github.com/google/flatbuffers v1.12.1 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gofuzz v1.2.0 // indirect @@ -183,7 +183,7 @@ replace ( github.com/sei-protocol/sei-db => github.com/sei-protocol/sei-db v0.0.31 // Latest goleveldb is broken, we have to stick to this version github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 - github.com/tendermint/tendermint => github.com/sei-protocol/sei-tendermint v0.2.38 + github.com/tendermint/tendermint => github.com/sei-protocol/sei-tendermint v0.2.38-evm-rebase // latest grpc doesn't work with with our modified proto compiler, so we need to enforce // the following version across all dependencies. google.golang.org/grpc => google.golang.org/grpc v1.33.2 diff --git a/go.sum b/go.sum index d03d8672b..33040f742 100644 --- a/go.sum +++ b/go.sum @@ -785,8 +785,8 @@ github.com/sei-protocol/sei-db v0.0.31 h1:UW9skaXnaXfi9mp60EbAJ2ijyr1Hnu9WYatMNr github.com/sei-protocol/sei-db v0.0.31/go.mod h1:F/ZKZA8HJPcUzSZPA8yt6pfwlGriJ4RDR4eHKSGLStI= github.com/sei-protocol/sei-iavl v0.1.9 h1:y4mVYftxLNRs6533zl7N0/Ch+CzRQc04JDfHolIxgBE= github.com/sei-protocol/sei-iavl v0.1.9/go.mod h1:7PfkEVT5dcoQE+s/9KWdoXJ8VVVP1QpYYPLdxlkSXFk= -github.com/sei-protocol/sei-tendermint v0.2.38 h1:jZ3QzdzsuzKZrBM1IqEPkYU60nEugpKM/rNFGfYqmu0= -github.com/sei-protocol/sei-tendermint v0.2.38/go.mod h1:4LSlJdhl3nf3OmohliwRNUFLOB1XWlrmSodrIP7fLh4= +github.com/sei-protocol/sei-tendermint v0.2.38-evm-rebase h1:+c9PFgoHwYV+FGPGnJK8ySmUqlwfE0dbDri5zmxBQQI= +github.com/sei-protocol/sei-tendermint v0.2.38-evm-rebase/go.mod h1:4LSlJdhl3nf3OmohliwRNUFLOB1XWlrmSodrIP7fLh4= github.com/sei-protocol/sei-tm-db v0.0.5 h1:3WONKdSXEqdZZeLuWYfK5hP37TJpfaUa13vAyAlvaQY= github.com/sei-protocol/sei-tm-db v0.0.5/go.mod h1:Cpa6rGyczgthq7/0pI31jys2Fw0Nfrc+/jKdP1prVqY= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= From 260d226fea17a08a6cde075c5ef4b1bd3b1ca81f Mon Sep 17 00:00:00 2001 From: Steven Landers Date: Fri, 19 Jan 2024 11:05:40 -0500 Subject: [PATCH 10/39] [EVM] Allow multiple txs from same account in a block (#397) - needs tendermint pr and go.mod update - adds evm properties to the `ResponseCheckTxV2` - adds evm properties to context - hardhat tests on sei-chain repo - unit tests on tendermint repo --- baseapp/abci.go | 21 +++++++++++++-------- baseapp/baseapp.go | 11 ++++++----- baseapp/test_helpers.go | 6 +++--- types/context.go | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 16 deletions(-) diff --git a/baseapp/abci.go b/baseapp/abci.go index 8a7c789e9..61a7f4ad4 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -225,22 +225,27 @@ func (app *BaseApp) CheckTx(ctx context.Context, req *abci.RequestCheckTx) (*abc res := sdkerrors.ResponseCheckTx(err, 0, 0, app.trace) return &abci.ResponseCheckTxV2{ResponseCheckTx: &res}, err } - gInfo, result, _, priority, pendingTxChecker, expireTxHandler, err := app.runTx(sdkCtx, mode, tx, sha256.Sum256(req.Tx)) + gInfo, result, _, priority, pendingTxChecker, expireTxHandler, txCtx, err := app.runTx(sdkCtx, mode, tx, sha256.Sum256(req.Tx)) if err != nil { res := sdkerrors.ResponseCheckTx(err, gInfo.GasWanted, gInfo.GasUsed, app.trace) return &abci.ResponseCheckTxV2{ResponseCheckTx: &res}, err } - res := &abci.ResponseCheckTxV2{ResponseCheckTx: &abci.ResponseCheckTx{ - GasWanted: int64(gInfo.GasWanted), // TODO: Should type accept unsigned ints? - Data: result.Data, - Priority: priority, - }} + res := &abci.ResponseCheckTxV2{ + ResponseCheckTx: &abci.ResponseCheckTx{ + GasWanted: int64(gInfo.GasWanted), // TODO: Should type accept unsigned ints? + Data: result.Data, + Priority: priority, + }, + ExpireTxHandler: expireTxHandler, + EVMNonce: txCtx.EVMNonce(), + EVMSenderAddress: txCtx.EVMSenderAddress(), + IsEVM: txCtx.IsEVM(), + } if pendingTxChecker != nil { res.IsPendingTransaction = true res.Checker = pendingTxChecker } - res.ExpireTxHandler = expireTxHandler return res, nil } @@ -288,7 +293,7 @@ func (app *BaseApp) DeliverTx(ctx sdk.Context, req abci.RequestDeliverTx, tx sdk telemetry.SetGauge(float32(gInfo.GasWanted), "tx", "gas", "wanted") }() - gInfo, result, anteEvents, _, _, _, err := app.runTx(ctx.WithTxBytes(req.Tx).WithVoteInfos(app.voteInfos), runTxModeDeliver, tx, checksum) + gInfo, result, anteEvents, _, _, _, _, err := app.runTx(ctx.WithTxBytes(req.Tx).WithVoteInfos(app.voteInfos), runTxModeDeliver, tx, checksum) if err != nil { resultStr = "failed" // if we have a result, use those events instead of just the anteEvents diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index ca79049db..20b978fbb 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -836,6 +836,7 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [ priority int64, pendingTxChecker abci.PendingTxChecker, expireHandler abci.ExpireTxHandler, + txCtx sdk.Context, err error, ) { defer telemetry.MeasureThroughputSinceWithLabels( @@ -885,13 +886,13 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [ }() if tx == nil { - return sdk.GasInfo{}, nil, nil, 0, nil, nil, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "tx decode error") + return sdk.GasInfo{}, nil, nil, 0, nil, nil, ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "tx decode error") } msgs := tx.GetMsgs() if err := validateBasicTxMsgs(msgs); err != nil { - return sdk.GasInfo{}, nil, nil, 0, nil, nil, err + return sdk.GasInfo{}, nil, nil, 0, nil, nil, ctx, err } if app.anteHandler != nil { @@ -936,7 +937,7 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [ // GasMeter expected to be set in AnteHandler gasWanted = ctx.GasMeter().Limit() if err != nil { - return gInfo, nil, nil, 0, nil, nil, err + return gInfo, nil, nil, 0, nil, nil, ctx, err } // Dont need to validate in checkTx mode @@ -952,7 +953,7 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [ op.EmitValidationFailMetrics() } errMessage := fmt.Sprintf("Invalid Concurrent Execution antehandler missing %d access operations", len(missingAccessOps)) - return gInfo, nil, nil, 0, nil, nil, sdkerrors.Wrap(sdkerrors.ErrInvalidConcurrencyExecution, errMessage) + return gInfo, nil, nil, 0, nil, nil, ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidConcurrencyExecution, errMessage) } } @@ -987,7 +988,7 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [ if ctx.CheckTxCallback() != nil { ctx.CheckTxCallback()(err) } - return gInfo, result, anteEvents, priority, pendingTxChecker, expireHandler, err + return gInfo, result, anteEvents, priority, pendingTxChecker, expireHandler, ctx, err } // runMsgs iterates through a list of messages and executes them with the provided diff --git a/baseapp/test_helpers.go b/baseapp/test_helpers.go index 1cc05327a..dc8b5150f 100644 --- a/baseapp/test_helpers.go +++ b/baseapp/test_helpers.go @@ -17,7 +17,7 @@ func (app *BaseApp) Check(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, *sdk return sdk.GasInfo{}, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "%s", err) } ctx := app.checkState.ctx.WithTxBytes(bz).WithVoteInfos(app.voteInfos).WithConsensusParams(app.GetConsensusParams(app.checkState.ctx)) - gasInfo, result, _, _, _, _, err := app.runTx(ctx, runTxModeCheck, tx, sha256.Sum256(bz)) + gasInfo, result, _, _, _, _, _, err := app.runTx(ctx, runTxModeCheck, tx, sha256.Sum256(bz)) if len(ctx.MultiStore().GetEvents()) > 0 { panic("Expected checkTx events to be empty") } @@ -31,7 +31,7 @@ func (app *BaseApp) Simulate(txBytes []byte) (sdk.GasInfo, *sdk.Result, error) { if err != nil { return sdk.GasInfo{}, nil, err } - gasInfo, result, _, _, _, _, err := app.runTx(ctx, runTxModeSimulate, tx, sha256.Sum256(txBytes)) + gasInfo, result, _, _, _, _, _, err := app.runTx(ctx, runTxModeSimulate, tx, sha256.Sum256(txBytes)) if len(ctx.MultiStore().GetEvents()) > 0 { panic("Expected simulate events to be empty") } @@ -49,7 +49,7 @@ func (app *BaseApp) Deliver(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, *s if err != nil { return sdk.GasInfo{}, &sdk.Result{}, err } - gasInfo, result, _, _, _, _, err := app.runTx(ctx, runTxModeDeliver, decoded, sha256.Sum256(bz)) + gasInfo, result, _, _, _, _, _, err := app.runTx(ctx, runTxModeDeliver, decoded, sha256.Sum256(bz)) return gasInfo, result, err } diff --git a/types/context.go b/types/context.go index 25d1a33fb..81d0ab14b 100644 --- a/types/context.go +++ b/types/context.go @@ -48,6 +48,11 @@ type Context struct { txCompletionChannels acltypes.MessageAccessOpsChannelMapping txMsgAccessOps map[int][]acltypes.AccessOperation + // EVM properties + evm bool // EVM transaction flag + evmNonce uint64 // EVM Transaction nonce + evmSenderAddress string // EVM Sender address + msgValidator *acltypes.MsgValidator messageIndex int // Used to track current message being processed txIndex int @@ -123,6 +128,18 @@ func (c Context) ExpireTxHandler() abci.ExpireTxHandler { return c.expireTxHandler } +func (c Context) EVMSenderAddress() string { + return c.evmSenderAddress +} + +func (c Context) EVMNonce() uint64 { + return c.evmNonce +} + +func (c Context) IsEVM() bool { + return c.evm +} + func (c Context) PendingTxChecker() abci.PendingTxChecker { return c.pendingTxChecker } @@ -364,6 +381,21 @@ func (c Context) WithTraceSpanContext(ctx context.Context) Context { return c } +func (c Context) WithEVMSenderAddress(address string) Context { + c.evmSenderAddress = address + return c +} + +func (c Context) WithEVMNonce(nonce uint64) Context { + c.evmNonce = nonce + return c +} + +func (c Context) WithIsEVM(isEVM bool) Context { + c.evm = isEVM + return c +} + func (c Context) WithPendingTxChecker(checker abci.PendingTxChecker) Context { c.pendingTxChecker = checker return c From eeeba13daf0dde454d0115b055e3baf196da2c83 Mon Sep 17 00:00:00 2001 From: codchen Date: Tue, 23 Jan 2024 16:08:34 +0800 Subject: [PATCH 11/39] Expose VersionExists (#400) Add an interface function `VersionExists` to store types local sei integration --- go.mod | 2 +- server/mock/store.go | 4 ++++ store/cachekv/store.go | 4 ++++ store/dbadapter/store.go | 4 ++++ store/gaskv/store.go | 4 ++++ store/listenkv/store.go | 4 ++++ store/prefix/store.go | 4 ++++ store/tracekv/store.go | 4 ++++ store/types/store.go | 2 ++ storev2/commitment/store.go | 5 +++++ storev2/state/store.go | 11 ++++++++++- x/bank/keeper/keeper.go | 6 ++++++ 12 files changed, 52 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 084aff912..aa5ac6836 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require ( github.com/regen-network/cosmos-proto v0.3.1 github.com/rs/zerolog v1.30.0 github.com/savaki/jq v0.0.0-20161209013833-0e6baecebbf8 - github.com/sei-protocol/sei-db v0.0.22 + github.com/sei-protocol/sei-db v0.0.27-0.20240123064153-d6dfa112e760 github.com/sei-protocol/sei-tm-db v0.0.5 github.com/spf13/cast v1.5.0 github.com/spf13/cobra v1.6.1 diff --git a/server/mock/store.go b/server/mock/store.go index ab12f961a..2f74d87eb 100644 --- a/server/mock/store.go +++ b/server/mock/store.go @@ -226,6 +226,10 @@ func (kv kvStore) ReverseSubspaceIterator(prefix []byte) sdk.Iterator { panic("not implemented") } +func (kv kvStore) VersionExists(version int64) bool { + panic("not implemented") +} + func NewCommitMultiStore() sdk.CommitMultiStore { return multiStore{kv: make(map[sdk.StoreKey]kvStore)} } diff --git a/store/cachekv/store.go b/store/cachekv/store.go index e4177f767..4217db46a 100644 --- a/store/cachekv/store.go +++ b/store/cachekv/store.go @@ -192,6 +192,10 @@ func (store *Store) iterator(start, end []byte, ascending bool) types.Iterator { return NewCacheMergeIterator(parent, cache, ascending, store.storeKey) } +func (store *Store) VersionExists(version int64) bool { + return store.parent.VersionExists(version) +} + func findStartIndex(strL []string, startQ string) int { // Modified binary search to find the very first element in >=startQ. if len(strL) == 0 { diff --git a/store/dbadapter/store.go b/store/dbadapter/store.go index bf0c95364..04b3910ac 100644 --- a/store/dbadapter/store.go +++ b/store/dbadapter/store.go @@ -95,5 +95,9 @@ func (dsa Store) CacheWrapWithListeners(storeKey types.StoreKey, listeners []typ return cachekv.NewStore(listenkv.NewStore(dsa, storeKey, listeners), storeKey, types.DefaultCacheSizeLimit) } +func (dsa Store) VersionExists(version int64) bool { + panic("no versioning for dbadater") +} + // dbm.DB implements KVStore so we can CacheKVStore it. var _ types.KVStore = Store{} diff --git a/store/gaskv/store.go b/store/gaskv/store.go index 0aa9f4282..4792becbe 100644 --- a/store/gaskv/store.go +++ b/store/gaskv/store.go @@ -126,6 +126,10 @@ func (gs *Store) iterator(start, end []byte, ascending bool) types.Iterator { return gi } +func (gs *Store) VersionExists(version int64) bool { + return gs.parent.VersionExists(version) +} + type gasIterator struct { gasMeter types.GasMeter gasConfig types.GasConfig diff --git a/store/listenkv/store.go b/store/listenkv/store.go index bf49b1282..99bdce48e 100644 --- a/store/listenkv/store.go +++ b/store/listenkv/store.go @@ -81,6 +81,10 @@ func (s *Store) iterator(start, end []byte, ascending bool) types.Iterator { return newTraceIterator(parent, s.listeners) } +func (s *Store) VersionExists(version int64) bool { + return s.parent.VersionExists(version) +} + type listenIterator struct { parent types.Iterator listeners []types.WriteListener diff --git a/store/prefix/store.go b/store/prefix/store.go index f6c29fd15..bb79f93f4 100644 --- a/store/prefix/store.go +++ b/store/prefix/store.go @@ -124,6 +124,10 @@ func (s Store) ReverseIterator(start, end []byte) types.Iterator { return newPrefixIterator(s.prefix, start, end, iter) } +func (s Store) VersionExists(version int64) bool { + return s.parent.VersionExists(version) +} + var _ types.Iterator = (*prefixIterator)(nil) type prefixIterator struct { diff --git a/store/tracekv/store.go b/store/tracekv/store.go index 2798d90ec..f18ab2c77 100644 --- a/store/tracekv/store.go +++ b/store/tracekv/store.go @@ -182,6 +182,10 @@ func (tkv *Store) CacheWrapWithListeners(_ types.StoreKey, _ []types.WriteListen panic("cannot CacheWrapWithListeners a TraceKVStore") } +func (tkv *Store) VersionExists(version int64) bool { + return tkv.parent.VersionExists(version) +} + // writeOperation writes a KVStore operation to the underlying io.Writer as // JSON-encoded data where the key/value pair is base64 encoded. func writeOperation(w io.Writer, op operation, tc types.TraceContext, key, value []byte) { diff --git a/store/types/store.go b/store/types/store.go index 1bc699b24..7ed731afa 100644 --- a/store/types/store.go +++ b/store/types/store.go @@ -253,6 +253,8 @@ type KVStore interface { ReverseIterator(start, end []byte) Iterator GetWorkingHash() ([]byte, error) + + VersionExists(version int64) bool } // Iterator is an alias db's Iterator for convenience. diff --git a/storev2/commitment/store.go b/storev2/commitment/store.go index a51073875..406419ad9 100644 --- a/storev2/commitment/store.go +++ b/storev2/commitment/store.go @@ -177,3 +177,8 @@ func (st *Store) Query(req abci.RequestQuery) (res abci.ResponseQuery) { return res } + +func (st *Store) VersionExists(version int64) bool { + // one version per SC tree + return version == st.tree.Version() +} diff --git a/storev2/state/store.go b/storev2/state/store.go index 76c129bf5..0257e2309 100644 --- a/storev2/state/store.go +++ b/storev2/state/store.go @@ -1,10 +1,11 @@ package state import ( - "cosmossdk.io/errors" "fmt" "io" + "cosmossdk.io/errors" + "github.com/cosmos/cosmos-sdk/store/cachekv" "github.com/cosmos/cosmos-sdk/store/listenkv" "github.com/cosmos/cosmos-sdk/store/tracekv" @@ -125,3 +126,11 @@ func (st *Store) Query(req abci.RequestQuery) (res abci.ResponseQuery) { return res } + +func (st *Store) VersionExists(version int64) bool { + earliest, err := st.store.GetEarliestVersion() + if err != nil { + panic(err) + } + return version >= earliest +} diff --git a/x/bank/keeper/keeper.go b/x/bank/keeper/keeper.go index cdcf20d6c..8b0bd2f03 100644 --- a/x/bank/keeper/keeper.go +++ b/x/bank/keeper/keeper.go @@ -51,6 +51,8 @@ type Keeper interface { DelegateCoins(ctx sdk.Context, delegatorAddr, moduleAccAddr sdk.AccAddress, amt sdk.Coins) error UndelegateCoins(ctx sdk.Context, moduleAccAddr, delegatorAddr sdk.AccAddress, amt sdk.Coins) error + GetStoreKey() sdk.StoreKey + types.QueryServer } @@ -677,6 +679,10 @@ func (k BaseKeeper) trackUndelegation(ctx sdk.Context, addr sdk.AccAddress, amt return nil } +func (k BaseKeeper) GetStoreKey() sdk.StoreKey { + return k.storeKey +} + // IterateTotalSupply iterates over the total supply calling the given cb (callback) function // with the balance of each coin. // The iteration stops if the callback returns true. From e2248dd580d34891080002ed2e307bfed4667f63 Mon Sep 17 00:00:00 2001 From: codchen Date: Wed, 24 Jan 2024 22:54:13 +0800 Subject: [PATCH 12/39] Add `DeleteAll` method to store type (#402) ## Describe your changes and provide context Iterating with mergeiterator to get all keys and then deleting is extremely slow when there are >10 layers of `cachekv`. This PR adds a more efficient function to delete all keys within a range, without having to make recursive calls like mergeiterator. ## Testing performed to validate your change unit test on cachekv --------- Co-authored-by: Philip Su --- server/mock/store.go | 4 ++++ store/cachekv/store.go | 15 +++++++++++++++ store/cachekv/store_test.go | 10 ++++++++++ store/dbadapter/store.go | 13 +++++++++++++ store/dbadapter/store_test.go | 12 ++++++++++++ store/gaskv/store.go | 4 ++++ store/iavl/store.go | 13 +++++++++++++ store/iavl/store_test.go | 15 +++++++++++++++ store/listenkv/store.go | 4 ++++ store/prefix/store.go | 12 ++++++++++++ store/tracekv/store.go | 4 ++++ store/types/store.go | 2 ++ storev2/commitment/store.go | 13 +++++++++++++ storev2/state/store.go | 13 +++++++++++++ 14 files changed, 134 insertions(+) diff --git a/server/mock/store.go b/server/mock/store.go index 2f74d87eb..6096f35d4 100644 --- a/server/mock/store.go +++ b/server/mock/store.go @@ -230,6 +230,10 @@ func (kv kvStore) VersionExists(version int64) bool { panic("not implemented") } +func (kv kvStore) DeleteAll(start, end []byte) error { + panic("not implemented") +} + func NewCommitMultiStore() sdk.CommitMultiStore { return multiStore{kv: make(map[sdk.StoreKey]kvStore)} } diff --git a/store/cachekv/store.go b/store/cachekv/store.go index 4217db46a..a33adf17c 100644 --- a/store/cachekv/store.go +++ b/store/cachekv/store.go @@ -367,3 +367,18 @@ func (store *Store) isDeleted(key string) bool { func (store *Store) GetParent() types.KVStore { return store.parent } + +func (store *Store) DeleteAll(start, end []byte) error { + store.dirtyItems(start, end) + // memdb iterator + cachedIter, err := store.sortedCache.Iterator(start, end) + if err != nil { + return err + } + defer cachedIter.Close() + for ; cachedIter.Valid(); cachedIter.Next() { + // `Delete` would not touch sortedCache so it's okay to perform inside iterator + store.Delete(cachedIter.Key()) + } + return nil +} diff --git a/store/cachekv/store_test.go b/store/cachekv/store_test.go index 65c3f4eaa..c6e7ab5b6 100644 --- a/store/cachekv/store_test.go +++ b/store/cachekv/store_test.go @@ -65,6 +65,16 @@ func TestCacheKVStore(t *testing.T) { // GetParent returns parent store require.NotNil(t, st.GetParent()) + + // DeleteAll deletes all entries in cache but not affect mem + st = cachekv.NewStore(mem, types.NewKVStoreKey("CacheKvTest"), types.DefaultCacheSizeLimit) + mem.Set(keyFmt(1), valFmt(1)) + st.Set(keyFmt(1), valFmt(2)) + st.Set(keyFmt(2), valFmt(3)) + require.Nil(t, st.DeleteAll(nil, nil)) + require.Nil(t, st.Get(keyFmt(1))) + require.Nil(t, st.Get(keyFmt(2))) + require.Equal(t, valFmt(1), mem.Get(keyFmt(1))) } func TestCacheKVStoreNoNilSet(t *testing.T) { diff --git a/store/dbadapter/store.go b/store/dbadapter/store.go index 04b3910ac..b8de090f1 100644 --- a/store/dbadapter/store.go +++ b/store/dbadapter/store.go @@ -99,5 +99,18 @@ func (dsa Store) VersionExists(version int64) bool { panic("no versioning for dbadater") } +func (dsa Store) DeleteAll(start, end []byte) error { + iter := dsa.Iterator(start, end) + keys := [][]byte{} + for ; iter.Valid(); iter.Next() { + keys = append(keys, iter.Key()) + } + iter.Close() + for _, key := range keys { + dsa.Delete(key) + } + return nil +} + // dbm.DB implements KVStore so we can CacheKVStore it. var _ types.KVStore = Store{} diff --git a/store/dbadapter/store_test.go b/store/dbadapter/store_test.go index 467ba6421..f13209cbe 100644 --- a/store/dbadapter/store_test.go +++ b/store/dbadapter/store_test.go @@ -13,6 +13,7 @@ import ( "github.com/cosmos/cosmos-sdk/store/dbadapter" "github.com/cosmos/cosmos-sdk/store/types" "github.com/cosmos/cosmos-sdk/tests/mocks" + dbm "github.com/tendermint/tm-db" ) var errFoo = errors.New("dummy") @@ -74,6 +75,17 @@ func TestAccessors(t *testing.T) { require.Panics(t, func() { store.ReverseIterator(start, end) }) } +func TestDeleteAll(t *testing.T) { + mem := dbadapter.Store{DB: dbm.NewMemDB()} + mem.Set([]byte("1"), []byte("2")) + mem.Set([]byte("3"), []byte("4")) + require.NotNil(t, mem.Get([]byte("1"))) + require.NotNil(t, mem.Get([]byte("3"))) + require.Nil(t, mem.DeleteAll(nil, nil)) + require.Nil(t, mem.Get([]byte("1"))) + require.Nil(t, mem.Get([]byte("3"))) +} + func TestCacheWraps(t *testing.T) { mockCtrl := gomock.NewController(t) mockDB := mocks.NewMockDB(mockCtrl) diff --git a/store/gaskv/store.go b/store/gaskv/store.go index 4792becbe..62e3d89c4 100644 --- a/store/gaskv/store.go +++ b/store/gaskv/store.go @@ -130,6 +130,10 @@ func (gs *Store) VersionExists(version int64) bool { return gs.parent.VersionExists(version) } +func (gs *Store) DeleteAll(start, end []byte) error { + return gs.parent.DeleteAll(start, end) +} + type gasIterator struct { gasMeter types.GasMeter gasConfig types.GasConfig diff --git a/store/iavl/store.go b/store/iavl/store.go index 3bcc9af97..2d5bfad88 100644 --- a/store/iavl/store.go +++ b/store/iavl/store.go @@ -423,6 +423,19 @@ func (st *Store) Query(req abci.RequestQuery) (res abci.ResponseQuery) { return res } +func (st *Store) DeleteAll(start, end []byte) error { + iter := st.Iterator(start, end) + keys := [][]byte{} + for ; iter.Valid(); iter.Next() { + keys = append(keys, iter.Key()) + } + iter.Close() + for _, key := range keys { + st.Delete(key) + } + return nil +} + // Takes a MutableTree, a key, and a flag for creating existence or absence proof and returns the // appropriate merkle.Proof. Since this must be called after querying for the value, this function should never error // Thus, it will panic on error rather than returning it diff --git a/store/iavl/store_test.go b/store/iavl/store_test.go index 3cf0194e9..de56b4277 100644 --- a/store/iavl/store_test.go +++ b/store/iavl/store_test.go @@ -463,6 +463,21 @@ func TestIAVLNoPrune(t *testing.T) { } } +func TestIAVLStoreDeleteAll(t *testing.T) { + db := dbm.NewMemDB() + tree, err := iavl.NewMutableTree(db, cacheSize, false) + require.NoError(t, err) + + iavlStore := UnsafeNewStore(tree) + iavlStore.Set([]byte("1"), []byte("2")) + iavlStore.Set([]byte("3"), []byte("4")) + require.NotNil(t, iavlStore.Get([]byte("1"))) + require.NotNil(t, iavlStore.Get([]byte("3"))) + require.Nil(t, iavlStore.DeleteAll(nil, nil)) + require.Nil(t, iavlStore.Get([]byte("1"))) + require.Nil(t, iavlStore.Get([]byte("3"))) +} + func TestIAVLStoreQuery(t *testing.T) { db := dbm.NewMemDB() tree, err := iavl.NewMutableTree(db, cacheSize, false) diff --git a/store/listenkv/store.go b/store/listenkv/store.go index 99bdce48e..20f103ec0 100644 --- a/store/listenkv/store.go +++ b/store/listenkv/store.go @@ -161,3 +161,7 @@ func (s *Store) onWrite(delete bool, key, value []byte) { l.OnWrite(s.parentStoreKey, key, value, delete) } } + +func (s *Store) DeleteAll(start, end []byte) error { + return s.parent.DeleteAll(start, end) +} diff --git a/store/prefix/store.go b/store/prefix/store.go index bb79f93f4..fd1f2672b 100644 --- a/store/prefix/store.go +++ b/store/prefix/store.go @@ -90,6 +90,18 @@ func (s Store) Delete(key []byte) { s.parent.Delete(s.key(key)) } +func (s Store) DeleteAll(start, end []byte) error { + newstart := cloneAppend(s.prefix, start) + + var newend []byte + if end == nil { + newend = cpIncr(s.prefix) + } else { + newend = cloneAppend(s.prefix, end) + } + return s.parent.DeleteAll(newstart, newend) +} + // Implements KVStore // Check https://github.com/tendermint/tendermint/blob/master/libs/db/prefix_db.go#L106 func (s Store) Iterator(start, end []byte) types.Iterator { diff --git a/store/tracekv/store.go b/store/tracekv/store.go index f18ab2c77..81fe2034c 100644 --- a/store/tracekv/store.go +++ b/store/tracekv/store.go @@ -186,6 +186,10 @@ func (tkv *Store) VersionExists(version int64) bool { return tkv.parent.VersionExists(version) } +func (tkv *Store) DeleteAll(start, end []byte) error { + return tkv.parent.DeleteAll(start, end) +} + // writeOperation writes a KVStore operation to the underlying io.Writer as // JSON-encoded data where the key/value pair is base64 encoded. func writeOperation(w io.Writer, op operation, tc types.TraceContext, key, value []byte) { diff --git a/store/types/store.go b/store/types/store.go index 7ed731afa..e1f4b0a97 100644 --- a/store/types/store.go +++ b/store/types/store.go @@ -255,6 +255,8 @@ type KVStore interface { GetWorkingHash() ([]byte, error) VersionExists(version int64) bool + + DeleteAll(start, end []byte) error } // Iterator is an alias db's Iterator for convenience. diff --git a/storev2/commitment/store.go b/storev2/commitment/store.go index 406419ad9..f48362873 100644 --- a/storev2/commitment/store.go +++ b/storev2/commitment/store.go @@ -182,3 +182,16 @@ func (st *Store) VersionExists(version int64) bool { // one version per SC tree return version == st.tree.Version() } + +func (st *Store) DeleteAll(start, end []byte) error { + iter := st.Iterator(start, end) + keys := [][]byte{} + for ; iter.Valid(); iter.Next() { + keys = append(keys, iter.Key()) + } + iter.Close() + for _, key := range keys { + st.Delete(key) + } + return nil +} diff --git a/storev2/state/store.go b/storev2/state/store.go index 0257e2309..b9c9c7599 100644 --- a/storev2/state/store.go +++ b/storev2/state/store.go @@ -134,3 +134,16 @@ func (st *Store) VersionExists(version int64) bool { } return version >= earliest } + +func (st *Store) DeleteAll(start, end []byte) error { + iter := st.Iterator(start, end) + keys := [][]byte{} + for ; iter.Valid(); iter.Next() { + keys = append(keys, iter.Key()) + } + iter.Close() + for _, key := range keys { + st.Delete(key) + } + return nil +} From 46ec3fb158f3d8f839a3b7f0f2a325c285cc04f2 Mon Sep 17 00:00:00 2001 From: codchen Date: Thu, 1 Feb 2024 15:57:22 +0800 Subject: [PATCH 13/39] Allow balance to go negative in SendCoinsAndWei (#417) ## Describe your changes and provide context Bypass negative check for sends involving Wei escrow accounts, since they may temporarily go negative during tx processing (but will be settled back to 0 in EndBlock) ## Testing performed to validate your change tested with the corresponding sei change --- types/coin.go | 8 +++++++ x/bank/keeper/keeper.go | 16 ++++++------- x/bank/keeper/send.go | 53 ++++++++++++++++++++++------------------- 3 files changed, 45 insertions(+), 32 deletions(-) diff --git a/types/coin.go b/types/coin.go index 0c33ed757..f96996c13 100644 --- a/types/coin.go +++ b/types/coin.go @@ -120,6 +120,14 @@ func (coin Coin) Sub(coinB Coin) Coin { return res } +func (coin Coin) SubUnsafe(coinB Coin) Coin { + if coin.Denom != coinB.Denom { + panic(fmt.Sprintf("invalid coin denominations; %s, %s", coin.Denom, coinB.Denom)) + } + + return Coin{coin.Denom, coin.Amount.Sub(coinB.Amount)} +} + // SubAmount subtracts an amount from the Coin. func (coin Coin) SubAmount(amount Int) Coin { res := Coin{coin.Denom, coin.Amount.Sub(amount)} diff --git a/x/bank/keeper/keeper.go b/x/bank/keeper/keeper.go index 8b0bd2f03..e74d868a1 100644 --- a/x/bank/keeper/keeper.go +++ b/x/bank/keeper/keeper.go @@ -200,7 +200,7 @@ func (k BaseKeeper) DelegateCoins(ctx sdk.Context, delegatorAddr, moduleAccAddr } balances = balances.Add(balance) - err := k.setBalance(ctx, delegatorAddr, balance.Sub(coin)) + err := k.setBalance(ctx, delegatorAddr, balance.Sub(coin), true) if err != nil { return err } @@ -214,7 +214,7 @@ func (k BaseKeeper) DelegateCoins(ctx sdk.Context, delegatorAddr, moduleAccAddr types.NewCoinSpentEvent(delegatorAddr, amt), ) - err := k.addCoins(ctx, moduleAccAddr, amt) + err := k.addCoins(ctx, moduleAccAddr, amt, true) if err != nil { return err } @@ -237,7 +237,7 @@ func (k BaseKeeper) UndelegateCoins(ctx sdk.Context, moduleAccAddr, delegatorAdd return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, amt.String()) } - err := k.subUnlockedCoins(ctx, moduleAccAddr, amt) + err := k.subUnlockedCoins(ctx, moduleAccAddr, amt, true) if err != nil { return err } @@ -246,7 +246,7 @@ func (k BaseKeeper) UndelegateCoins(ctx sdk.Context, moduleAccAddr, delegatorAdd return sdkerrors.Wrap(err, "failed to track undelegation") } - err = k.addCoins(ctx, delegatorAddr, amt) + err = k.addCoins(ctx, delegatorAddr, amt, true) if err != nil { return err } @@ -410,7 +410,7 @@ func (k BaseKeeper) DeferredSendCoinsFromAccountToModule( panic("bank keeper created without deferred cache") } // Deducts Fees from the Sender Account - err := k.subUnlockedCoins(ctx, senderAddr, amount) + err := k.subUnlockedCoins(ctx, senderAddr, amount, true) if err != nil { return err } @@ -468,7 +468,7 @@ func (k BaseKeeper) WriteDeferredBalances(ctx sdk.Context) []abci.Event { ctx.Logger().Error(err.Error()) panic(err) } - err := k.addCoins(ctx, sdk.MustAccAddressFromBech32(moduleBech32Addr), amount) + err := k.addCoins(ctx, sdk.MustAccAddressFromBech32(moduleBech32Addr), amount, true) if err != nil { ctx.Logger().Error(fmt.Sprintf("Failed to add coin=%s to module address=%s, error is: %s", amount, moduleBech32Addr, err)) panic(err) @@ -570,7 +570,7 @@ func (k BaseKeeper) MintCoins(ctx sdk.Context, moduleName string, amounts sdk.Co if acc == nil { return errors.New(fmt.Sprintf("module account for %s not found", moduleName)) } - return k.addCoins(ctx, acc.GetAddress(), amounts) + return k.addCoins(ctx, acc.GetAddress(), amounts, true) } err := k.createCoins(ctx, moduleName, amounts, addFn) @@ -616,7 +616,7 @@ func (k BaseKeeper) destroyCoins(ctx sdk.Context, moduleName string, amounts sdk func (k BaseKeeper) BurnCoins(ctx sdk.Context, moduleName string, amounts sdk.Coins) error { subFn := func(ctx sdk.Context, moduleName string, amounts sdk.Coins) error { acc := k.ak.GetModuleAccount(ctx, moduleName) - return k.subUnlockedCoins(ctx, acc.GetAddress(), amounts) + return k.subUnlockedCoins(ctx, acc.GetAddress(), amounts, true) } err := k.destroyCoins(ctx, moduleName, amounts, subFn) diff --git a/x/bank/keeper/send.go b/x/bank/keeper/send.go index 93ac398dd..401a815ba 100644 --- a/x/bank/keeper/send.go +++ b/x/bank/keeper/send.go @@ -89,7 +89,7 @@ func (k BaseSendKeeper) InputOutputCoins(ctx sdk.Context, inputs []types.Input, return err } - err = k.subUnlockedCoins(ctx, inAddress, in.Coins) + err = k.subUnlockedCoins(ctx, inAddress, in.Coins, true) if err != nil { return err } @@ -107,7 +107,7 @@ func (k BaseSendKeeper) InputOutputCoins(ctx sdk.Context, inputs []types.Input, if err != nil { return err } - err = k.addCoins(ctx, outAddress, out.Coins) + err = k.addCoins(ctx, outAddress, out.Coins, true) if err != nil { return err } @@ -155,12 +155,16 @@ func (k BaseSendKeeper) SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAd } func (k BaseSendKeeper) SendCoinsWithoutAccCreation(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error { - err := k.subUnlockedCoins(ctx, fromAddr, amt) + return k.sendCoinsWithoutAccCreation(ctx, fromAddr, toAddr, amt, true) +} + +func (k BaseSendKeeper) sendCoinsWithoutAccCreation(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins, checkNeg bool) error { + err := k.subUnlockedCoins(ctx, fromAddr, amt, checkNeg) if err != nil { return err } - err = k.addCoins(ctx, toAddr, amt) + err = k.addCoins(ctx, toAddr, amt, checkNeg) if err != nil { return err } @@ -184,7 +188,7 @@ func (k BaseSendKeeper) SendCoinsWithoutAccCreation(ctx sdk.Context, fromAddr sd // subUnlockedCoins removes the unlocked amt coins of the given account. An error is // returned if the resulting balance is negative or the initial amount is invalid. // A coin_spent event is emitted after. -func (k BaseSendKeeper) subUnlockedCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) error { +func (k BaseSendKeeper) subUnlockedCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins, checkNeg bool) error { if !amt.IsValid() { return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, amt.String()) } @@ -193,17 +197,24 @@ func (k BaseSendKeeper) subUnlockedCoins(ctx sdk.Context, addr sdk.AccAddress, a for _, coin := range amt { balance := k.GetBalance(ctx, addr, coin.Denom) - locked := sdk.NewCoin(coin.Denom, lockedCoins.AmountOf(coin.Denom)) - spendable := balance.Sub(locked) + if checkNeg { + locked := sdk.NewCoin(coin.Denom, lockedCoins.AmountOf(coin.Denom)) + spendable := balance.Sub(locked) - _, hasNeg := sdk.Coins{spendable}.SafeSub(sdk.Coins{coin}) - if hasNeg { - return sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, "%s is smaller than %s", spendable, coin) + _, hasNeg := sdk.Coins{spendable}.SafeSub(sdk.Coins{coin}) + if hasNeg { + return sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, "%s is smaller than %s", spendable, coin) + } } - newBalance := balance.Sub(coin) + var newBalance sdk.Coin + if checkNeg { + newBalance = balance.Sub(coin) + } else { + newBalance = balance.SubUnsafe(coin) + } - err := k.setBalance(ctx, addr, newBalance) + err := k.setBalance(ctx, addr, newBalance, checkNeg) if err != nil { return err } @@ -218,7 +229,7 @@ func (k BaseSendKeeper) subUnlockedCoins(ctx sdk.Context, addr sdk.AccAddress, a // addCoins increase the addr balance by the given amt. Fails if the provided amt is invalid. // It emits a coin received event. -func (k BaseSendKeeper) addCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) error { +func (k BaseSendKeeper) addCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins, checkNeg bool) error { if !amt.IsValid() { return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, amt.String()) } @@ -227,7 +238,7 @@ func (k BaseSendKeeper) addCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.C balance := k.GetBalance(ctx, addr, coin.Denom) newBalance := balance.Add(coin) - err := k.setBalance(ctx, addr, newBalance) + err := k.setBalance(ctx, addr, newBalance, checkNeg) if err != nil { return err } @@ -262,8 +273,8 @@ func (k BaseSendKeeper) initBalances(ctx sdk.Context, addr sdk.AccAddress, balan } // setBalance sets the coin balance for an account by address. -func (k BaseSendKeeper) setBalance(ctx sdk.Context, addr sdk.AccAddress, balance sdk.Coin) error { - if !balance.IsValid() { +func (k BaseSendKeeper) setBalance(ctx sdk.Context, addr sdk.AccAddress, balance sdk.Coin, checkNeg bool) error { + if checkNeg && !balance.IsValid() { return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, balance.String()) } @@ -343,7 +354,7 @@ func (k BaseSendKeeper) SendCoinsAndWei(ctx sdk.Context, from sdk.AccAddress, to return err } // need to send one sei to escrow because wei balance is insufficient - if err := k.SendCoinsWithoutAccCreation(ctx, from, escrow, sdk.NewCoins(sdk.NewCoin(denom, sdk.OneInt()))); err != nil { + if err := k.sendCoinsWithoutAccCreation(ctx, from, escrow, sdk.NewCoins(sdk.NewCoin(denom, sdk.OneInt())), false); err != nil { return err } } @@ -359,13 +370,7 @@ func (k BaseSendKeeper) SendCoinsAndWei(ctx sdk.Context, from sdk.AccAddress, to } // need to redeem one sei from escrow because wei balance overflowed one := sdk.NewCoins(sdk.NewCoin(denom, sdk.OneInt())) - if err := k.SendCoinsWithoutAccCreation(ctx, escrow, to, one); err != nil { - if sdkerrors.ErrInsufficientFunds.Is(err) && customEscrow != nil { - // custom escrow does not have enough balance to redeem. Try the global escrow instead - if err := k.SendCoinsWithoutAccCreation(ctx, k.ak.GetModuleAddress(types.WeiEscrowName), to, one); err != nil { - return err - } - } + if err := k.sendCoinsWithoutAccCreation(ctx, escrow, to, one, false); err != nil { return err } } From d952e2a5224bb325a22b7492ab23de1e98ce2873 Mon Sep 17 00:00:00 2001 From: codchen Date: Tue, 13 Feb 2024 16:17:22 +0800 Subject: [PATCH 14/39] Expose add/sub balance methods on bank keeper (#432) ## Describe your changes and provide context ## Testing performed to validate your change --- x/bank/keeper/keeper.go | 14 +++---- x/bank/keeper/send.go | 79 ++++++++++++++++++++++++++-------------- x/bank/spec/04_events.md | 4 +- 3 files changed, 61 insertions(+), 36 deletions(-) diff --git a/x/bank/keeper/keeper.go b/x/bank/keeper/keeper.go index e74d868a1..8bad207e8 100644 --- a/x/bank/keeper/keeper.go +++ b/x/bank/keeper/keeper.go @@ -214,7 +214,7 @@ func (k BaseKeeper) DelegateCoins(ctx sdk.Context, delegatorAddr, moduleAccAddr types.NewCoinSpentEvent(delegatorAddr, amt), ) - err := k.addCoins(ctx, moduleAccAddr, amt, true) + err := k.AddCoins(ctx, moduleAccAddr, amt, true) if err != nil { return err } @@ -237,7 +237,7 @@ func (k BaseKeeper) UndelegateCoins(ctx sdk.Context, moduleAccAddr, delegatorAdd return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, amt.String()) } - err := k.subUnlockedCoins(ctx, moduleAccAddr, amt, true) + err := k.SubUnlockedCoins(ctx, moduleAccAddr, amt, true) if err != nil { return err } @@ -246,7 +246,7 @@ func (k BaseKeeper) UndelegateCoins(ctx sdk.Context, moduleAccAddr, delegatorAdd return sdkerrors.Wrap(err, "failed to track undelegation") } - err = k.addCoins(ctx, delegatorAddr, amt, true) + err = k.AddCoins(ctx, delegatorAddr, amt, true) if err != nil { return err } @@ -410,7 +410,7 @@ func (k BaseKeeper) DeferredSendCoinsFromAccountToModule( panic("bank keeper created without deferred cache") } // Deducts Fees from the Sender Account - err := k.subUnlockedCoins(ctx, senderAddr, amount, true) + err := k.SubUnlockedCoins(ctx, senderAddr, amount, true) if err != nil { return err } @@ -468,7 +468,7 @@ func (k BaseKeeper) WriteDeferredBalances(ctx sdk.Context) []abci.Event { ctx.Logger().Error(err.Error()) panic(err) } - err := k.addCoins(ctx, sdk.MustAccAddressFromBech32(moduleBech32Addr), amount, true) + err := k.AddCoins(ctx, sdk.MustAccAddressFromBech32(moduleBech32Addr), amount, true) if err != nil { ctx.Logger().Error(fmt.Sprintf("Failed to add coin=%s to module address=%s, error is: %s", amount, moduleBech32Addr, err)) panic(err) @@ -570,7 +570,7 @@ func (k BaseKeeper) MintCoins(ctx sdk.Context, moduleName string, amounts sdk.Co if acc == nil { return errors.New(fmt.Sprintf("module account for %s not found", moduleName)) } - return k.addCoins(ctx, acc.GetAddress(), amounts, true) + return k.AddCoins(ctx, acc.GetAddress(), amounts, true) } err := k.createCoins(ctx, moduleName, amounts, addFn) @@ -616,7 +616,7 @@ func (k BaseKeeper) destroyCoins(ctx sdk.Context, moduleName string, amounts sdk func (k BaseKeeper) BurnCoins(ctx sdk.Context, moduleName string, amounts sdk.Coins) error { subFn := func(ctx sdk.Context, moduleName string, amounts sdk.Coins) error { acc := k.ak.GetModuleAccount(ctx, moduleName) - return k.subUnlockedCoins(ctx, acc.GetAddress(), amounts, true) + return k.SubUnlockedCoins(ctx, acc.GetAddress(), amounts, true) } err := k.destroyCoins(ctx, moduleName, amounts, subFn) diff --git a/x/bank/keeper/send.go b/x/bank/keeper/send.go index 401a815ba..b08728e05 100644 --- a/x/bank/keeper/send.go +++ b/x/bank/keeper/send.go @@ -21,6 +21,10 @@ type SendKeeper interface { SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error SendCoinsWithoutAccCreation(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error SendCoinsAndWei(ctx sdk.Context, from sdk.AccAddress, to sdk.AccAddress, customEscrow sdk.AccAddress, denom string, amt sdk.Int, wei sdk.Int) error + SubUnlockedCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins, checkNeg bool) error + AddCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins, checkNeg bool) error + SubWei(ctx sdk.Context, addr sdk.AccAddress, customEscrow sdk.AccAddress, denom string, amt sdk.Int) error + AddWei(ctx sdk.Context, addr sdk.AccAddress, customEscrow sdk.AccAddress, denom string, amt sdk.Int) error GetParams(ctx sdk.Context) types.Params SetParams(ctx sdk.Context, params types.Params) @@ -89,7 +93,7 @@ func (k BaseSendKeeper) InputOutputCoins(ctx sdk.Context, inputs []types.Input, return err } - err = k.subUnlockedCoins(ctx, inAddress, in.Coins, true) + err = k.SubUnlockedCoins(ctx, inAddress, in.Coins, true) if err != nil { return err } @@ -107,7 +111,7 @@ func (k BaseSendKeeper) InputOutputCoins(ctx sdk.Context, inputs []types.Input, if err != nil { return err } - err = k.addCoins(ctx, outAddress, out.Coins, true) + err = k.AddCoins(ctx, outAddress, out.Coins, true) if err != nil { return err } @@ -159,12 +163,12 @@ func (k BaseSendKeeper) SendCoinsWithoutAccCreation(ctx sdk.Context, fromAddr sd } func (k BaseSendKeeper) sendCoinsWithoutAccCreation(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins, checkNeg bool) error { - err := k.subUnlockedCoins(ctx, fromAddr, amt, checkNeg) + err := k.SubUnlockedCoins(ctx, fromAddr, amt, checkNeg) if err != nil { return err } - err = k.addCoins(ctx, toAddr, amt, checkNeg) + err = k.AddCoins(ctx, toAddr, amt, checkNeg) if err != nil { return err } @@ -185,10 +189,10 @@ func (k BaseSendKeeper) sendCoinsWithoutAccCreation(ctx sdk.Context, fromAddr sd return nil } -// subUnlockedCoins removes the unlocked amt coins of the given account. An error is +// SubUnlockedCoins removes the unlocked amt coins of the given account. An error is // returned if the resulting balance is negative or the initial amount is invalid. // A coin_spent event is emitted after. -func (k BaseSendKeeper) subUnlockedCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins, checkNeg bool) error { +func (k BaseSendKeeper) SubUnlockedCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins, checkNeg bool) error { if !amt.IsValid() { return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, amt.String()) } @@ -227,9 +231,9 @@ func (k BaseSendKeeper) subUnlockedCoins(ctx sdk.Context, addr sdk.AccAddress, a return nil } -// addCoins increase the addr balance by the given amt. Fails if the provided amt is invalid. +// AddCoins increase the addr balance by the given amt. Fails if the provided amt is invalid. // It emits a coin received event. -func (k BaseSendKeeper) addCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins, checkNeg bool) error { +func (k BaseSendKeeper) AddCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins, checkNeg bool) error { if !amt.IsValid() { return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, amt.String()) } @@ -328,52 +332,73 @@ func (k BaseSendKeeper) BlockedAddr(addr sdk.AccAddress) bool { return k.blockedAddrs[addr.String()] } -func (k BaseSendKeeper) SendCoinsAndWei(ctx sdk.Context, from sdk.AccAddress, to sdk.AccAddress, customEscrow sdk.AccAddress, denom string, amt sdk.Int, wei sdk.Int) error { - if wei.Equal(sdk.ZeroInt()) { - if amt.Equal(sdk.ZeroInt()) { - return nil - } - return k.SendCoinsWithoutAccCreation(ctx, from, to, sdk.NewCoins(sdk.NewCoin(denom, amt))) +func (k BaseSendKeeper) SubWei(ctx sdk.Context, addr sdk.AccAddress, customEscrow sdk.AccAddress, denom string, amt sdk.Int) error { + if amt.Equal(sdk.ZeroInt()) { + return nil } - if wei.GTE(MaxWeiBalance) { + if amt.GTE(MaxWeiBalance) { return errors.New("cannot send more than 10^12 wei") } escrow := customEscrow if escrow == nil { escrow = k.ak.GetModuleAddress(types.WeiEscrowName) } - currentWeiBalanceFrom := k.GetWeiBalance(ctx, from) - postWeiBalanceFrom := currentWeiBalanceFrom.Sub(wei) - if postWeiBalanceFrom.GTE(sdk.ZeroInt()) { - if err := k.setWeiBalance(ctx, from, postWeiBalanceFrom); err != nil { + currentWeiBalance := k.GetWeiBalance(ctx, addr) + postWeiBalance := currentWeiBalance.Sub(amt) + if postWeiBalance.GTE(sdk.ZeroInt()) { + if err := k.setWeiBalance(ctx, addr, postWeiBalance); err != nil { return err } } else { - if err := k.setWeiBalance(ctx, from, MaxWeiBalance.Add(postWeiBalanceFrom)); err != nil { + if err := k.setWeiBalance(ctx, addr, MaxWeiBalance.Add(postWeiBalance)); err != nil { // postWeiBalanceFrom is negative return err } // need to send one sei to escrow because wei balance is insufficient - if err := k.sendCoinsWithoutAccCreation(ctx, from, escrow, sdk.NewCoins(sdk.NewCoin(denom, sdk.OneInt())), false); err != nil { + if err := k.sendCoinsWithoutAccCreation(ctx, addr, escrow, sdk.NewCoins(sdk.NewCoin(denom, sdk.OneInt())), false); err != nil { return err } } - currentWeiBalanceTo := k.GetWeiBalance(ctx, to) - postWeiBalanceTo := currentWeiBalanceTo.Add(wei) - if postWeiBalanceTo.LT(MaxWeiBalance) { - if err := k.setWeiBalance(ctx, to, postWeiBalanceTo); err != nil { + return nil +} + +func (k BaseSendKeeper) AddWei(ctx sdk.Context, addr sdk.AccAddress, customEscrow sdk.AccAddress, denom string, amt sdk.Int) error { + if amt.Equal(sdk.ZeroInt()) { + return nil + } + if amt.GTE(MaxWeiBalance) { + return errors.New("cannot send more than 10^12 wei") + } + escrow := customEscrow + if escrow == nil { + escrow = k.ak.GetModuleAddress(types.WeiEscrowName) + } + currentWeiBalance := k.GetWeiBalance(ctx, addr) + postWeiBalance := currentWeiBalance.Add(amt) + if postWeiBalance.LT(MaxWeiBalance) { + if err := k.setWeiBalance(ctx, addr, postWeiBalance); err != nil { return err } } else { - if err := k.setWeiBalance(ctx, to, postWeiBalanceTo.Sub(MaxWeiBalance)); err != nil { + if err := k.setWeiBalance(ctx, addr, postWeiBalance.Sub(MaxWeiBalance)); err != nil { return err } // need to redeem one sei from escrow because wei balance overflowed one := sdk.NewCoins(sdk.NewCoin(denom, sdk.OneInt())) - if err := k.sendCoinsWithoutAccCreation(ctx, escrow, to, one, false); err != nil { + if err := k.sendCoinsWithoutAccCreation(ctx, escrow, addr, one, false); err != nil { return err } } + return nil +} + +func (k BaseSendKeeper) SendCoinsAndWei(ctx sdk.Context, from sdk.AccAddress, to sdk.AccAddress, customEscrow sdk.AccAddress, denom string, amt sdk.Int, wei sdk.Int) error { + if err := k.SubWei(ctx, from, customEscrow, denom, wei); err != nil { + return err + } + if err := k.AddWei(ctx, to, customEscrow, denom, wei); err != nil { + return err + } if amt.GT(sdk.ZeroInt()) { return k.SendCoinsWithoutAccCreation(ctx, from, to, sdk.NewCoins(sdk.NewCoin(denom, amt))) } diff --git a/x/bank/spec/04_events.md b/x/bank/spec/04_events.md index e71b82057..92dde22c1 100644 --- a/x/bank/spec/04_events.md +++ b/x/bank/spec/04_events.md @@ -108,7 +108,7 @@ In addition to handlers events, the bank keeper will produce events when the fol } ``` -### addCoins +### AddCoins ```json { @@ -128,7 +128,7 @@ In addition to handlers events, the bank keeper will produce events when the fol } ``` -### subUnlockedCoins/DelegateCoins +### SubUnlockedCoins/DelegateCoins ```json { From 0d9eda0b37ddcdc0eec96985ba7453d0d4b5188e Mon Sep 17 00:00:00 2001 From: codchen Date: Wed, 14 Feb 2024 16:23:43 +0800 Subject: [PATCH 15/39] Remove escrow account in wei logic (#434) ## Describe your changes and provide context Since add and sub balance are now decoupled, we no longer need an explicit escrow account, and can implicitly represent "escrow" by direct crediting/debiting account's usei balances. This PR removes the explicit escrow account logic, and also added wei logic in invariant checks ## Testing performed to validate your change unit tests --- types/denom.go | 8 ++++ x/bank/keeper/invariants.go | 26 +++++++++++ x/bank/keeper/keeper_test.go | 21 +++------ x/bank/keeper/send.go | 90 +++++++++++++++--------------------- x/bank/keeper/view.go | 19 ++++++++ x/bank/types/key.go | 2 - 6 files changed, 96 insertions(+), 70 deletions(-) diff --git a/types/denom.go b/types/denom.go index 0e8d716a2..33f42a917 100644 --- a/types/denom.go +++ b/types/denom.go @@ -53,6 +53,14 @@ func GetBaseDenom() (string, error) { return baseDenom, nil } +func MustGetBaseDenom() string { + bd, err := GetBaseDenom() + if err != nil { + panic(err) + } + return bd +} + // ConvertCoin attempts to convert a coin to a given denomination. If the given // denomination is invalid or if neither denomination is registered, an error // is returned. diff --git a/x/bank/keeper/invariants.go b/x/bank/keeper/invariants.go index aa5751da0..12ebf782a 100644 --- a/x/bank/keeper/invariants.go +++ b/x/bank/keeper/invariants.go @@ -37,6 +37,14 @@ func NonnegativeBalanceInvariant(k ViewKeeper) sdk.Invariant { return false }) + k.IterateAllWeiBalances(ctx, func(addr sdk.AccAddress, balance sdk.Int) bool { + if balance.IsNegative() { + count++ + msg += fmt.Sprintf("\t%s has a negative wei balance of %s\n", addr, balance) + } + + return false + }) broken := count != 0 @@ -51,6 +59,7 @@ func NonnegativeBalanceInvariant(k ViewKeeper) sdk.Invariant { func TotalSupply(k Keeper) sdk.Invariant { return func(ctx sdk.Context) (string, bool) { expectedTotal := sdk.Coins{} + weiTotal := sdk.NewInt(0) supply, _, err := k.GetPaginatedTotalSupply(ctx, &query.PageRequest{Limit: query.MaxLimit}) if err != nil { @@ -67,6 +76,23 @@ func TotalSupply(k Keeper) sdk.Invariant { expectedTotal = expectedTotal.Add(coin) return false }) + k.IterateAllWeiBalances(ctx, func(addr sdk.AccAddress, balance sdk.Int) bool { + weiTotal = weiTotal.Add(balance) + return false + }) + weiInUsei, weiRemainder := SplitUseiWeiAmount(weiTotal) + if !weiRemainder.IsZero() { + return sdk.FormatInvariant(types.ModuleName, "total supply", + fmt.Sprintf( + "\twei remainder: %v\n", + weiRemainder)), true + } + baseDenom, err := sdk.GetBaseDenom() + if err == nil { + expectedTotal = expectedTotal.Add(sdk.NewCoin(baseDenom, weiInUsei)) + } else if !weiInUsei.IsZero() { + return sdk.FormatInvariant(types.ModuleName, "total supply", "non-zero wei balance without base denom"), true + } broken := !expectedTotal.IsEqual(supply) diff --git a/x/bank/keeper/keeper_test.go b/x/bank/keeper/keeper_test.go index 25600f3f7..72d4060cf 100644 --- a/x/bank/keeper/keeper_test.go +++ b/x/bank/keeper/keeper_test.go @@ -76,7 +76,6 @@ func (suite *IntegrationTestSuite) initKeepersWithmAccPerms(blockedAddrs map[str appCodec := simapp.MakeTestEncodingConfig().Marshaler maccPerms[holder] = nil - maccPerms[types.WeiEscrowName] = nil maccPerms[authtypes.Burner] = []string{authtypes.Burner} maccPerms[authtypes.Minter] = []string{authtypes.Minter} maccPerms[multiPerm] = []string{authtypes.Burner, authtypes.Minter, authtypes.Staking} @@ -112,7 +111,8 @@ func (suite *IntegrationTestSuite) SetupTest() { func (suite *IntegrationTestSuite) TestSendCoinsAndWei() { ctx := suite.ctx require := suite.Require() - authKeeper, keeper := suite.initKeepersWithmAccPerms(make(map[string]bool)) + sdk.RegisterDenom(sdk.DefaultBondDenom, sdk.OneDec()) + _, keeper := suite.initKeepersWithmAccPerms(make(map[string]bool)) amt := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))) require.NoError(keeper.MintCoins(ctx, authtypes.Minter, amt)) addr1 := sdk.AccAddress([]byte("addr1_______________")) @@ -120,42 +120,35 @@ func (suite *IntegrationTestSuite) TestSendCoinsAndWei() { addr3 := sdk.AccAddress([]byte("addr3_______________")) require.NoError(keeper.SendCoinsFromModuleToAccount(ctx, authtypes.Minter, addr1, amt)) // should no-op if sending zero - require.NoError(keeper.SendCoinsAndWei(ctx, addr1, addr2, nil, sdk.DefaultBondDenom, sdk.ZeroInt(), sdk.ZeroInt())) + require.NoError(keeper.SendCoinsAndWei(ctx, addr1, addr2, sdk.ZeroInt(), sdk.ZeroInt())) require.Equal(sdk.ZeroInt(), keeper.GetWeiBalance(ctx, addr1)) require.Equal(sdk.ZeroInt(), keeper.GetWeiBalance(ctx, addr2)) require.Equal(sdk.NewInt(100), keeper.GetBalance(ctx, addr1, sdk.DefaultBondDenom).Amount) require.Equal(sdk.ZeroInt(), keeper.GetBalance(ctx, addr2, sdk.DefaultBondDenom).Amount) - require.Equal(sdk.ZeroInt(), keeper.GetBalance(ctx, authKeeper.GetModuleAddress(types.WeiEscrowName), sdk.DefaultBondDenom).Amount) // should just do usei send if wei is zero - require.NoError(keeper.SendCoinsAndWei(ctx, addr1, addr3, nil, sdk.DefaultBondDenom, sdk.NewInt(50), sdk.ZeroInt())) + require.NoError(keeper.SendCoinsAndWei(ctx, addr1, addr3, sdk.NewInt(50), sdk.ZeroInt())) require.Equal(sdk.ZeroInt(), keeper.GetWeiBalance(ctx, addr1)) require.Equal(sdk.ZeroInt(), keeper.GetWeiBalance(ctx, addr3)) require.Equal(sdk.NewInt(50), keeper.GetBalance(ctx, addr1, sdk.DefaultBondDenom).Amount) require.Equal(sdk.NewInt(50), keeper.GetBalance(ctx, addr3, sdk.DefaultBondDenom).Amount) - require.Equal(sdk.ZeroInt(), keeper.GetBalance(ctx, authKeeper.GetModuleAddress(types.WeiEscrowName), sdk.DefaultBondDenom).Amount) - // should return error if wei amount overflows - require.Error(keeper.SendCoinsAndWei(ctx, addr1, addr2, nil, sdk.DefaultBondDenom, sdk.ZeroInt(), sdk.NewInt(1_000_000_000_000))) // sender gets escrowed one usei, recipient does not get redeemed - require.NoError(keeper.SendCoinsAndWei(ctx, addr1, addr2, nil, sdk.DefaultBondDenom, sdk.NewInt(1), sdk.NewInt(1))) + require.NoError(keeper.SendCoinsAndWei(ctx, addr1, addr2, sdk.NewInt(1), sdk.NewInt(1))) require.Equal(sdk.NewInt(999_999_999_999), keeper.GetWeiBalance(ctx, addr1)) require.Equal(sdk.OneInt(), keeper.GetWeiBalance(ctx, addr2)) require.Equal(sdk.NewInt(48), keeper.GetBalance(ctx, addr1, sdk.DefaultBondDenom).Amount) require.Equal(sdk.OneInt(), keeper.GetBalance(ctx, addr2, sdk.DefaultBondDenom).Amount) - require.Equal(sdk.OneInt(), keeper.GetBalance(ctx, authKeeper.GetModuleAddress(types.WeiEscrowName), sdk.DefaultBondDenom).Amount) // sender does not get escrowed due to sufficient wei balance, recipient does not get redeemed - require.NoError(keeper.SendCoinsAndWei(ctx, addr1, addr3, nil, sdk.DefaultBondDenom, sdk.NewInt(1), sdk.NewInt(999_999_999_999))) + require.NoError(keeper.SendCoinsAndWei(ctx, addr1, addr3, sdk.NewInt(1), sdk.NewInt(999_999_999_999))) require.Equal(sdk.ZeroInt(), keeper.GetWeiBalance(ctx, addr1)) require.Equal(sdk.NewInt(999_999_999_999), keeper.GetWeiBalance(ctx, addr3)) require.Equal(sdk.NewInt(47), keeper.GetBalance(ctx, addr1, sdk.DefaultBondDenom).Amount) require.Equal(sdk.NewInt(51), keeper.GetBalance(ctx, addr3, sdk.DefaultBondDenom).Amount) - require.Equal(sdk.OneInt(), keeper.GetBalance(ctx, authKeeper.GetModuleAddress(types.WeiEscrowName), sdk.DefaultBondDenom).Amount) // sender gets escrowed and recipient gets redeemed - require.NoError(keeper.SendCoinsAndWei(ctx, addr1, addr3, nil, sdk.DefaultBondDenom, sdk.NewInt(1), sdk.NewInt(2))) + require.NoError(keeper.SendCoinsAndWei(ctx, addr1, addr3, sdk.NewInt(1), sdk.NewInt(2))) require.Equal(sdk.NewInt(999_999_999_998), keeper.GetWeiBalance(ctx, addr1)) require.Equal(sdk.NewInt(1), keeper.GetWeiBalance(ctx, addr3)) require.Equal(sdk.NewInt(45), keeper.GetBalance(ctx, addr1, sdk.DefaultBondDenom).Amount) require.Equal(sdk.NewInt(53), keeper.GetBalance(ctx, addr3, sdk.DefaultBondDenom).Amount) - require.Equal(sdk.OneInt(), keeper.GetBalance(ctx, authKeeper.GetModuleAddress(types.WeiEscrowName), sdk.DefaultBondDenom).Amount) } func (suite *IntegrationTestSuite) TestSupply() { diff --git a/x/bank/keeper/send.go b/x/bank/keeper/send.go index b08728e05..c9fe7a410 100644 --- a/x/bank/keeper/send.go +++ b/x/bank/keeper/send.go @@ -1,8 +1,6 @@ package keeper import ( - "errors" - "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/store/prefix" "github.com/cosmos/cosmos-sdk/telemetry" @@ -20,11 +18,11 @@ type SendKeeper interface { InputOutputCoins(ctx sdk.Context, inputs []types.Input, outputs []types.Output) error SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error SendCoinsWithoutAccCreation(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error - SendCoinsAndWei(ctx sdk.Context, from sdk.AccAddress, to sdk.AccAddress, customEscrow sdk.AccAddress, denom string, amt sdk.Int, wei sdk.Int) error + SendCoinsAndWei(ctx sdk.Context, from sdk.AccAddress, to sdk.AccAddress, amt sdk.Int, wei sdk.Int) error SubUnlockedCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins, checkNeg bool) error AddCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins, checkNeg bool) error - SubWei(ctx sdk.Context, addr sdk.AccAddress, customEscrow sdk.AccAddress, denom string, amt sdk.Int) error - AddWei(ctx sdk.Context, addr sdk.AccAddress, customEscrow sdk.AccAddress, denom string, amt sdk.Int) error + SubWei(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Int) error + AddWei(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Int) error GetParams(ctx sdk.Context) types.Params SetParams(ctx sdk.Context, params types.Params) @@ -36,7 +34,7 @@ type SendKeeper interface { } var _ SendKeeper = (*BaseSendKeeper)(nil) -var MaxWeiBalance sdk.Int = sdk.NewInt(1_000_000_000_000) +var OneUseiInWei sdk.Int = sdk.NewInt(1_000_000_000_000) // BaseSendKeeper only allows transfers between accounts without the possibility of // creating coins. It implements the SendKeeper interface. @@ -332,75 +330,59 @@ func (k BaseSendKeeper) BlockedAddr(addr sdk.AccAddress) bool { return k.blockedAddrs[addr.String()] } -func (k BaseSendKeeper) SubWei(ctx sdk.Context, addr sdk.AccAddress, customEscrow sdk.AccAddress, denom string, amt sdk.Int) error { +func (k BaseSendKeeper) SubWei(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Int) error { if amt.Equal(sdk.ZeroInt()) { return nil } - if amt.GTE(MaxWeiBalance) { - return errors.New("cannot send more than 10^12 wei") + currentWeiBalance := k.GetWeiBalance(ctx, addr) + if amt.LTE(currentWeiBalance) { + // no need to change usei balance + return k.setWeiBalance(ctx, addr, currentWeiBalance.Sub(amt)) } - escrow := customEscrow - if escrow == nil { - escrow = k.ak.GetModuleAddress(types.WeiEscrowName) + currentUseiBalance := k.GetBalance(ctx, addr, sdk.MustGetBaseDenom()).Amount + currentAggregatedBalance := currentUseiBalance.Mul(OneUseiInWei).Add(currentWeiBalance) + postAggregatedbalance := currentAggregatedBalance.Sub(amt) + if postAggregatedbalance.IsNegative() { + return sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, "%swei is smaller than %swei", currentAggregatedBalance, amt) } - currentWeiBalance := k.GetWeiBalance(ctx, addr) - postWeiBalance := currentWeiBalance.Sub(amt) - if postWeiBalance.GTE(sdk.ZeroInt()) { - if err := k.setWeiBalance(ctx, addr, postWeiBalance); err != nil { - return err - } - } else { - if err := k.setWeiBalance(ctx, addr, MaxWeiBalance.Add(postWeiBalance)); err != nil { - // postWeiBalanceFrom is negative - return err - } - // need to send one sei to escrow because wei balance is insufficient - if err := k.sendCoinsWithoutAccCreation(ctx, addr, escrow, sdk.NewCoins(sdk.NewCoin(denom, sdk.OneInt())), false); err != nil { - return err - } + useiBalance, weiBalance := SplitUseiWeiAmount(postAggregatedbalance) + if err := k.setBalance(ctx, addr, sdk.NewCoin(sdk.MustGetBaseDenom(), useiBalance), true); err != nil { + return err } - return nil + return k.setWeiBalance(ctx, addr, weiBalance) } -func (k BaseSendKeeper) AddWei(ctx sdk.Context, addr sdk.AccAddress, customEscrow sdk.AccAddress, denom string, amt sdk.Int) error { +func (k BaseSendKeeper) AddWei(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Int) error { if amt.Equal(sdk.ZeroInt()) { return nil } - if amt.GTE(MaxWeiBalance) { - return errors.New("cannot send more than 10^12 wei") - } - escrow := customEscrow - if escrow == nil { - escrow = k.ak.GetModuleAddress(types.WeiEscrowName) - } currentWeiBalance := k.GetWeiBalance(ctx, addr) postWeiBalance := currentWeiBalance.Add(amt) - if postWeiBalance.LT(MaxWeiBalance) { - if err := k.setWeiBalance(ctx, addr, postWeiBalance); err != nil { - return err - } - } else { - if err := k.setWeiBalance(ctx, addr, postWeiBalance.Sub(MaxWeiBalance)); err != nil { - return err - } - // need to redeem one sei from escrow because wei balance overflowed - one := sdk.NewCoins(sdk.NewCoin(denom, sdk.OneInt())) - if err := k.sendCoinsWithoutAccCreation(ctx, escrow, addr, one, false); err != nil { - return err - } + if postWeiBalance.LT(OneUseiInWei) { + // no need to change usei balance + return k.setWeiBalance(ctx, addr, postWeiBalance) } - return nil + currentUseiBalance := k.GetBalance(ctx, addr, sdk.MustGetBaseDenom()).Amount + useiCredit, weiBalance := SplitUseiWeiAmount(postWeiBalance) + if err := k.setBalance(ctx, addr, sdk.NewCoin(sdk.MustGetBaseDenom(), currentUseiBalance.Add(useiCredit)), true); err != nil { + return err + } + return k.setWeiBalance(ctx, addr, weiBalance) } -func (k BaseSendKeeper) SendCoinsAndWei(ctx sdk.Context, from sdk.AccAddress, to sdk.AccAddress, customEscrow sdk.AccAddress, denom string, amt sdk.Int, wei sdk.Int) error { - if err := k.SubWei(ctx, from, customEscrow, denom, wei); err != nil { +func (k BaseSendKeeper) SendCoinsAndWei(ctx sdk.Context, from sdk.AccAddress, to sdk.AccAddress, amt sdk.Int, wei sdk.Int) error { + if err := k.SubWei(ctx, from, wei); err != nil { return err } - if err := k.AddWei(ctx, to, customEscrow, denom, wei); err != nil { + if err := k.AddWei(ctx, to, wei); err != nil { return err } if amt.GT(sdk.ZeroInt()) { - return k.SendCoinsWithoutAccCreation(ctx, from, to, sdk.NewCoins(sdk.NewCoin(denom, amt))) + return k.SendCoinsWithoutAccCreation(ctx, from, to, sdk.NewCoins(sdk.NewCoin(sdk.MustGetBaseDenom(), amt))) } return nil } + +func SplitUseiWeiAmount(amt sdk.Int) (sdk.Int, sdk.Int) { + return amt.Quo(OneUseiInWei), amt.Mod(OneUseiInWei) +} diff --git a/x/bank/keeper/view.go b/x/bank/keeper/view.go index 7f835ab2b..3dbe99fd5 100644 --- a/x/bank/keeper/view.go +++ b/x/bank/keeper/view.go @@ -30,6 +30,7 @@ type ViewKeeper interface { IterateAccountBalances(ctx sdk.Context, addr sdk.AccAddress, cb func(coin sdk.Coin) (stop bool)) IterateAllBalances(ctx sdk.Context, cb func(address sdk.AccAddress, coin sdk.Coin) (stop bool)) + IterateAllWeiBalances(ctx sdk.Context, cb func(sdk.AccAddress, sdk.Int) bool) } // BaseViewKeeper implements a read only keeper implementation of ViewKeeper. @@ -247,3 +248,21 @@ func (k BaseViewKeeper) GetWeiBalance(ctx sdk.Context, addr sdk.AccAddress) sdk. } return *res } + +func (k BaseViewKeeper) IterateAllWeiBalances(ctx sdk.Context, cb func(sdk.AccAddress, sdk.Int) bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.WeiBalancesPrefix) + + iterator := store.Iterator(nil, nil) + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + val := new(sdk.Int) + if err := val.Unmarshal(iterator.Value()); err != nil { + // should never happen + panic(err) + } + if cb(iterator.Key(), *val) { + break + } + } +} diff --git a/x/bank/types/key.go b/x/bank/types/key.go index 146b30de1..97b8f1268 100644 --- a/x/bank/types/key.go +++ b/x/bank/types/key.go @@ -21,8 +21,6 @@ const ( // QuerierRoute defines the module's query routing key QuerierRoute = ModuleName - - WeiEscrowName = "weiescrow" ) // KVStore keys From c85968134d138f666cf26090e8e971febc810515 Mon Sep 17 00:00:00 2001 From: codchen Date: Tue, 27 Feb 2024 08:57:29 +0800 Subject: [PATCH 16/39] Add evm address to keys output (#442) Derive evm address from private key when showing keys in `seid keys show` and `seid keys list`. This only works for local keyring since it would have access to the private key Screen Shot 2024-02-26 at 11 18 43 AM Screen Shot 2024-02-26 at 11 18 35 AM --- .github/workflows/test.yml | 6 +- client/keys/codec_test.go | 16 +- client/keys/utils.go | 4 + crypto/keyring/output.go | 36 ++- crypto/keyring/output_test.go | 2 +- go.mod | 30 ++- go.sum | 479 +++++++++++++++++++++++++++------- 7 files changed, 455 insertions(+), 118 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1934ff94d..488279a01 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -24,7 +24,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: 1.19 + go-version: 1.21 - name: Create a file with all core Cosmos SDK pkgs run: go list ./... > pkgs.txt - name: Split pkgs into 10 files @@ -83,7 +83,7 @@ jobs: - uses: actions/setup-python@v3 - uses: actions/setup-go@v3 with: - go-version: 1.19 + go-version: 1.21 - uses: technote-space/get-diff-action@v6.1.0 with: PATTERNS: | @@ -118,7 +118,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: 1.19 + go-version: 1.21 # Download all coverage reports from the 'tests' job - name: Download coverage reports diff --git a/client/keys/codec_test.go b/client/keys/codec_test.go index f61792e60..9b78eebad 100644 --- a/client/keys/codec_test.go +++ b/client/keys/codec_test.go @@ -20,17 +20,17 @@ func getTestCases() testCases { return testCases{ // nolint:govet []keyring.KeyOutput{ - {"A", "B", "C", "D", "E"}, - {"A", "B", "C", "D", ""}, - {"", "B", "C", "D", ""}, - {"", "", "", "", ""}, + {"A", "B", "C", "", "D", "E"}, + {"A", "B", "C", "", "D", ""}, + {"", "B", "C", "", "D", ""}, + {"", "", "", "", "", ""}, }, make([]keyring.KeyOutput, 4), [][]byte{ - []byte(`{"name":"A","type":"B","address":"C","pubkey":"D","mnemonic":"E"}`), - []byte(`{"name":"A","type":"B","address":"C","pubkey":"D"}`), - []byte(`{"name":"","type":"B","address":"C","pubkey":"D"}`), - []byte(`{"name":"","type":"","address":"","pubkey":""}`), + []byte(`{"name":"A","type":"B","address":"C","evm_address":"","pubkey":"D","mnemonic":"E"}`), + []byte(`{"name":"A","type":"B","address":"C","evm_address":"","pubkey":"D"}`), + []byte(`{"name":"","type":"B","address":"C","evm_address":"","pubkey":"D"}`), + []byte(`{"name":"","type":"","address":"","evm_address":"","pubkey":""}`), }, } } diff --git a/client/keys/utils.go b/client/keys/utils.go index 775a6df69..05f11915e 100644 --- a/client/keys/utils.go +++ b/client/keys/utils.go @@ -25,6 +25,10 @@ func printKeyInfo(w io.Writer, keyInfo cryptokeyring.Info, bechKeyOut bechKeyOut if err != nil { panic(err) } + ko, err = cryptokeyring.PopulateEvmAddrIfApplicable(keyInfo, ko) + if err != nil { + panic(err) + } switch output { case OutputFormatText: diff --git a/crypto/keyring/output.go b/crypto/keyring/output.go index 91588e313..bb658be27 100644 --- a/crypto/keyring/output.go +++ b/crypto/keyring/output.go @@ -1,10 +1,14 @@ package keyring import ( + "encoding/hex" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/legacy" codectypes "github.com/cosmos/cosmos-sdk/codec/types" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/crypto" ) // TODO: Move this file to client/keys @@ -13,11 +17,12 @@ import ( // KeyOutput defines a structure wrapping around an Info object used for output // functionality. type KeyOutput struct { - Name string `json:"name" yaml:"name"` - Type string `json:"type" yaml:"type"` - Address string `json:"address" yaml:"address"` - PubKey string `json:"pubkey" yaml:"pubkey"` - Mnemonic string `json:"mnemonic,omitempty" yaml:"mnemonic"` + Name string `json:"name" yaml:"name"` + Type string `json:"type" yaml:"type"` + Address string `json:"address" yaml:"address"` + EvmAddress string `json:"evm_address" yaml:"evm_address"` + PubKey string `json:"pubkey" yaml:"pubkey"` + Mnemonic string `json:"mnemonic,omitempty" yaml:"mnemonic"` } // NewKeyOutput creates a default KeyOutput instance without Mnemonic, Threshold and PubKeys @@ -72,7 +77,28 @@ func MkAccKeysOutput(infos []Info) ([]KeyOutput, error) { if err != nil { return nil, err } + kos[i], err = PopulateEvmAddrIfApplicable(info, kos[i]) + if err != nil { + return nil, err + } } return kos, nil } + +func PopulateEvmAddrIfApplicable(info Info, o KeyOutput) (KeyOutput, error) { + localInfo, ok := info.(LocalInfo) + if ok { + priv, err := legacy.PrivKeyFromBytes([]byte(localInfo.PrivKeyArmor)) + if err != nil { + return o, err + } + privHex := hex.EncodeToString(priv.Bytes()) + privKey, err := crypto.HexToECDSA(privHex) + if err != nil { + return o, err + } + o.EvmAddress = crypto.PubkeyToAddress(privKey.PublicKey).Hex() + } + return o, nil +} diff --git a/crypto/keyring/output_test.go b/crypto/keyring/output_test.go index 8f28e8cd1..54a1e847e 100644 --- a/crypto/keyring/output_test.go +++ b/crypto/keyring/output_test.go @@ -26,5 +26,5 @@ func TestBech32KeysOutput(t *testing.T) { out, err := MkAccKeyOutput(info) require.NoError(t, err) require.Equal(t, expectedOutput, out) - require.Equal(t, `{Name:multisig Type:multi Address:cosmos1nf8lf6n4wa43rzmdzwe6hkrnw5guekhqt595cw PubKey:{"@type":"/cosmos.crypto.multisig.LegacyAminoPubKey","threshold":1,"public_keys":[{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AurroA7jvfPd1AadmmOvWM2rJSwipXfRf8yD6pLbA2DJ"}]} Mnemonic:}`, fmt.Sprintf("%+v", out)) + require.Equal(t, `{Name:multisig Type:multi Address:cosmos1nf8lf6n4wa43rzmdzwe6hkrnw5guekhqt595cw EvmAddress: PubKey:{"@type":"/cosmos.crypto.multisig.LegacyAminoPubKey","threshold":1,"public_keys":[{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AurroA7jvfPd1AadmmOvWM2rJSwipXfRf8yD6pLbA2DJ"}]} Mnemonic:}`, fmt.Sprintf("%+v", out)) } diff --git a/go.mod b/go.mod index aa5ac6836..001b4ef35 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -go 1.18 +go 1.21 module github.com/cosmos/cosmos-sdk @@ -15,6 +15,7 @@ require ( github.com/cosmos/iavl v0.21.0-alpha.1.0.20230904092046-df3db2d96583 github.com/cosmos/ledger-cosmos-go v0.12.2 github.com/deckarep/golang-set v1.8.0 + github.com/ethereum/go-ethereum v1.13.2 github.com/gogo/gateway v1.1.0 github.com/gogo/protobuf v1.3.3 github.com/golang/mock v1.6.0 @@ -55,8 +56,8 @@ require ( go.opentelemetry.io/otel/exporters/jaeger v1.9.0 go.opentelemetry.io/otel/sdk v1.9.0 go.opentelemetry.io/otel/trace v1.9.0 - golang.org/x/crypto v0.14.0 - golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb + golang.org/x/crypto v0.15.0 + golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa google.golang.org/genproto/googleapis/api v0.0.0-20230920204549-e6e6cdab5c13 google.golang.org/grpc v1.58.3 google.golang.org/protobuf v1.31.0 @@ -69,11 +70,12 @@ require ( github.com/DataDog/zstd v1.4.5 // indirect github.com/alitto/pond v1.8.3 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cockroachdb/errors v1.8.1 // indirect github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f // indirect - github.com/cockroachdb/pebble v0.0.0-20230819001538-1798fbf5956c // indirect + github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 // indirect github.com/cockroachdb/redact v1.0.8 // indirect github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect @@ -81,6 +83,7 @@ require ( github.com/creachadair/taskgroup v0.3.2 // indirect github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // 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.1 // indirect @@ -97,10 +100,9 @@ require ( github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/golang/glog v1.1.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/snappy v0.0.4 // indirect + github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/flatbuffers v1.12.1 // indirect github.com/google/go-cmp v0.5.9 // indirect - github.com/google/gofuzz v1.2.0 // indirect github.com/google/orderedcode v0.0.1 // indirect github.com/google/uuid v1.3.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect @@ -109,6 +111,7 @@ require ( github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/holiman/uint256 v1.2.4 // indirect github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/jmhodges/levigo v1.0.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect @@ -148,13 +151,13 @@ require ( github.com/zondax/ledger-go v0.14.1 // indirect go.etcd.io/bbolt v1.3.7 // indirect go.opencensus.io v0.23.0 // indirect - golang.org/x/mod v0.11.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/sync v0.4.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/term v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect - golang.org/x/tools v0.6.0 // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/net v0.18.0 // indirect + golang.org/x/sync v0.5.0 // indirect + golang.org/x/sys v0.14.0 // indirect + golang.org/x/term v0.14.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/tools v0.15.0 // indirect google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a // indirect gopkg.in/ini.v1 v1.67.0 // indirect @@ -176,6 +179,7 @@ replace ( github.com/99designs/keyring => github.com/cosmos/keyring v1.1.7-0.20210622111912-ef00f8ac3d76 github.com/confio/ics23/go => github.com/cosmos/cosmos-sdk/ics23/go v0.8.0 github.com/cosmos/iavl => github.com/sei-protocol/sei-iavl v0.1.9 + github.com/ethereum/go-ethereum => github.com/sei-protocol/go-ethereum v1.13.5-sei-8 // Fix upstream GHSA-h395-qcrw-5vmq vulnerability. // TODO Remove it: https://github.com/cosmos/cosmos-sdk/issues/10409 github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.7.0 diff --git a/go.sum b/go.sum index 33040f742..768c06703 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,4 @@ +cloud.google.com/go v0.0.0-20170206221025-ce650573d812/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= @@ -39,22 +40,26 @@ cosmossdk.io/errors v1.0.0/go.mod h1:+hJZLuhdDE0pYN8HkOrVNwrIOYvUGnn6+4fjnJs/oV0 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU= filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= +gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= -github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= -github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= -github.com/Azure/azure-storage-blob-go v0.7.0/go.mod h1:f9YQKtsG1nMisotuTPpO0tjNuEjKRYAcJU8/ydDI++4= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.0.0/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.0.0/go.mod h1:+6sju8gk8FRmSajX3Oz4G5Gm7P+mbqE9FVaXXFYTkCM= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.0.0/go.mod h1:ceIuwmxDWptoW3eCqSXlnPsZFKh4X+R38dWPv7GS9Vs= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.0.0/go.mod h1:s1tW/At+xHqjNFvWU4G0c0Qv33KOhvbGNj0RCTQDV8s= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.2.0/go.mod h1:c+Lifp3EDEamAkPVzMooRNOK6CZjNSdEnf1A7jsI9u4= +github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0/go.mod h1:+6KLcKIVgxoBDMqMO/Nvy7bZ9a0nbU3I1DtFQK3YvB4= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= -github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= -github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= -github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= -github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= -github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= -github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= -github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= -github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/AzureAD/microsoft-authentication-library-for-go v0.4.0/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4= +github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= @@ -62,25 +67,34 @@ github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3 github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20190129172621-c8b1d7a94ddf/go.mod h1:aJ4qN3TfrelA6NZ6AXsXRfmEVaYin3EDbSPJrKS8OXo= +github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8= +github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= +github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20201201074141-dd0ecada1be6/go.mod h1:eSYp2T6f0apnuW8TzhV3f6Aff2SE8Dwio++U4ha4yEM= +github.com/aclements/go-gg v0.0.0-20170118225347-6dbb4e4fefb0/go.mod h1:55qNq4vcpkIuHowELi5C8e+1yUHtoLoOUR9QU5j7Tes= +github.com/aclements/go-moremath v0.0.0-20210112150236-f10218a38794/go.mod h1:7e+I0LQFUI9AXWxOfsQROs9xPhoJtbsyWcjJqDd4KPY= github.com/adlio/schema v1.3.0 h1:eSVYLxYWbm/6ReZBCkLw4Fz7uqC+ZNoPvA39bOwi52A= +github.com/adlio/schema v1.3.0/go.mod h1:51QzxkpeFs6lRY11kPye26IaFPOV+HqEj01t5aXXKfs= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= +github.com/ajstarks/svgo v0.0.0-20210923152817-c3b6e2f0c527/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -92,7 +106,6 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -101,9 +114,21 @@ github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/aws/aws-sdk-go-v2 v1.21.2/go.mod h1:ErQhvNuEMhJjweavOYhxVkn2RUx7kQXVATHrjKtxIpM= +github.com/aws/aws-sdk-go-v2/config v1.18.45/go.mod h1:ZwDUgFnQgsazQTnWfeLWk5GjeqTQTL8lMkoE1UXzxdE= +github.com/aws/aws-sdk-go-v2/credentials v1.13.43/go.mod h1:zWJBz1Yf1ZtX5NGax9ZdNjhhI4rgjfgsyk6vTY1yfVg= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.13/go.mod h1:f/Ib/qYjhV2/qdsf79H3QP/eRE4AkVyEf6sk7XfZ1tg= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43/go.mod h1:auo+PiyLl0n1l8A0e8RIeR8tOzYPfZZH/JNlrJ8igTQ= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.37/go.mod h1:Qe+2KtKml+FEsQF/DHmDV+xjtche/hwoF75EG4UlHW8= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.45/go.mod h1:lD5M20o09/LCuQ2mE62Mb/iSdSlCNuj6H5ci7tW7OsE= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.37/go.mod h1:vBmDnwWXWxNPFRMmG2m/3MKOe+xEcMDo1tanpaWCcck= +github.com/aws/aws-sdk-go-v2/service/route53 v1.30.2/go.mod h1:TQZBt/WaQy+zTHoW++rnl8JBrmZ0VO6EUbVua1+foCA= +github.com/aws/aws-sdk-go-v2/service/sso v1.15.2/go.mod h1:gsL4keucRCgW+xA85ALBpRFfdSLH4kHOVSnLMSuBECo= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.3/go.mod h1:a7bHA82fyUXOm+ZSWKU6PIoBxrjSprdLoM8xPYvzYVg= +github.com/aws/aws-sdk-go-v2/service/sts v1.23.2/go.mod h1:Eows6e1uQEsc4ZaHANmsPRzAKcVDrcmjjWiih2+HUUQ= +github.com/aws/smithy-go v1.15.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -111,19 +136,27 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ= +github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bits-and-blooms/bitset v1.7.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/btcsuite/btcd v0.0.0-20190315201642-aa6e0f35703c/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94= github.com/btcsuite/btcd v0.22.1 h1:CnwP9LM/M9xuRrGSCGeMVs9iv09uMqwsVX7EeIpgV2c= github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= +github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= +github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= 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/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= +github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= @@ -139,26 +172,31 @@ github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= -github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U= +github.com/cloudflare/cloudflare-go v0.79.0/go.mod h1:gkHQf9xEubaQPEuerBuoinR9P8bf8a05Lq0X6WKy1Oc= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/cockroachdb/datadriven v1.0.0/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/errors v1.6.1/go.mod h1:tm6FTP5G81vwJ5lC0SizQo374JNCOPrHyXGitRJoDqM= github.com/cockroachdb/errors v1.8.1 h1:A5+txlVZfOqFBDa4mGz2bUWSp0aHElvHX2bKkdbQu+Y= github.com/cockroachdb/errors v1.8.1/go.mod h1:qGwQn6JmZ+oMjuLwjWzUNqblqk0xl4CVV3SQbGwK7Ac= github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f h1:o/kfcElHqOiXqcou5a3rIlMc7oJbMQkeLk0VQJ7zgqY= github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= -github.com/cockroachdb/pebble v0.0.0-20230819001538-1798fbf5956c h1:aDetJlMe4qJxWAwu+/bzTs2/b1EW9ecVyawpRD7N/tE= -github.com/cockroachdb/pebble v0.0.0-20230819001538-1798fbf5956c/go.mod h1:EDjiaAXc0FXiRmxDzcu1wIEJ093ohHMUWxrI6iku0XA= +github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 h1:aPEJyR4rPBvDmeyi+l/FS/VtA00IWvjeFvjen1m1l1A= +github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593/go.mod h1:6hk1eMY/u5t+Cf18q5lFMUA1Rc+Sm5I6Ra1QuPyxXCo= github.com/cockroachdb/redact v1.0.8 h1:8QG/764wK+vmEYoOlfobpe12EQcS81ukx/a4hdVMxNw= github.com/cockroachdb/redact v1.0.8/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2 h1:IKgmqgMQlVJIZj19CdocBeSfSaiCbEBZGKODaixqtHM= @@ -169,13 +207,20 @@ github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/coinbase/rosetta-sdk-go v0.7.0 h1:lmTO/JEpCvZgpbkOITL95rA80CPKb5CtMzLaqF2mCNg= github.com/coinbase/rosetta-sdk-go v0.7.0/go.mod h1:7nD3oBPIiHqhRprqvMgPoGxe/nyq3yftRmpsy29coWE= +github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= +github.com/consensys/gnark-crypto v0.10.0/go.mod h1:Iq/P3HHl0ElSjsg2E1gsMwhAyxnxoKK5nVyZKd+/KhU= +github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= github.com/containerd/continuity v0.2.1 h1:/EeEo2EtN3umhbbgCveyjifoMYg0pS+nMMEemaYw634= +github.com/containerd/continuity v0.2.1/go.mod h1:wCYX+dRqZdImhGucXOqTQn05AhX6EUDaGEMUzTFFpLg= +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= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= github.com/cosmos/cosmos-sdk/ics23/go v0.8.0 h1:iKclrn3YEOwk4jQHT2ulgzuXyxmzmPczUalMwW4XH9k= @@ -190,11 +235,15 @@ github.com/cosmos/ledger-cosmos-go v0.12.2 h1:/XYaBlE2BJxtvpkHiBm97gFGSGmYGKunKy github.com/cosmos/ledger-cosmos-go v0.12.2/go.mod h1:ZcqYgnfNJ6lAXe4HPtWgarNEY+B74i+2/8MhZw4ziiI= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= +github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= github.com/creachadair/taskgroup v0.3.2 h1:zlfutDS+5XG40AOxcHDSThxKzns8Tnr9jnr6VqkYlkM= github.com/creachadair/taskgroup v0.3.2/go.mod h1:wieWwecHVzsidg2CsUnFinW1faVN4+kq+TDlRJQ0Wbk= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U= github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= @@ -202,11 +251,15 @@ github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= +github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= +github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= 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 v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= @@ -223,11 +276,18 @@ github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUn 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/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= +github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= -github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= +github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= +github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= @@ -235,47 +295,63 @@ github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+m github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= -github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= 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= -github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= -github.com/ethereum/go-ethereum v1.9.25/go.mod h1:vMkFiYLHI4tgPw4k2j4MHKoovchFE8plZ0M9VMk4/oM= +github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= +github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= +github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= +github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= -github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e/go.mod h1:AzA8Lj6YtixmJWL+wkKoBGsLWy9gFrAzi4g+5bCKwpY= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= +github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= +github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= +github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= +github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9/go.mod h1:106OIgooyS7OzLDOpUGgm9fA3bQENb/cFSyyBmMoJDs= 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.7.0 h1:jGB9xAJQ12AIGNB4HguylppmDK1Am9ppF7XnGXXJuoU= github.com/gin-gonic/gin v1.7.0/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= +github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= +github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= +github.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= +github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -284,8 +360,11 @@ github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U= +github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= @@ -297,7 +376,10 @@ github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= -github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= +github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= 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/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= @@ -305,26 +387,36 @@ github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD87 github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= -github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= 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/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/gateway v1.1.0 h1:u0SuhL9+Il+UbjM9VIE3ntfRujKbvVpFvNB4HbjeVQ0= github.com/gogo/gateway v1.1.0/go.mod h1:S7rR8FRQyG3QFESeSv4l2WnsyzlCLG0CzBbUUo/mbic= github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= +github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= 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= @@ -354,15 +446,22 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 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.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3-0.20201103224600-674baa8c7fc3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 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/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= +github.com/gonum/blas v0.0.0-20181208220705-f22b278b28ac/go.mod h1:P32wAyui1PQ58Oce/KYkOqQv8cVw1zAapXOl+dRFGbc= +github.com/gonum/floats v0.0.0-20181209220543-c233463c7e82/go.mod h1:PxC8OnwL11+aosOB5+iEPoV3picfs8tUpkVd0pDo+Kg= +github.com/gonum/internal v0.0.0-20181124074243-f884aa714029/go.mod h1:Pu4dmpkhSyOzRwuXkOgAvijx4o+4YMUJJo9OvPYMkks= +github.com/gonum/lapack v0.0.0-20181123203213-e4cdc5a0bff9/go.mod h1:XA3DeT6rxh2EAE789SSiSJNqxPaC0aE9J8NTOI0Jo/A= +github.com/gonum/matrix v0.0.0-20181209220409-c518dec07be9/go.mod h1:0EXg4mc1CNP0HCqCz+K4ts155PXIlUywf0wqN+GfPZw= 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/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= @@ -380,12 +479,13 @@ 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.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -403,13 +503,17 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= +github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= +github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/safehtml v0.0.2/go.mod h1:L4KWwDsUJdECRAEpZoBn3O64bQaywRscowZjJAzjHnU= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go v0.0.0-20161107002406-da06d194a00e/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= @@ -423,11 +527,12 @@ github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= 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-0.20190629185528-ae1634f6a989/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +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-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= @@ -435,22 +540,29 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +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-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= +github.com/guptarohit/asciigraph v0.5.5/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= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= @@ -461,7 +573,6 @@ github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09 github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru/v2 v2.0.1 h1:5pv5N1lT1fjLg2VQ5KWc7kmucp2x/kvFOnxuVTqZ6x4= @@ -474,28 +585,33 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 h1:aSVUgRRRtOrZOC1fYmY9gV0e9z/Iu+xNVSASWjsuyGU= github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3/go.mod h1:5PC6ZNPde8bBqU/ewGZig35+UIZtw9Ytxez8/q5ZyFE= -github.com/holiman/uint256 v1.1.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= +github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= +github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= +github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= -github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/improbable-eng/grpc-web v0.14.1 h1:NrN4PY71A6tAz2sKDvC5JCauENWp0ykG8Oq1H3cpFvw= github.com/improbable-eng/grpc-web v0.14.1/go.mod h1:zEjGHa8DAlkoOXmswrNvhUGEYQA9UI7DhrGeHR1DMGU= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= +github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= -github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= -github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267/go.mod h1:h1nSAbGFqGVzn6Jyl1R/iCcBUHN4g+gW1u9CoBTrb9E= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jhump/gopoet v0.0.0-20190322174617-17282ff210b3/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= @@ -505,6 +621,8 @@ github.com/jhump/protoreflect v1.11.0/go.mod h1:U7aMIjN0NWq9swDP7xDdoMfRHb35uiuT github.com/jhump/protoreflect v1.12.1-0.20220417024638-438db461d753 h1:uFlcJKZPLQd7rmOY/RrvBuUaYmAFnlFHKLivhO6cOy8= github.com/jhump/protoreflect v1.12.1-0.20220417024638-438db461d753/go.mod h1:JytZfP5d0r8pVNLZvai7U/MCuTWITgrI4tTg7puQFKI= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= @@ -515,18 +633,21 @@ github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= -github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= -github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= +github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= @@ -535,6 +656,7 @@ github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNU github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d h1:Z+RDyXzjKE0i2sTjZ/b1uxiGtPhFy34Ou/Tk0qwN0kM= github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d/go.mod h1:JJNrCn9otv/2QP4D7SMJBgaleKpOf66PnW6F5WGNRIc= +github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= @@ -543,6 +665,7 @@ github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0 github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY= github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= @@ -552,15 +675,20 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/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/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= +github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/ledgerwatch/erigon-lib v0.0.0-20230210071639-db0e7ed11263 h1:LGEzZvf33Y1NhuP5+jI/ni9l1TFS6oYPDilgy74NusM= github.com/ledgerwatch/erigon-lib v0.0.0-20230210071639-db0e7ed11263/go.mod h1:OXgMDuUo2lZ3NpH29ZvMYbk+LxFd5ffDl2Z2mGMuY/I= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= @@ -577,31 +705,39 @@ github.com/lucasjones/reggen v0.0.0-20180717132126-cdb49ff09d77/go.mod h1:5ELEyG github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= 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-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= -github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= 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.5-0.20180830101745-3fb116b82035/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.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +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.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= +github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= @@ -617,14 +753,22 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0Qu github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= +github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= +github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= +github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= +github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= @@ -653,10 +797,10 @@ github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtb 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/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= 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.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= @@ -666,10 +810,14 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= +github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= +github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/runc v1.0.3 h1:1hbqejyQWCJBvtKAfdO0b1FmaEf2z/bxnjqbARass5k= +github.com/opencontainers/runc v1.0.3/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -679,11 +827,11 @@ github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJ github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= +github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= 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.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= @@ -695,10 +843,15 @@ github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssy github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 h1:hDSdbBuw3Lefr6R18ax0tZ2BJeNB3NehB3trOwYBsdU= github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= +github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= +github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= 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= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -709,12 +862,16 @@ github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qR github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= 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.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -723,26 +880,34 @@ github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1: github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= 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.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= 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.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= -github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7/go.mod h1:IToEjHuttnUzwZI5KBSM/LOOW3qLbbrHOEfp3SbECGY= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= @@ -753,24 +918,26 @@ github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= -github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U= github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= -github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c= github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w= 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/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= +github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= @@ -781,6 +948,8 @@ github.com/savaki/jq v0.0.0-20161209013833-0e6baecebbf8/go.mod h1:Nw/CCOXNyF5JDd github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= +github.com/sei-protocol/go-ethereum v1.13.5-sei-8 h1:z6rUvSgLXtXQBdF1dOe8A1iDFORz0+ObH2H1qM5FQKE= +github.com/sei-protocol/go-ethereum v1.13.5-sei-8/go.mod h1:kcRZmuzRn1lVejiFNTz4l4W7imnpq1bDAnuKS/RyhbQ= github.com/sei-protocol/sei-db v0.0.31 h1:UW9skaXnaXfi9mp60EbAJ2ijyr1Hnu9WYatMNrhXfjE= github.com/sei-protocol/sei-db v0.0.31/go.mod h1:F/ZKZA8HJPcUzSZPA8yt6pfwlGriJ4RDR4eHKSGLStI= github.com/sei-protocol/sei-iavl v0.1.9 h1:y4mVYftxLNRs6533zl7N0/Ch+CzRQc04JDfHolIxgBE= @@ -790,13 +959,14 @@ github.com/sei-protocol/sei-tendermint v0.2.38-evm-rebase/go.mod h1:4LSlJdhl3nf3 github.com/sei-protocol/sei-tm-db v0.0.5 h1:3WONKdSXEqdZZeLuWYfK5hP37TJpfaUa13vAyAlvaQY= github.com/sei-protocol/sei-tm-db v0.0.5/go.mod h1:Cpa6rGyczgthq7/0pI31jys2Fw0Nfrc+/jKdP1prVqY= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/shirou/gopsutil v2.20.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -812,6 +982,8 @@ github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= @@ -822,11 +994,10 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn 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.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.13.0 h1:BWSJ/M+f+3nmdz9bxB+bWX28kkALN2ok11D0rSo8EJU= github.com/spf13/viper v1.13.0/go.mod h1:Icm2xNL3/8uyh/wFuB1jI7TiTNKp8632Nwegu+zgdYw= -github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= -github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw= -github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU= +github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= @@ -843,12 +1014,15 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs= github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tendermint/btcd v0.1.1 h1:0VcxPfflS2zZ3RiOAHkBiFUcPvbtRj5O7zHmcJWHV7s= @@ -860,6 +1034,7 @@ github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoM github.com/tendermint/tm-db v0.6.8-0.20220519162814-e24b96538a12 h1:unOeFDC/TV4Oh371XZGmZyfeIzeGfK/JINb0T+6C+QY= github.com/tendermint/tm-db v0.6.8-0.20220519162814-e24b96538a12/go.mod h1:PWsIWOTwdwC7Ow/GUvx8HgUJTO691pBuorIQD8JvwAs= github.com/tidwall/btree v1.6.0 h1:LDZfKfQIBHGHWSwckhXI0RPSXzlo+KYdjK7FWSqOzzg= +github.com/tidwall/btree v1.6.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= github.com/tidwall/gjson v1.6.7/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI= github.com/tidwall/gjson v1.10.2 h1:APbLGOM0rrEkd8WBw9C24nllro4ajFuJu0Sc9hRz8Bo= github.com/tidwall/gjson v1.10.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= @@ -874,10 +1049,14 @@ github.com/tidwall/tinylru v1.1.0 h1:XY6IUfzVTU9rpwdhKUF6nQdChgCdGjkMfLzbWyiau6I github.com/tidwall/tinylru v1.1.0/go.mod h1:3+bX+TJ2baOLMWTnlyNWHh4QMnFyARg2TLTQ6OFbzw8= github.com/tidwall/wal v1.1.7 h1:emc1TRjIVsdKKSnpwGBAcsAGg0767SvUk8+ygx7Bb+4= github.com/tidwall/wal v1.1.7/go.mod h1:r6lR1j27W9EPalgHiB7zLJDYu3mzW5BQP5KrzBpYY/E= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= 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/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= +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/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= @@ -885,19 +1064,22 @@ 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/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/v2 v2.24.1/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= +github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/vmihailenco/msgpack/v5 v5.1.4/go.mod h1:C5gboKD0TJPqWDTVTtrQNfRbiBwHZGo8UTqP/9/XvLI= github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= -github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/ybbus/jsonrpc v2.1.2+incompatible/go.mod h1:XJrh1eMSzdIYFbM08flv0wp5G35eRniyeGut1z+LSiE= github.com/yourbasic/graph v0.0.0-20210606180040-8ecfec1c2869 h1:7v7L5lsfw4w8iqBBXETukHo4IPltmD+mWoLRYUmeGN8= @@ -910,12 +1092,15 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 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.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zbiljic/go-filelock v0.0.0-20170914061330-1dbf7103ab7d h1:XQyeLr7N9iY9mi+TGgsBFkj54+j3fdoo8e2u6zrGP5A= github.com/zbiljic/go-filelock v0.0.0-20170914061330-1dbf7103ab7d/go.mod h1:hoMeDjlNXTNqVwrCk8YDyaBS2g5vFfEX2ezMi4vb6CY= github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c= github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320= +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/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= @@ -941,6 +1126,7 @@ go.opentelemetry.io/otel/trace v1.9.0/go.mod h1:2737Q0MuG8q1uILYm2YYVkAyLtOofiTN go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= @@ -955,7 +1141,6 @@ golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -964,14 +1149,27 @@ golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA= +golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= +golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= @@ -979,10 +1177,21 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb h1:mIKbk8weKhSeLH2GmUTrvx8CjkyJmnU1wFmg59CUjFA= -golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/exp v0.0.0-20220426173459-3bcf042a4bf5/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= +golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= +golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -995,23 +1204,27 @@ golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPI golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mobile v0.0.0-20200801112145-973feb4309de/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1024,6 +1237,7 @@ golang.org/x/net v0.0.0-20190327091125-710a502c58a2/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= @@ -1049,15 +1263,30 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg= +golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= +golang.org/x/oauth2 v0.0.0-20170207211851-4464e7848382/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1067,6 +1296,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/perf v0.0.0-20230113213139-801c7ef9e5c5/go.mod h1:UBKtEnL8aqnd+0JHqZ+2qoMDwtuy6cYhhKNoHLBiTQc= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1078,8 +1309,11 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +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.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1103,8 +1337,10 @@ golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/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-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1130,33 +1366,62 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/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-20210819135213-f52c844e1c1c/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-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/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-20220715151400-c0bba94af5f8/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.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/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.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +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.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8= +golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1164,14 +1429,29 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 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= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -1186,6 +1466,7 @@ golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgw 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-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/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= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1193,11 +1474,11 @@ golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191126055441-b0650ceb63d9/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1226,12 +1507,25 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8= +golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= +gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= +gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY= +gonum.org/v1/plot v0.10.0/go.mod h1:JWIHJ7U20drSQb/aDpTetJzfC1KlAPldJLpkSy88dvQ= +google.golang.org/api v0.0.0-20170206182103-3d017632ea10/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -1322,14 +1616,17 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -1337,12 +1634,10 @@ gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= -gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= -gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1356,6 +1651,7 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= @@ -1374,7 +1670,9 @@ modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0= modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw= modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY= modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk= +modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM= +modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= modernc.org/libc v1.24.1 h1:uvJSeCKL/AgzBo2yYIPPTy82v21KgGnizcGYfBHaNuM= modernc.org/libc v1.24.1/go.mod h1:FmfO1RLrU3MHJfyi9eYYmZBfi/R+tqZ6+hQ3yQQUkak= modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ= @@ -1388,14 +1686,19 @@ modernc.org/sqlite v1.26.0/go.mod h1:FL3pVXie73rg3Rii6V/u5BoHlSoyeZeIgKZEgHARyCU modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= modernc.org/tcl v1.15.2 h1:C4ybAYCGJw968e+Me18oW55kD/FexcHbqH2xak1ROSY= +modernc.org/tcl v1.15.2/go.mod h1:3+k/ZaEbKrC8ePv8zJWPtBSW0V7Gg9g8rkmhI1Kfs3c= modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg= modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/z v1.7.3 h1:zDJf6iHjrnB+WRD88stbXokugjyc0/pB91ri1gO6LZY= +modernc.org/z v1.7.3/go.mod h1:Ipv4tsdxZRbQyLq9Q1M6gdbkxYzdlrciF2Hi/lS7nWE= nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= pgregory.net/rapid v0.4.7 h1:MTNRktPuv5FNqOO151TM9mDTa+XHcX6ypYeISDVD14g= +pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= 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= +rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= From 11cfa1c1b56bed927c1a57162730f2b27108ebd0 Mon Sep 17 00:00:00 2001 From: codchen Date: Tue, 27 Feb 2024 23:57:19 +0800 Subject: [PATCH 17/39] Amplify cosmos tx priority (#443) ## Describe your changes and provide context Since EVM transactions specify gas price in unit of wei, we have started representing priority of EVM transactions in wei-per-gas. In order for cosmos transactions' priority to be comparable with EVM transactions', we would like to use the same unit for priority here as well. Hence in this PR we amplify cosmos transaction priority by 10^12 (if the original priority is based on the base denom aka usei) ## Testing performed to validate your change unit test --- x/auth/ante/validator_tx_fee.go | 18 ++++++++++++++---- x/auth/ante/validator_tx_fee_test.go | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/x/auth/ante/validator_tx_fee.go b/x/auth/ante/validator_tx_fee.go index 948831b27..65f33cf34 100644 --- a/x/auth/ante/validator_tx_fee.go +++ b/x/auth/ante/validator_tx_fee.go @@ -8,6 +8,8 @@ import ( paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" ) +var BaseDenomGasPriceAmplfier = sdk.NewInt(1_000_000_000_000) + // checkTxFeeWithValidatorMinGasPrices implements the default fee logic, where the minimum price per // unit of gas is fixed and set by each validator, can the tx priority is computed from the gas price. func CheckTxFeeWithValidatorMinGasPrices(ctx sdk.Context, tx sdk.Tx, simulate bool, paramsKeeper paramskeeper.Keeper) (sdk.Coins, int64, error) { @@ -46,7 +48,7 @@ func CheckTxFeeWithValidatorMinGasPrices(ctx sdk.Context, tx sdk.Tx, simulate bo // realistically, if the gas limit IS set to 0, the tx will run out of gas anyways. priority := int64(0) if gas > 0 { - priority = getTxPriority(feeCoins, int64(gas)) + priority = GetTxPriority(feeCoins, int64(gas)) } return feeCoins, priority, nil } @@ -55,15 +57,23 @@ func GetMinimumGasPricesWantedSorted(globalMinimumGasPrices, validatorMinimumGas return globalMinimumGasPrices.UnionMax(validatorMinimumGasPrices).Sort() } -// getTxPriority returns a naive tx priority based on the amount of the smallest denomination of the gas price +// GetTxPriority returns a naive tx priority based on the amount of the smallest denomination of the gas price // provided in a transaction. +// If base denom is used as fee, the calculated gas price will be amplified by 10^12 to capture higher precision +// in priority differences. // NOTE: This implementation should be used with a great consideration as it opens potential attack vectors // where txs with multiple coins could not be prioritize as expected. -func getTxPriority(fee sdk.Coins, gas int64) int64 { +func GetTxPriority(fee sdk.Coins, gas int64) int64 { var priority int64 + baseDenom, err := sdk.GetBaseDenom() for _, c := range fee { p := int64(math.MaxInt64) - gasPrice := c.Amount.QuoRaw(gas) + var gasPrice sdk.Int + if err == nil && baseDenom == c.Denom { + gasPrice = c.Amount.Mul(BaseDenomGasPriceAmplfier).QuoRaw(gas) + } else { + gasPrice = c.Amount.QuoRaw(gas) + } if gasPrice.IsInt64() { p = gasPrice.Int64() } diff --git a/x/auth/ante/validator_tx_fee_test.go b/x/auth/ante/validator_tx_fee_test.go index b75e8dcf4..e8d795f62 100644 --- a/x/auth/ante/validator_tx_fee_test.go +++ b/x/auth/ante/validator_tx_fee_test.go @@ -79,3 +79,22 @@ func TestGetMinimumGasWanted(t *testing.T) { require.True(t, expectedMinGasWanted.IsEqual(minGasWanted)) } + +func TestGetTxPriority(t *testing.T) { + sdk.RegisterDenom("test", sdk.NewDecWithPrec(1, 6)) + require.Equal( + t, + int64(0), + ante.GetTxPriority(sdk.NewCoins(), 1000), + ) + require.Equal( + t, + int64(1_000_000_000), + ante.GetTxPriority(sdk.NewCoins(sdk.NewCoin("test", sdk.NewInt(1))), 1000), + ) + require.Equal( + t, + int64(0), + ante.GetTxPriority(sdk.NewCoins(sdk.NewCoin("test", sdk.NewInt(1))), 10_000_000_000_000), // gas too large + ) +} From b2e7486194d875a0b323357fc0ed3e369f08fad5 Mon Sep 17 00:00:00 2001 From: Uday Patil Date: Mon, 8 Jan 2024 15:10:23 -0600 Subject: [PATCH 18/39] occ-evm compatibility changes --- tasks/scheduler.go | 12 ++++++++---- types/tx_batch.go | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/tasks/scheduler.go b/tasks/scheduler.go index 22da1696f..e65843d20 100644 --- a/tasks/scheduler.go +++ b/tasks/scheduler.go @@ -51,6 +51,8 @@ type deliverTxTask struct { Index int Incarnation int Request types.RequestDeliverTx + SdkTx sdk.Tx + Checksum [32]byte Response *types.ResponseDeliverTx VersionStores map[sdk.StoreKey]*multiversion.VersionIndexedStore } @@ -94,7 +96,7 @@ type Scheduler interface { } type scheduler struct { - deliverTx func(ctx sdk.Context, req types.RequestDeliverTx) (res types.ResponseDeliverTx) + deliverTx func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res types.ResponseDeliverTx) workers int multiVersionStores map[sdk.StoreKey]multiversion.MultiVersionStore tracingInfo *tracing.Info @@ -107,7 +109,7 @@ type scheduler struct { } // NewScheduler creates a new scheduler -func NewScheduler(workers int, tracingInfo *tracing.Info, deliverTxFunc func(ctx sdk.Context, req types.RequestDeliverTx) (res types.ResponseDeliverTx)) Scheduler { +func NewScheduler(workers int, tracingInfo *tracing.Info, deliverTxFunc func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res types.ResponseDeliverTx)) Scheduler { return &scheduler{ workers: workers, deliverTx: deliverTxFunc, @@ -179,9 +181,11 @@ func toTasks(reqs []*sdk.DeliverTxEntry) []*deliverTxTask { for idx, r := range reqs { res = append(res, &deliverTxTask{ Request: r.Request, + SdkTx: r.SdkTx, + Checksum: r.Checksum, Index: idx, - Dependencies: map[int]struct{}{}, Status: statusPending, + Dependencies: map[int]struct{}{}, }) } return res @@ -515,7 +519,7 @@ func (s *scheduler) executeTask(task *deliverTxTask) { s.prepareTask(task) - resp := s.deliverTx(task.Ctx, task.Request) + resp := s.deliverTx(task.Ctx, task.Request, task.SdkTx, task.Checksum) // if an abort occurred, we want to handle that at this level if resp.Codespace == errors.ErrOCCAbort.Codespace() && resp.Code == errors.ErrOCCAbort.ABCICode() { diff --git a/types/tx_batch.go b/types/tx_batch.go index b053aa5fa..0199306c8 100644 --- a/types/tx_batch.go +++ b/types/tx_batch.go @@ -9,6 +9,8 @@ import ( // This can be extended to include tx-level tracing or metadata type DeliverTxEntry struct { Request abci.RequestDeliverTx + SdkTx Tx + Checksum [32]byte EstimatedWritesets MappedWritesets } From 23a17a2ba8b301eb455fd2bcd570bdbe4e42dc5d Mon Sep 17 00:00:00 2001 From: Uday Patil Date: Tue, 9 Jan 2024 15:24:57 -0600 Subject: [PATCH 19/39] update generate estimated writeset for evm compatibility --- x/accesscontrol/keeper/keeper.go | 6 +----- x/accesscontrol/keeper/keeper_test.go | 4 +--- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/x/accesscontrol/keeper/keeper.go b/x/accesscontrol/keeper/keeper.go index efbedb741..13fc5ae8f 100644 --- a/x/accesscontrol/keeper/keeper.go +++ b/x/accesscontrol/keeper/keeper.go @@ -532,13 +532,9 @@ func (k Keeper) UpdateWritesetsWithAccessOps(accessOps []acltypes.AccessOperatio } // GenerateEstimatedWritesets utilizes the existing patterns for access operation generation to estimate the writesets for a transaction -func (k Keeper) GenerateEstimatedWritesets(ctx sdk.Context, txDecoder sdk.TxDecoder, anteDepGen sdk.AnteDepGenerator, txIndex int, txBytes []byte) (sdk.MappedWritesets, error) { +func (k Keeper) GenerateEstimatedWritesets(ctx sdk.Context, anteDepGen sdk.AnteDepGenerator, txIndex int, tx sdk.Tx) (sdk.MappedWritesets, error) { storeKeyMap := k.GetStoreKeyMap(ctx) writesets := make(sdk.MappedWritesets) - tx, err := txDecoder(txBytes) - if err != nil { - return nil, err - } // generate antedeps accessOps for tx anteDeps, err := anteDepGen([]acltypes.AccessOperation{}, tx, txIndex) if err != nil { diff --git a/x/accesscontrol/keeper/keeper_test.go b/x/accesscontrol/keeper/keeper_test.go index e077bdf6f..a18f86436 100644 --- a/x/accesscontrol/keeper/keeper_test.go +++ b/x/accesscontrol/keeper/keeper_test.go @@ -2660,10 +2660,8 @@ func TestGenerateEstimatedDependencies(t *testing.T) { txBuilder := simapp.MakeTestEncodingConfig().TxConfig.NewTxBuilder() err := txBuilder.SetMsgs(msgs...) require.NoError(t, err) - bz, err := simapp.MakeTestEncodingConfig().TxConfig.TxEncoder()(txBuilder.GetTx()) - require.NoError(t, err) - writesets, err := app.AccessControlKeeper.GenerateEstimatedWritesets(ctx, simapp.MakeTestEncodingConfig().TxConfig.TxDecoder(), app.GetAnteDepGenerator(), 0, bz) + writesets, err := app.AccessControlKeeper.GenerateEstimatedWritesets(ctx, app.GetAnteDepGenerator(), 0, txBuilder.GetTx()) require.NoError(t, err) // check writesets From c54c4f0c1af75f9bb54ae20c679f648b3739b578 Mon Sep 17 00:00:00 2001 From: Uday Patil Date: Thu, 11 Jan 2024 11:36:30 -0600 Subject: [PATCH 20/39] use absoluteIndex instead of relative Index for txIndex --- tasks/scheduler.go | 16 +++++++++------- types/tx_batch.go | 1 + 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/tasks/scheduler.go b/tasks/scheduler.go index e65843d20..17bbaff1f 100644 --- a/tasks/scheduler.go +++ b/tasks/scheduler.go @@ -53,6 +53,7 @@ type deliverTxTask struct { Request types.RequestDeliverTx SdkTx sdk.Tx Checksum [32]byte + AbsoluteIndex int Response *types.ResponseDeliverTx VersionStores map[sdk.StoreKey]*multiversion.VersionIndexedStore } @@ -180,12 +181,13 @@ func toTasks(reqs []*sdk.DeliverTxEntry) []*deliverTxTask { res := make([]*deliverTxTask, 0, len(reqs)) for idx, r := range reqs { res = append(res, &deliverTxTask{ - Request: r.Request, - SdkTx: r.SdkTx, - Checksum: r.Checksum, - Index: idx, - Status: statusPending, - Dependencies: map[int]struct{}{}, + Request: r.Request, + SdkTx: r.SdkTx, + Checksum: r.Checksum, + AbsoluteIndex: r.AbsoluteIndex, + Index: idx, + Status: statusPending, + Dependencies: map[int]struct{}{}, }) } return res @@ -469,7 +471,7 @@ func (s *scheduler) traceSpan(ctx sdk.Context, name string, task *deliverTxTask) // prepareTask initializes the context and version stores for a task func (s *scheduler) prepareTask(task *deliverTxTask) { - ctx := task.Ctx.WithTxIndex(task.Index) + ctx := task.Ctx.WithTxIndex(task.AbsoluteIndex) _, span := s.traceSpan(ctx, "SchedulerPrepare", task) defer span.End() diff --git a/types/tx_batch.go b/types/tx_batch.go index 0199306c8..3a835715e 100644 --- a/types/tx_batch.go +++ b/types/tx_batch.go @@ -11,6 +11,7 @@ type DeliverTxEntry struct { Request abci.RequestDeliverTx SdkTx Tx Checksum [32]byte + AbsoluteIndex int EstimatedWritesets MappedWritesets } From 7f7061379c5ad1c34aa3cf49197b8bac57acc8ec Mon Sep 17 00:00:00 2001 From: Uday Patil Date: Thu, 25 Jan 2024 16:50:44 -0600 Subject: [PATCH 21/39] Fix mvkv to adhere to updated KVStore interface --- store/multiversion/mvkv.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/store/multiversion/mvkv.go b/store/multiversion/mvkv.go index e28912b06..14f4be5a0 100644 --- a/store/multiversion/mvkv.go +++ b/store/multiversion/mvkv.go @@ -311,6 +311,14 @@ func (store *VersionIndexedStore) iterator(start []byte, end []byte, ascending b } +func (v *VersionIndexedStore) VersionExists(version int64) bool { + return v.parent.VersionExists(version) +} + +func (v *VersionIndexedStore) DeleteAll(start, end []byte) error { + return v.parent.DeleteAll(start, end) +} + // GetStoreType implements types.KVStore. func (v *VersionIndexedStore) GetStoreType() types.StoreType { return v.parent.GetStoreType() From ed2ea7dc5cd2bd033b09485791adc0121eaea9cc Mon Sep 17 00:00:00 2001 From: Uday Patil Date: Thu, 25 Jan 2024 19:01:17 -0600 Subject: [PATCH 22/39] update schduler and tests --- baseapp/deliver_tx_batch_test.go | 4 +++- tasks/scheduler.go | 11 ++++++----- tasks/scheduler_test.go | 14 ++++++++------ 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/baseapp/deliver_tx_batch_test.go b/baseapp/deliver_tx_batch_test.go index c3d92b4bd..3cf6e0739 100644 --- a/baseapp/deliver_tx_batch_test.go +++ b/baseapp/deliver_tx_batch_test.go @@ -121,7 +121,9 @@ func TestDeliverTxBatch(t *testing.T) { txBytes, err := codec.Marshal(tx) require.NoError(t, err) requests = append(requests, &sdk.DeliverTxEntry{ - Request: abci.RequestDeliverTx{Tx: txBytes}, + Request: abci.RequestDeliverTx{Tx: txBytes}, + SdkTx: *tx, + AbsoluteIndex: i, }) } diff --git a/tasks/scheduler.go b/tasks/scheduler.go index 17bbaff1f..5ca1cafee 100644 --- a/tasks/scheduler.go +++ b/tasks/scheduler.go @@ -121,9 +121,9 @@ func NewScheduler(workers int, tracingInfo *tracing.Info, deliverTxFunc func(ctx func (s *scheduler) invalidateTask(task *deliverTxTask) { for _, mv := range s.multiVersionStores { - mv.InvalidateWriteset(task.Index, task.Incarnation) - mv.ClearReadset(task.Index) - mv.ClearIterateset(task.Index) + mv.InvalidateWriteset(task.AbsoluteIndex, task.Incarnation) + mv.ClearReadset(task.AbsoluteIndex) + mv.ClearIterateset(task.AbsoluteIndex) } } @@ -163,7 +163,7 @@ func (s *scheduler) findConflicts(task *deliverTxTask) (bool, []int) { uniq := make(map[int]struct{}) valid := true for _, mv := range s.multiVersionStores { - ok, mvConflicts := mv.ValidateTransactionState(task.Index) + ok, mvConflicts := mv.ValidateTransactionState(task.AbsoluteIndex) for _, c := range mvConflicts { if _, ok := uniq[c]; !ok { conflicts = append(conflicts, c) @@ -463,6 +463,7 @@ func (s *scheduler) traceSpan(ctx sdk.Context, name string, task *deliverTxTask) if task != nil { span.SetAttributes(attribute.String("txHash", fmt.Sprintf("%X", sha256.Sum256(task.Request.Tx)))) span.SetAttributes(attribute.Int("txIndex", task.Index)) + span.SetAttributes(attribute.Int("absoluteIndex", task.AbsoluteIndex)) span.SetAttributes(attribute.Int("txIncarnation", task.Incarnation)) } ctx = ctx.WithTraceSpanContext(spanCtx) @@ -487,7 +488,7 @@ func (s *scheduler) prepareTask(task *deliverTxTask) { // init version stores by store key vs := make(map[store.StoreKey]*multiversion.VersionIndexedStore) for storeKey, mvs := range s.multiVersionStores { - vs[storeKey] = mvs.VersionedIndexedStore(task.Index, task.Incarnation, abortCh) + vs[storeKey] = mvs.VersionedIndexedStore(task.AbsoluteIndex, task.Incarnation, abortCh) } // save off version store so we can ask it things later diff --git a/tasks/scheduler_test.go b/tasks/scheduler_test.go index 13a9ad496..c245367e5 100644 --- a/tasks/scheduler_test.go +++ b/tasks/scheduler_test.go @@ -26,7 +26,7 @@ import ( "github.com/cosmos/cosmos-sdk/utils/tracing" ) -type mockDeliverTxFunc func(ctx sdk.Context, req types.RequestDeliverTx) types.ResponseDeliverTx +type mockDeliverTxFunc func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res types.ResponseDeliverTx) var testStoreKey = sdk.NewKVStoreKey("mock") var itemKey = []byte("key") @@ -38,6 +38,8 @@ func requestList(n int) []*sdk.DeliverTxEntry { Request: types.RequestDeliverTx{ Tx: []byte(fmt.Sprintf("%d", i)), }, + AbsoluteIndex: i, + // TODO: maybe we need to add dummy sdkTx message types and handler routers too } } @@ -95,7 +97,7 @@ func TestProcessAll(t *testing.T) { runs: 10, addStores: true, requests: requestList(0), - deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx) types.ResponseDeliverTx { + deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res types.ResponseDeliverTx) { panic("should not deliver") }, assertions: func(t *testing.T, ctx sdk.Context, res []types.ResponseDeliverTx) { @@ -116,7 +118,7 @@ func TestProcessAll(t *testing.T) { kv.Set([]byte(fmt.Sprintf("%d", i)), []byte(fmt.Sprintf("%d", i))) } }, - deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx) (response types.ResponseDeliverTx) { + deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res types.ResponseDeliverTx) { defer abortRecoveryFunc(&response) kv := ctx.MultiStore().GetKVStore(testStoreKey) if ctx.TxIndex()%2 == 0 { @@ -157,7 +159,7 @@ func TestProcessAll(t *testing.T) { runs: 10, addStores: true, requests: requestList(1000), - deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx) (response types.ResponseDeliverTx) { + deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res types.ResponseDeliverTx) { defer abortRecoveryFunc(&response) // all txs read and write to the same key to maximize conflicts kv := ctx.MultiStore().GetKVStore(testStoreKey) @@ -189,7 +191,7 @@ func TestProcessAll(t *testing.T) { runs: 5, addStores: true, requests: requestList(1000), - deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx) (response types.ResponseDeliverTx) { + deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res types.ResponseDeliverTx) { defer abortRecoveryFunc(&response) // all txs read and write to the same key to maximize conflicts kv := ctx.MultiStore().GetKVStore(testStoreKey) @@ -253,7 +255,7 @@ func TestProcessAll(t *testing.T) { runs: 10, addStores: false, requests: requestList(10), - deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx) (response types.ResponseDeliverTx) { + deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res types.ResponseDeliverTx) { defer abortRecoveryFunc(&response) return types.ResponseDeliverTx{ Info: fmt.Sprintf("%d", ctx.TxIndex()), From 4322be8b1ff4f007ce0a6a1eb416deacb59ce9ac Mon Sep 17 00:00:00 2001 From: Uday Patil Date: Tue, 27 Feb 2024 22:43:26 -0600 Subject: [PATCH 23/39] update scheduler test call pattern --- tasks/scheduler_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/scheduler_test.go b/tasks/scheduler_test.go index c245367e5..5b469e4b1 100644 --- a/tasks/scheduler_test.go +++ b/tasks/scheduler_test.go @@ -227,7 +227,7 @@ func TestProcessAll(t *testing.T) { runs: 1, addStores: true, requests: requestList(2000), - deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx) (response types.ResponseDeliverTx) { + deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) types.ResponseDeliverTx { defer abortRecoveryFunc(&response) if ctx.TxIndex()%10 != 0 { return types.ResponseDeliverTx{ From 7418b51cdd34b933ff7d84c6d35a9d00f4ccc9e9 Mon Sep 17 00:00:00 2001 From: codchen Date: Thu, 7 Mar 2024 13:19:23 +0800 Subject: [PATCH 24/39] Integrate with tendermint EVM tx replacement logic (#446) ## Describe your changes and provide context See description in https://github.com/sei-protocol/sei-tendermint/pull/206 ## Testing performed to validate your change --------- Co-authored-by: Steven Landers Co-authored-by: Philip Su Co-authored-by: Yiming Zang <50607998+yzang2019@users.noreply.github.com> Co-authored-by: Aleksandr Bezobchuk Co-authored-by: Uday Patil --- baseapp/abci.go | 25 +++++++++++++++++++++++-- baseapp/baseapp.go | 2 +- go.mod | 2 +- go.sum | 4 ++-- types/context.go | 7 ++++--- 5 files changed, 31 insertions(+), 9 deletions(-) diff --git a/baseapp/abci.go b/baseapp/abci.go index 61a7f4ad4..7e528d121 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -293,7 +293,7 @@ func (app *BaseApp) DeliverTx(ctx sdk.Context, req abci.RequestDeliverTx, tx sdk telemetry.SetGauge(float32(gInfo.GasWanted), "tx", "gas", "wanted") }() - gInfo, result, anteEvents, _, _, _, _, err := app.runTx(ctx.WithTxBytes(req.Tx).WithVoteInfos(app.voteInfos), runTxModeDeliver, tx, checksum) + gInfo, result, anteEvents, _, _, _, resCtx, err := app.runTx(ctx.WithTxBytes(req.Tx).WithVoteInfos(app.voteInfos), runTxModeDeliver, tx, checksum) if err != nil { resultStr = "failed" // if we have a result, use those events instead of just the anteEvents @@ -303,13 +303,20 @@ func (app *BaseApp) DeliverTx(ctx sdk.Context, req abci.RequestDeliverTx, tx sdk return sdkerrors.ResponseDeliverTxWithEvents(err, gInfo.GasWanted, gInfo.GasUsed, sdk.MarkEventsToIndex(anteEvents, app.indexEvents), app.trace) } - return abci.ResponseDeliverTx{ + res = abci.ResponseDeliverTx{ GasWanted: int64(gInfo.GasWanted), // TODO: Should type accept unsigned ints? GasUsed: int64(gInfo.GasUsed), // TODO: Should type accept unsigned ints? Log: result.Log, Data: result.Data, Events: sdk.MarkEventsToIndex(result.Events, app.indexEvents), } + if resCtx.IsEVM() { + res.EvmTxInfo = &abci.EvmTxInfo{ + SenderAddress: resCtx.EVMSenderAddress(), + Nonce: resCtx.EVMNonce(), + } + } + return } func (app *BaseApp) WriteStateToCommitAndGetWorkingHash() []byte { @@ -1063,6 +1070,20 @@ func (app *BaseApp) ProcessProposal(ctx context.Context, req *abci.RequestProces } }() + defer func() { + if err := recover(); err != nil { + app.logger.Error( + "panic recovered in ProcessProposal", + "height", req.Height, + "time", req.Time, + "hash", fmt.Sprintf("%X", req.Hash), + "panic", err, + ) + + resp = &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT} + } + }() + if app.processProposalHandler != nil { resp, err = app.processProposalHandler(app.processProposalState.ctx, req) if err != nil { diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 20b978fbb..5aa821585 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -986,7 +986,7 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [ result.Events = append(anteEvents, result.Events...) } if ctx.CheckTxCallback() != nil { - ctx.CheckTxCallback()(err) + ctx.CheckTxCallback()(ctx, err) } return gInfo, result, anteEvents, priority, pendingTxChecker, expireHandler, ctx, err } diff --git a/go.mod b/go.mod index 001b4ef35..270c208b9 100644 --- a/go.mod +++ b/go.mod @@ -187,7 +187,7 @@ replace ( github.com/sei-protocol/sei-db => github.com/sei-protocol/sei-db v0.0.31 // Latest goleveldb is broken, we have to stick to this version github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 - github.com/tendermint/tendermint => github.com/sei-protocol/sei-tendermint v0.2.38-evm-rebase + github.com/tendermint/tendermint => github.com/sei-protocol/sei-tendermint v0.2.38-evm-rebase-2 // latest grpc doesn't work with with our modified proto compiler, so we need to enforce // the following version across all dependencies. google.golang.org/grpc => google.golang.org/grpc v1.33.2 diff --git a/go.sum b/go.sum index 768c06703..e9399f4a3 100644 --- a/go.sum +++ b/go.sum @@ -954,8 +954,8 @@ github.com/sei-protocol/sei-db v0.0.31 h1:UW9skaXnaXfi9mp60EbAJ2ijyr1Hnu9WYatMNr github.com/sei-protocol/sei-db v0.0.31/go.mod h1:F/ZKZA8HJPcUzSZPA8yt6pfwlGriJ4RDR4eHKSGLStI= github.com/sei-protocol/sei-iavl v0.1.9 h1:y4mVYftxLNRs6533zl7N0/Ch+CzRQc04JDfHolIxgBE= github.com/sei-protocol/sei-iavl v0.1.9/go.mod h1:7PfkEVT5dcoQE+s/9KWdoXJ8VVVP1QpYYPLdxlkSXFk= -github.com/sei-protocol/sei-tendermint v0.2.38-evm-rebase h1:+c9PFgoHwYV+FGPGnJK8ySmUqlwfE0dbDri5zmxBQQI= -github.com/sei-protocol/sei-tendermint v0.2.38-evm-rebase/go.mod h1:4LSlJdhl3nf3OmohliwRNUFLOB1XWlrmSodrIP7fLh4= +github.com/sei-protocol/sei-tendermint v0.2.38-evm-rebase-2 h1:y740HdzTehlJaBrwy/T1ncwJ9D10xu4r6gSHtNRzqF0= +github.com/sei-protocol/sei-tendermint v0.2.38-evm-rebase-2/go.mod h1:4LSlJdhl3nf3OmohliwRNUFLOB1XWlrmSodrIP7fLh4= github.com/sei-protocol/sei-tm-db v0.0.5 h1:3WONKdSXEqdZZeLuWYfK5hP37TJpfaUa13vAyAlvaQY= github.com/sei-protocol/sei-tm-db v0.0.5/go.mod h1:Cpa6rGyczgthq7/0pI31jys2Fw0Nfrc+/jKdP1prVqY= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= diff --git a/types/context.go b/types/context.go index 81d0ab14b..b2c467257 100644 --- a/types/context.go +++ b/types/context.go @@ -34,6 +34,7 @@ type Context struct { voteInfo []abci.VoteInfo gasMeter GasMeter occEnabled bool + blockGasMeter GasMeter checkTx bool recheckTx bool // if recheckTx == true, then checkTx must also be true minGasPrice DecCoins @@ -41,7 +42,7 @@ type Context struct { eventManager *EventManager priority int64 // The tx priority, only relevant in CheckTx pendingTxChecker abci.PendingTxChecker // Checker for pending transaction, only relevant in CheckTx - checkTxCallback func(error) // callback to make at the end of CheckTx. Input param is the error (nil-able) of `runMsgs` + checkTxCallback func(Context, error) // callback to make at the end of CheckTx. Input param is the error (nil-able) of `runMsgs` expireTxHandler func() // callback that the mempool invokes when a tx is expired txBlockingChannels acltypes.MessageAccessOpsChannelMapping @@ -144,7 +145,7 @@ func (c Context) PendingTxChecker() abci.PendingTxChecker { return c.pendingTxChecker } -func (c Context) CheckTxCallback() func(error) { +func (c Context) CheckTxCallback() func(Context, error) { return c.checkTxCallback } @@ -401,7 +402,7 @@ func (c Context) WithPendingTxChecker(checker abci.PendingTxChecker) Context { return c } -func (c Context) WithCheckTxCallback(checkTxCallback func(error)) Context { +func (c Context) WithCheckTxCallback(checkTxCallback func(Context, error)) Context { c.checkTxCallback = checkTxCallback return c } From ae6f0c5204fb1dfd1ac250f636a7e6a1ae707857 Mon Sep 17 00:00:00 2001 From: Uday Patil Date: Mon, 11 Mar 2024 11:26:53 -0500 Subject: [PATCH 25/39] Fix indexesValidated and PrefillEstimates to operate on absolute idx (#454) This is one component that was missed when refactoring to use absolute indices for EVM changes. This change refactors such that prefill estimates will appropriately fill the estimates by absolute Index and indexes validated will similarly check via absolute indices instead of relative. Existing unit tests + loadtesting --- tasks/scheduler.go | 34 +++++++++++++-------- tasks/scheduler_test.go | 68 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 83 insertions(+), 19 deletions(-) diff --git a/tasks/scheduler.go b/tasks/scheduler.go index 5ca1cafee..5445d724d 100644 --- a/tasks/scheduler.go +++ b/tasks/scheduler.go @@ -101,6 +101,7 @@ type scheduler struct { workers int multiVersionStores map[sdk.StoreKey]multiversion.MultiVersionStore tracingInfo *tracing.Info + allTasksMap map[int]*deliverTxTask allTasks []*deliverTxTask executeCh chan func() validateCh chan func() @@ -177,10 +178,11 @@ func (s *scheduler) findConflicts(task *deliverTxTask) (bool, []int) { return valid, conflicts } -func toTasks(reqs []*sdk.DeliverTxEntry) []*deliverTxTask { - res := make([]*deliverTxTask, 0, len(reqs)) +func toTasks(reqs []*sdk.DeliverTxEntry) ([]*deliverTxTask, map[int]*deliverTxTask) { + tasksMap := make(map[int]*deliverTxTask) + allTasks := make([]*deliverTxTask, 0, len(reqs)) for idx, r := range reqs { - res = append(res, &deliverTxTask{ + task := &deliverTxTask{ Request: r.Request, SdkTx: r.SdkTx, Checksum: r.Checksum, @@ -188,9 +190,11 @@ func toTasks(reqs []*sdk.DeliverTxEntry) []*deliverTxTask { Index: idx, Status: statusPending, Dependencies: map[int]struct{}{}, - }) + } + tasksMap[r.AbsoluteIndex] = task + allTasks = append(allTasks, task) } - return res + return allTasks, tasksMap } func (s *scheduler) collectResponses(tasks []*deliverTxTask) []types.ResponseDeliverTx { @@ -213,9 +217,11 @@ func (s *scheduler) tryInitMultiVersionStore(ctx sdk.Context) { s.multiVersionStores = mvs } -func dependenciesValidated(tasks []*deliverTxTask, deps map[int]struct{}) bool { +func dependenciesValidated(tasksMap map[int]*deliverTxTask, deps map[int]struct{}) bool { for i := range deps { - if !tasks[i].IsStatus(statusValidated) { + // because idx contains absoluteIndices, we need to fetch from map + task := tasksMap[i] + if !task.IsStatus(statusValidated) { return false } } @@ -243,12 +249,12 @@ func allValidated(tasks []*deliverTxTask) bool { func (s *scheduler) PrefillEstimates(reqs []*sdk.DeliverTxEntry) { // iterate over TXs, update estimated writesets where applicable - for i, req := range reqs { + for _, req := range reqs { mappedWritesets := req.EstimatedWritesets // order shouldnt matter for storeKeys because each storeKey partitioned MVS is independent for storeKey, writeset := range mappedWritesets { // we use `-1` to indicate a prefill incarnation - s.multiVersionStores[storeKey].SetEstimatedWriteset(i, -1, writeset) + s.multiVersionStores[storeKey].SetEstimatedWriteset(req.AbsoluteIndex, -1, writeset) } } } @@ -271,9 +277,11 @@ func (s *scheduler) ProcessAll(ctx sdk.Context, reqs []*sdk.DeliverTxEntry) ([]t // initialize mutli-version stores if they haven't been initialized yet s.tryInitMultiVersionStore(ctx) // prefill estimates - s.PrefillEstimates(reqs) - tasks := toTasks(reqs) + // This "optimization" path is being disabled because we don't have a strong reason to have it given that it + // s.PrefillEstimates(reqs) + tasks, tasksMap := toTasks(reqs) s.allTasks = tasks + s.allTasksMap = tasksMap s.executeCh = make(chan func(), len(tasks)) s.validateCh = make(chan func(), len(tasks)) defer s.emitMetrics() @@ -345,7 +353,7 @@ func (s *scheduler) shouldRerun(task *deliverTxTask) bool { task.AppendDependencies(conflicts) // if the conflicts are now validated, then rerun this task - if dependenciesValidated(s.allTasks, task.Dependencies) { + if dependenciesValidated(s.allTasksMap, task.Dependencies) { return true } else { // otherwise, wait for completion @@ -362,7 +370,7 @@ func (s *scheduler) shouldRerun(task *deliverTxTask) bool { case statusWaiting: // if conflicts are done, then this task is ready to run again - return dependenciesValidated(s.allTasks, task.Dependencies) + return dependenciesValidated(s.allTasksMap, task.Dependencies) } panic("unexpected status: " + task.Status) } diff --git a/tasks/scheduler_test.go b/tasks/scheduler_test.go index 5b469e4b1..7776179b1 100644 --- a/tasks/scheduler_test.go +++ b/tasks/scheduler_test.go @@ -20,6 +20,7 @@ import ( "github.com/cosmos/cosmos-sdk/store/cachekv" "github.com/cosmos/cosmos-sdk/store/cachemulti" "github.com/cosmos/cosmos-sdk/store/dbadapter" + "github.com/cosmos/cosmos-sdk/store/multiversion" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/occ" @@ -58,6 +59,25 @@ func abortRecoveryFunc(response *types.ResponseDeliverTx) { } } +func requestListWithEstimatedWritesets(n int) []*sdk.DeliverTxEntry { + tasks := make([]*sdk.DeliverTxEntry, n) + for i := 0; i < n; i++ { + tasks[i] = &sdk.DeliverTxEntry{ + Request: types.RequestDeliverTx{ + Tx: []byte(fmt.Sprintf("%d", i)), + }, + AbsoluteIndex: i, + EstimatedWritesets: sdk.MappedWritesets{ + testStoreKey: multiversion.WriteSet{ + string(itemKey): []byte("foo"), + }, + }, + } + + } + return tasks +} + func initTestCtx(injectStores bool) sdk.Context { ctx := sdk.Context{}.WithContext(context.Background()) keys := make(map[string]sdk.StoreKey) @@ -119,7 +139,7 @@ func TestProcessAll(t *testing.T) { } }, deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res types.ResponseDeliverTx) { - defer abortRecoveryFunc(&response) + defer abortRecoveryFunc(&res) kv := ctx.MultiStore().GetKVStore(testStoreKey) if ctx.TxIndex()%2 == 0 { // For even-indexed transactions, write to the store @@ -160,7 +180,7 @@ func TestProcessAll(t *testing.T) { addStores: true, requests: requestList(1000), deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res types.ResponseDeliverTx) { - defer abortRecoveryFunc(&response) + defer abortRecoveryFunc(&res) // all txs read and write to the same key to maximize conflicts kv := ctx.MultiStore().GetKVStore(testStoreKey) @@ -192,7 +212,43 @@ func TestProcessAll(t *testing.T) { addStores: true, requests: requestList(1000), deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res types.ResponseDeliverTx) { - defer abortRecoveryFunc(&response) + defer abortRecoveryFunc(&res) + // all txs read and write to the same key to maximize conflicts + kv := ctx.MultiStore().GetKVStore(testStoreKey) + val := string(kv.Get(itemKey)) + + // write to the store with this tx's index + kv.Set(itemKey, req.Tx) + + // return what was read from the store (final attempt should be index-1) + return types.ResponseDeliverTx{ + Info: val, + } + }, + assertions: func(t *testing.T, ctx sdk.Context, res []types.ResponseDeliverTx) { + for idx, response := range res { + if idx == 0 { + require.Equal(t, "", response.Info) + } else { + // the info is what was read from the kv store by the tx + // each tx writes its own index, so the info should be the index of the previous tx + require.Equal(t, fmt.Sprintf("%d", idx-1), response.Info) + } + } + // confirm last write made it to the parent store + latest := ctx.MultiStore().GetKVStore(testStoreKey).Get(itemKey) + require.Equal(t, []byte(fmt.Sprintf("%d", len(res)-1)), latest) + }, + expectedErr: nil, + }, + { + name: "Test every tx accesses same key with estimated writesets", + workers: 50, + runs: 1, + addStores: true, + requests: requestListWithEstimatedWritesets(1000), + deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res types.ResponseDeliverTx) { + defer abortRecoveryFunc(&res) // all txs read and write to the same key to maximize conflicts kv := ctx.MultiStore().GetKVStore(testStoreKey) val := string(kv.Get(itemKey)) @@ -227,8 +283,8 @@ func TestProcessAll(t *testing.T) { runs: 1, addStores: true, requests: requestList(2000), - deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) types.ResponseDeliverTx { - defer abortRecoveryFunc(&response) + deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res types.ResponseDeliverTx) { + defer abortRecoveryFunc(&res) if ctx.TxIndex()%10 != 0 { return types.ResponseDeliverTx{ Info: "none", @@ -256,7 +312,7 @@ func TestProcessAll(t *testing.T) { addStores: false, requests: requestList(10), deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res types.ResponseDeliverTx) { - defer abortRecoveryFunc(&response) + defer abortRecoveryFunc(&res) return types.ResponseDeliverTx{ Info: fmt.Sprintf("%d", ctx.TxIndex()), } From edf3698d8cdc267476476862484afe33f5be9f68 Mon Sep 17 00:00:00 2001 From: Uday Patil Date: Thu, 14 Mar 2024 09:05:10 -0500 Subject: [PATCH 26/39] Modify max incarnation fallback (#460) --------- Co-authored-by: Steven Landers --- tasks/scheduler.go | 7 ++----- tasks/scheduler_test.go | 40 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/tasks/scheduler.go b/tasks/scheduler.go index 5445d724d..ab6c681b2 100644 --- a/tasks/scheduler.go +++ b/tasks/scheduler.go @@ -48,7 +48,6 @@ type deliverTxTask struct { Status status Dependencies map[int]struct{} Abort *occ.Abort - Index int Incarnation int Request types.RequestDeliverTx SdkTx sdk.Tx @@ -181,13 +180,12 @@ func (s *scheduler) findConflicts(task *deliverTxTask) (bool, []int) { func toTasks(reqs []*sdk.DeliverTxEntry) ([]*deliverTxTask, map[int]*deliverTxTask) { tasksMap := make(map[int]*deliverTxTask) allTasks := make([]*deliverTxTask, 0, len(reqs)) - for idx, r := range reqs { + for _, r := range reqs { task := &deliverTxTask{ Request: r.Request, SdkTx: r.SdkTx, Checksum: r.Checksum, AbsoluteIndex: r.AbsoluteIndex, - Index: idx, Status: statusPending, Dependencies: map[int]struct{}{}, } @@ -303,7 +301,7 @@ func (s *scheduler) ProcessAll(ctx sdk.Context, reqs []*sdk.DeliverTxEntry) ([]t toExecute := tasks for !allValidated(tasks) { - // if the max incarnation >= 5, we should revert to synchronous + // if the max incarnation >= x, we should revert to synchronous if iterations >= maximumIterations { // process synchronously s.synchronous = true @@ -470,7 +468,6 @@ func (s *scheduler) traceSpan(ctx sdk.Context, name string, task *deliverTxTask) spanCtx, span := s.tracingInfo.StartWithContext(name, ctx.TraceSpanContext()) if task != nil { span.SetAttributes(attribute.String("txHash", fmt.Sprintf("%X", sha256.Sum256(task.Request.Tx)))) - span.SetAttributes(attribute.Int("txIndex", task.Index)) span.SetAttributes(attribute.Int("absoluteIndex", task.AbsoluteIndex)) span.SetAttributes(attribute.Int("txIncarnation", task.Incarnation)) } diff --git a/tasks/scheduler_test.go b/tasks/scheduler_test.go index 7776179b1..738ea2986 100644 --- a/tasks/scheduler_test.go +++ b/tasks/scheduler_test.go @@ -324,14 +324,50 @@ func TestProcessAll(t *testing.T) { }, expectedErr: nil, }, + { + name: "Test every tx accesses same key with estimated writesets", + workers: 50, + runs: 1, + addStores: true, + requests: requestListWithEstimatedWritesets(1000), + deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res types.ResponseDeliverTx) { + defer abortRecoveryFunc(&res) + // all txs read and write to the same key to maximize conflicts + kv := ctx.MultiStore().GetKVStore(testStoreKey) + val := string(kv.Get(itemKey)) + + // write to the store with this tx's index + kv.Set(itemKey, req.Tx) + + // return what was read from the store (final attempt should be index-1) + return types.ResponseDeliverTx{ + Info: val, + } + }, + assertions: func(t *testing.T, ctx sdk.Context, res []types.ResponseDeliverTx) { + for idx, response := range res { + if idx == 0 { + require.Equal(t, "", response.Info) + } else { + // the info is what was read from the kv store by the tx + // each tx writes its own index, so the info should be the index of the previous tx + require.Equal(t, fmt.Sprintf("%d", idx-1), response.Info) + } + } + // confirm last write made it to the parent store + latest := ctx.MultiStore().GetKVStore(testStoreKey).Get(itemKey) + require.Equal(t, []byte(fmt.Sprintf("%d", len(res)-1)), latest) + }, + expectedErr: nil, + }, { name: "Test every tx accesses same key with delays", workers: 50, runs: 1, addStores: true, requests: requestList(1000), - deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx) (response types.ResponseDeliverTx) { - defer abortRecoveryFunc(&response) + deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res types.ResponseDeliverTx) { + defer abortRecoveryFunc(&res) wait := rand.Intn(10) time.Sleep(time.Duration(wait) * time.Millisecond) // all txs read and write to the same key to maximize conflicts From d9a0f351c02611e2a464a852205602d52792ead9 Mon Sep 17 00:00:00 2001 From: Steven Landers Date: Fri, 15 Mar 2024 10:46:06 -0400 Subject: [PATCH 27/39] add async scheduler --- tasksv2/int_set.go | 149 +++++++++++ tasksv2/int_set_benchmark_test.go | 99 +++++++ tasksv2/scheduler.go | 205 ++++++++++++++ tasksv2/scheduler_test.go | 427 ++++++++++++++++++++++++++++++ tasksv2/task.go | 214 +++++++++++++++ tasksv2/task_execution.go | 81 ++++++ tasksv2/task_queue.go | 234 ++++++++++++++++ tasksv2/task_queue_test.go | 89 +++++++ tasksv2/task_validation.go | 68 +++++ tasksv2/timer.go | 123 +++++++++ tasksv2/utils.go | 104 ++++++++ 11 files changed, 1793 insertions(+) create mode 100644 tasksv2/int_set.go create mode 100644 tasksv2/int_set_benchmark_test.go create mode 100644 tasksv2/scheduler.go create mode 100644 tasksv2/scheduler_test.go create mode 100644 tasksv2/task.go create mode 100644 tasksv2/task_execution.go create mode 100644 tasksv2/task_queue.go create mode 100644 tasksv2/task_queue_test.go create mode 100644 tasksv2/task_validation.go create mode 100644 tasksv2/timer.go create mode 100644 tasksv2/utils.go diff --git a/tasksv2/int_set.go b/tasksv2/int_set.go new file mode 100644 index 000000000..282b15b85 --- /dev/null +++ b/tasksv2/int_set.go @@ -0,0 +1,149 @@ +package tasksv2 + +import ( + "sync" + "sync/atomic" +) + +type IntSet interface { + Add(idx int) + Delete(idx int) + Length() int + Exists(idx int) bool +} + +// points to implementation +func newIntSet(size int) IntSet { + return newIntSetByteSlice(size) +} + +// syncSetMap uses a map with a RW Mutex +type intSetMap struct { + mx sync.RWMutex + m map[int]struct{} +} + +func newIntSetMap(size int) IntSet { + return &intSetMap{ + m: make(map[int]struct{}), + } +} + +func (ss *intSetMap) Add(idx int) { + ss.mx.Lock() + defer ss.mx.Unlock() + ss.m[idx] = struct{}{} +} + +func (ss *intSetMap) List() []int { + ss.mx.RLock() + defer ss.mx.RUnlock() + list := make([]int, 0, len(ss.m)) + for k := range ss.m { + list = append(list, k) + } + return list +} + +func (ss *intSetMap) Delete(idx int) { + if ss.Exists(idx) { + ss.mx.Lock() + defer ss.mx.Unlock() + delete(ss.m, idx) + } +} + +func (ss *intSetMap) Length() int { + ss.mx.RLock() + defer ss.mx.RUnlock() + return len(ss.m) +} + +func (ss *intSetMap) Exists(idx int) bool { + ss.mx.RLock() + defer ss.mx.RUnlock() + _, ok := ss.m[idx] + return ok +} + +// intSetSyncMap uses a sync.Map with a length counter +type intSetSyncMap struct { + m sync.Map + length int32 +} + +func newIntSetSyncMap(size int) IntSet { + return &intSetSyncMap{} +} + +func (ss *intSetSyncMap) Add(idx int) { + _, loaded := ss.m.LoadOrStore(idx, struct{}{}) + if !loaded { + atomic.AddInt32(&ss.length, 1) + } +} + +func (ss *intSetSyncMap) Delete(idx int) { + _, ok := ss.m.Load(idx) + if ok { + ss.m.Delete(idx) + atomic.AddInt32(&ss.length, -1) + } +} + +func (ss *intSetSyncMap) Length() int { + return int(atomic.LoadInt32(&ss.length)) +} + +func (ss *intSetSyncMap) Exists(idx int) bool { + _, ok := ss.m.Load(idx) + return ok +} + +// syncSet holds a set of integers in a thread-safe way. +type intSetByteSlice struct { + locks []sync.RWMutex + state []byte + length int32 +} + +func newIntSetByteSlice(size int) *syncSet { + return &syncSet{ + state: make([]byte, size), + locks: make([]sync.RWMutex, size), + } +} + +func (ss *intSetByteSlice) Add(idx int) { + // First check without locking to reduce contention. + if ss.state[idx] == byte(0) { + ss.locks[idx].Lock() + // Check again to make sure it hasn't changed since acquiring the lock. + if ss.state[idx] == byte(0) { + ss.state[idx] = byte(1) + atomic.AddInt32(&ss.length, 1) + } + ss.locks[idx].Unlock() + } +} + +func (ss *intSetByteSlice) Delete(idx int) { + ss.locks[idx].Lock() + defer ss.locks[idx].Unlock() + + // Check again to make sure it hasn't changed since acquiring the lock. + if ss.state[idx] == byte(1) { + ss.state[idx] = byte(0) + atomic.AddInt32(&ss.length, -1) + } + +} + +func (ss *intSetByteSlice) Length() int { + return int(atomic.LoadInt32(&ss.length)) +} + +func (ss *intSetByteSlice) Exists(idx int) bool { + // Atomic read of a single byte is safe + return ss.state[idx] == byte(1) +} diff --git a/tasksv2/int_set_benchmark_test.go b/tasksv2/int_set_benchmark_test.go new file mode 100644 index 000000000..1a7998538 --- /dev/null +++ b/tasksv2/int_set_benchmark_test.go @@ -0,0 +1,99 @@ +package tasksv2 + +import ( + "math/rand" + "testing" +) + +func intSetImpl(size int) IntSet { + return newIntSetByteSlice(size) +} + +func BenchmarkSyncSet_Add(b *testing.B) { + size := 1000 // Assuming a size of 1000 for this example + ss := intSetImpl(size) + b.ResetTimer() + for i := 0; i < b.N; i++ { + ss.Add(i % size) // Loop over the syncSet size to avoid out-of-range panics + } +} + +func BenchmarkSyncSet_Delete(b *testing.B) { + size := 1000 + ss := intSetImpl(size) + // Pre-fill the syncSet to delete from + for i := 0; i < size; i++ { + ss.Add(i) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + ss.Delete(i % size) // Loop over the syncSet size to avoid out-of-range panics + } +} + +func BenchmarkSyncSet_Length(b *testing.B) { + size := 1000 + ss := intSetImpl(size) + // Pre-fill the syncSet + for i := 0; i < size; i++ { + ss.Add(i) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = ss.Length() + } +} + +func BenchmarkSyncSet_Exists(b *testing.B) { + size := 1000 + ss := intSetImpl(size) + // Pre-fill the syncSet + for i := 0; i < size; i++ { + ss.Add(i) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = ss.Exists(i % size) // Loop over the syncSet size to avoid out-of-range panics + } +} + +func BenchmarkSyncSet_Add_Contention(b *testing.B) { + size := 1000 // The size of the syncSet + ss := intSetImpl(size) + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + ss.Add(rand.Intn(size)) // Use a random index for contention + } + }) +} + +func BenchmarkSyncSet_Delete_Contention(b *testing.B) { + size := 1000 // The size of the syncSet + ss := intSetImpl(size) + // Pre-fill the syncSet to delete from + for i := 0; i < size; i++ { + ss.Add(i) + } + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + ss.Delete(rand.Intn(size)) // Use a random index for contention + } + }) +} + +func BenchmarkSyncSet_Exists_Contention(b *testing.B) { + size := 1000 // The size of the syncSet + ss := intSetImpl(size) + // Pre-fill the syncSet + for i := 0; i < size; i++ { + ss.Add(i) + } + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + ss.Exists(rand.Intn(size)) // Use a random index for contention + } + }) +} diff --git a/tasksv2/scheduler.go b/tasksv2/scheduler.go new file mode 100644 index 000000000..fdac27771 --- /dev/null +++ b/tasksv2/scheduler.go @@ -0,0 +1,205 @@ +package tasksv2 + +import ( + "fmt" + "strings" + "sync" + "sync/atomic" + + "github.com/cosmos/cosmos-sdk/store/multiversion" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/utils/tracing" + "github.com/tendermint/tendermint/abci/types" +) + +type SchedulerHandler func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res types.ResponseDeliverTx) + +// Scheduler processes tasks concurrently +type Scheduler interface { + ProcessAll(ctx sdk.Context, reqs []*sdk.DeliverTxEntry) ([]types.ResponseDeliverTx, error) +} + +type scheduler struct { + deliverTx SchedulerHandler + workers int + multiVersionStores map[sdk.StoreKey]multiversion.MultiVersionStore + tracingInfo *tracing.Info + tasks []*TxTask + executeCh chan func() + validateCh chan func() + timer *Timer +} + +// NewScheduler creates a new scheduler +func NewScheduler(workers int, tracingInfo *tracing.Info, deliverTxFunc SchedulerHandler) Scheduler { + return &scheduler{ + workers: workers, + deliverTx: deliverTxFunc, + tracingInfo: tracingInfo, + timer: NewTimer("Scheduler"), + } +} + +func (s *scheduler) initScheduler(ctx sdk.Context, reqs []*sdk.DeliverTxEntry) (Queue, int) { + // initialize mutli-version stores + s.initMultiVersionStore(ctx) + // prefill estimates + s.PrefillEstimates(reqs) + tasks := toTasks(ctx, reqs) + s.tasks = tasks + + workers := s.workers + if s.workers < 1 { + workers = len(tasks) + } + + // initialize scheduler queue + queue := NewTaskQueue(tasks, workers) + + // send all tasks to queue + go queue.ExecuteAll() + + return queue, workers +} + +func (s *scheduler) ProcessAll(ctx sdk.Context, reqs []*sdk.DeliverTxEntry) ([]types.ResponseDeliverTx, error) { + if len(reqs) == 0 { + return []types.ResponseDeliverTx{}, nil + } + + var results []types.ResponseDeliverTx + var err error + counter := atomic.Int32{} + + WithTimer(s.timer, "ProcessAll", func() { + + queue, workers := s.initScheduler(ctx, reqs) + wg := sync.WaitGroup{} + wg.Add(workers) + mx := sync.Mutex{} + var activeCount int32 + final := atomic.Bool{} + + for i := 0; i < workers; i++ { + go func(worker int) { + defer wg.Done() + + for { + + if atomic.LoadInt32(&activeCount) == 0 { + mx.Lock() + if queue.IsCompleted() { + if final.Load() { + queue.Close() + } else { + final.Store(true) + queue.ValidateAll() + } + } + mx.Unlock() + } + + cancel := hangDebug(func() { + if worker == 0 && !queue.IsCompleted() { + fmt.Printf("Logging tasks for height %d \n", ctx.BlockHeight()) + // produce a report of tasks mapped by status + var lines []string + for _, t := range s.tasks { + lines = append(lines, fmt.Sprintf("Task(idx=%d, status=%s, incarnation=%d):\t%s", t.AbsoluteIndex, t.status, t.Incarnation, "status")) + } + fmt.Println(strings.Join(lines, "\n")) + } + fmt.Printf("worker=%d, completed=%v\n", worker, queue.IsCompleted()) + }) + task, anyTasks := queue.NextTask(worker) + cancel() + atomic.AddInt32(&activeCount, 1) + + if !anyTasks { + return + } + + // this safely gets the task type while someone could be editing it + if tt, ok := task.PopTaskType(); ok { + counter.Add(1) + if !s.processTask(ctx, tt, worker, task, queue) { + final.Store(false) + } + } + atomic.AddInt32(&activeCount, -1) + } + + }(i) + } + + wg.Wait() + + for _, mv := range s.multiVersionStores { + mv.WriteLatestToStore() + } + results = collectResponses(s.tasks) + err = nil + }) + //s.timer.PrintReport() + //fmt.Printf("Total Tasks: %d\n", counter.Load()) + + return results, err +} + +func (s *scheduler) processTask(ctx sdk.Context, taskType TaskType, w int, t *TxTask, queue Queue) bool { + switch taskType { + case TypeValidation: + TaskLog(t, fmt.Sprintf("TypeValidation (worker=%d)", w)) + + s.validateTask(ctx, t) + + // check the outcome of validation and do things accordingly + switch t.status { + case statusValidated: + // task is finished (but can be re-validated by others) + TaskLog(t, "*** VALIDATED ***") + // informs queue that it's complete (counts towards overall completion) + queue.FinishTask(t.AbsoluteIndex) + return true + case statusWaiting: + // task should be re-validated (waiting on others) + // how can we wait on dependencies? + TaskLog(t, "waiting, executing again") + queue.Execute(t.AbsoluteIndex) + + case statusInvalid: + TaskLog(t, "invalid (re-executing, re-validating > tx)") + queue.ValidateLaterTasks(t.AbsoluteIndex) + queue.Execute(t.AbsoluteIndex) + default: + TaskLog(t, "unexpected status") + panic("unexpected status ") + } + + case TypeExecution: + t.ResetForExecution() + TaskLog(t, fmt.Sprintf("TypeExecution (worker=%d)", w)) + + s.executeTask(t) + + if t.IsStatus(statusAborted) { + parent := s.tasks[t.Abort.DependentTxIdx] + parent.LockTask() + if parent.IsTaskType(TypeExecution) { + t.Parents = []int{t.Abort.DependentTxIdx} + queue.AddDependentToParents(t.AbsoluteIndex) + } else { + queue.Execute(t.AbsoluteIndex) + } + parent.UnlockTask() + } else { + TaskLog(t, fmt.Sprintf("FINISHING task EXECUTION (worker=%d, incarnation=%d)", w, t.Incarnation)) + queue.FinishExecute(t.AbsoluteIndex) + } + + default: + TaskLog(t, "unexpected type") + panic("unexpected type") + } + return false +} diff --git a/tasksv2/scheduler_test.go b/tasksv2/scheduler_test.go new file mode 100644 index 000000000..43b15be77 --- /dev/null +++ b/tasksv2/scheduler_test.go @@ -0,0 +1,427 @@ +package tasksv2 + +import ( + "context" + "errors" + "fmt" + "math/rand" + "net/http" + _ "net/http/pprof" + "runtime" + "testing" + "time" + + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/abci/types" + dbm "github.com/tendermint/tm-db" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/trace" + + "github.com/cosmos/cosmos-sdk/store/cachekv" + "github.com/cosmos/cosmos-sdk/store/cachemulti" + "github.com/cosmos/cosmos-sdk/store/dbadapter" + "github.com/cosmos/cosmos-sdk/store/multiversion" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/occ" + "github.com/cosmos/cosmos-sdk/utils/tracing" +) + +var testStoreKey = sdk.NewKVStoreKey("mock") +var itemKey = []byte("key") + +func requestList(n int) []*sdk.DeliverTxEntry { + tasks := make([]*sdk.DeliverTxEntry, n) + for i := 0; i < n; i++ { + tasks[i] = &sdk.DeliverTxEntry{ + Request: types.RequestDeliverTx{ + Tx: []byte(fmt.Sprintf("%d", i)), + }, + AbsoluteIndex: i, + // TODO: maybe we need to add dummy sdkTx message types and handler routers too + } + + } + return tasks +} + +func abortRecoveryFunc(response *types.ResponseDeliverTx) { + if r := recover(); r != nil { + _, ok := r.(occ.Abort) + if !ok { + panic(r) + } + response.Code = sdkerrors.ErrOCCAbort.ABCICode() + response.Codespace = sdkerrors.ErrOCCAbort.Codespace() + response.Info = "occ abort" + } +} + +func requestListWithEstimatedWritesets(n int) []*sdk.DeliverTxEntry { + tasks := make([]*sdk.DeliverTxEntry, n) + for i := 0; i < n; i++ { + tasks[i] = &sdk.DeliverTxEntry{ + Request: types.RequestDeliverTx{ + Tx: []byte(fmt.Sprintf("%d", i)), + }, + AbsoluteIndex: i, + EstimatedWritesets: sdk.MappedWritesets{ + testStoreKey: multiversion.WriteSet{ + string(itemKey): []byte("foo"), + }, + }, + } + + } + return tasks +} + +func initTestCtx(injectStores bool) sdk.Context { + ctx := sdk.Context{}.WithContext(context.Background()) + keys := make(map[string]sdk.StoreKey) + stores := make(map[sdk.StoreKey]sdk.CacheWrapper) + db := dbm.NewMemDB() + if injectStores { + mem := dbadapter.Store{DB: db} + stores[testStoreKey] = cachekv.NewStore(mem, testStoreKey, 1000) + keys[testStoreKey.Name()] = testStoreKey + } + store := cachemulti.NewStore(db, stores, keys, nil, nil, nil) + ctx = ctx.WithMultiStore(&store) + return ctx +} + +func TestProcessAll(t *testing.T) { + runtime.SetBlockProfileRate(1) + + go func() { + http.ListenAndServe("localhost:6060", nil) + }() + + tests := []struct { + name string + workers int + runs int + before func(ctx sdk.Context) + requests []*sdk.DeliverTxEntry + deliverTxFunc SchedulerHandler + addStores bool + expectedErr error + assertions func(t *testing.T, ctx sdk.Context, res []types.ResponseDeliverTx) + }{ + { + name: "Test zero txs does not hang", + workers: 20, + runs: 10, + addStores: true, + requests: requestList(0), + deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res types.ResponseDeliverTx) { + panic("should not deliver") + }, + assertions: func(t *testing.T, ctx sdk.Context, res []types.ResponseDeliverTx) { + require.Len(t, res, 0) + }, + expectedErr: nil, + }, + { + name: "Test tx writing to a store that another tx is iterating", + workers: 50, + runs: 1, + requests: requestList(100), + addStores: true, + before: func(ctx sdk.Context) { + kv := ctx.MultiStore().GetKVStore(testStoreKey) + // initialize 100 test values in the base kv store so iterating isn't too fast + for i := 0; i < 10; i++ { + kv.Set([]byte(fmt.Sprintf("%d", i)), []byte(fmt.Sprintf("%d", i))) + } + }, + deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res types.ResponseDeliverTx) { + defer abortRecoveryFunc(&res) + kv := ctx.MultiStore().GetKVStore(testStoreKey) + if ctx.TxIndex()%2 == 0 { + // For even-indexed transactions, write to the store + kv.Set(req.Tx, req.Tx) + return types.ResponseDeliverTx{ + Info: "write", + } + } else { + // For odd-indexed transactions, iterate over the store + + // just write so we have more writes going on + kv.Set(req.Tx, req.Tx) + iterator := kv.Iterator(nil, nil) + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + // Do nothing, just iterate + } + return types.ResponseDeliverTx{ + Info: "iterate", + } + } + }, + assertions: func(t *testing.T, ctx sdk.Context, res []types.ResponseDeliverTx) { + for idx, response := range res { + if idx%2 == 0 { + require.Equal(t, "write", response.Info) + } else { + require.Equal(t, "iterate", response.Info) + } + } + }, + expectedErr: nil, + }, + { + name: "Test no overlap txs", + workers: 20, + runs: 10, + addStores: true, + requests: requestList(1000), + deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res types.ResponseDeliverTx) { + defer abortRecoveryFunc(&res) + // all txs read and write to the same key to maximize conflicts + kv := ctx.MultiStore().GetKVStore(testStoreKey) + + // write to the store with this tx's index + kv.Set(req.Tx, req.Tx) + val := string(kv.Get(req.Tx)) + + // return what was read from the store (final attempt should be index-1) + return types.ResponseDeliverTx{ + Info: val, + } + }, + assertions: func(t *testing.T, ctx sdk.Context, res []types.ResponseDeliverTx) { + for idx, response := range res { + require.Equal(t, fmt.Sprintf("%d", idx), response.Info) + } + store := ctx.MultiStore().GetKVStore(testStoreKey) + for i := 0; i < len(res); i++ { + val := store.Get([]byte(fmt.Sprintf("%d", i))) + require.Equal(t, []byte(fmt.Sprintf("%d", i)), val) + } + }, + expectedErr: nil, + }, + { + name: "Test every tx accesses same key", + workers: 50, + runs: 5, + addStores: true, + requests: requestList(1000), + deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res types.ResponseDeliverTx) { + defer abortRecoveryFunc(&res) + // all txs read and write to the same key to maximize conflicts + kv := ctx.MultiStore().GetKVStore(testStoreKey) + val := string(kv.Get(itemKey)) + + // write to the store with this tx's index + kv.Set(itemKey, req.Tx) + + // return what was read from the store (final attempt should be index-1) + return types.ResponseDeliverTx{ + Info: val, + } + }, + assertions: func(t *testing.T, ctx sdk.Context, res []types.ResponseDeliverTx) { + for idx, response := range res { + if idx == 0 { + require.Equal(t, "", response.Info) + } else { + // the info is what was read from the kv store by the tx + // each tx writes its own index, so the info should be the index of the previous tx + require.Equal(t, fmt.Sprintf("%d", idx-1), response.Info) + } + } + // confirm last write made it to the parent store + latest := ctx.MultiStore().GetKVStore(testStoreKey).Get(itemKey) + require.Equal(t, []byte(fmt.Sprintf("%d", len(res)-1)), latest) + }, + expectedErr: nil, + }, + { + name: "Test every tx accesses same key with estimated writesets", + workers: 50, + runs: 1, + addStores: true, + requests: requestListWithEstimatedWritesets(1000), + deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res types.ResponseDeliverTx) { + defer abortRecoveryFunc(&res) + // all txs read and write to the same key to maximize conflicts + kv := ctx.MultiStore().GetKVStore(testStoreKey) + val := string(kv.Get(itemKey)) + + // write to the store with this tx's index + kv.Set(itemKey, req.Tx) + + // return what was read from the store (final attempt should be index-1) + return types.ResponseDeliverTx{ + Info: val, + } + }, + assertions: func(t *testing.T, ctx sdk.Context, res []types.ResponseDeliverTx) { + for idx, response := range res { + if idx == 0 { + require.Equal(t, "", response.Info) + } else { + // the info is what was read from the kv store by the tx + // each tx writes its own index, so the info should be the index of the previous tx + require.Equal(t, fmt.Sprintf("%d", idx-1), response.Info) + } + } + // confirm last write made it to the parent store + latest := ctx.MultiStore().GetKVStore(testStoreKey).Get(itemKey) + require.Equal(t, []byte(fmt.Sprintf("%d", len(res)-1)), latest) + }, + expectedErr: nil, + }, + { + name: "Test some tx accesses same key", + workers: 50, + runs: 1, + addStores: true, + requests: requestList(2000), + deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res types.ResponseDeliverTx) { + defer abortRecoveryFunc(&res) + if ctx.TxIndex()%10 != 0 { + return types.ResponseDeliverTx{ + Info: "none", + } + } + // all txs read and write to the same key to maximize conflicts + kv := ctx.MultiStore().GetKVStore(testStoreKey) + val := string(kv.Get(itemKey)) + + // write to the store with this tx's index + kv.Set(itemKey, req.Tx) + + // return what was read from the store (final attempt should be index-1) + return types.ResponseDeliverTx{ + Info: val, + } + }, + assertions: func(t *testing.T, ctx sdk.Context, res []types.ResponseDeliverTx) {}, + expectedErr: nil, + }, + { + name: "Test no stores on context should not panic", + workers: 50, + runs: 10, + addStores: false, + requests: requestList(10), + deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res types.ResponseDeliverTx) { + defer abortRecoveryFunc(&res) + return types.ResponseDeliverTx{ + Info: fmt.Sprintf("%d", ctx.TxIndex()), + } + }, + assertions: func(t *testing.T, ctx sdk.Context, res []types.ResponseDeliverTx) { + for idx, response := range res { + require.Equal(t, fmt.Sprintf("%d", idx), response.Info) + } + }, + expectedErr: nil, + }, + { + name: "Test every tx accesses same key with estimated writesets", + workers: 50, + runs: 1, + addStores: true, + requests: requestListWithEstimatedWritesets(1000), + deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res types.ResponseDeliverTx) { + defer abortRecoveryFunc(&res) + // all txs read and write to the same key to maximize conflicts + kv := ctx.MultiStore().GetKVStore(testStoreKey) + val := string(kv.Get(itemKey)) + + // write to the store with this tx's index + kv.Set(itemKey, req.Tx) + + // return what was read from the store (final attempt should be index-1) + return types.ResponseDeliverTx{ + Info: val, + } + }, + assertions: func(t *testing.T, ctx sdk.Context, res []types.ResponseDeliverTx) { + for idx, response := range res { + if idx == 0 { + require.Equal(t, "", response.Info) + } else { + // the info is what was read from the kv store by the tx + // each tx writes its own index, so the info should be the index of the previous tx + require.Equal(t, fmt.Sprintf("%d", idx-1), response.Info) + } + } + // confirm last write made it to the parent store + latest := ctx.MultiStore().GetKVStore(testStoreKey).Get(itemKey) + require.Equal(t, []byte(fmt.Sprintf("%d", len(res)-1)), latest) + }, + expectedErr: nil, + }, + { + name: "Test every tx accesses same key with delays", + workers: 50, + runs: 1, + addStores: true, + requests: requestList(1000), + deliverTxFunc: func(ctx sdk.Context, req types.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res types.ResponseDeliverTx) { + defer abortRecoveryFunc(&res) + wait := rand.Intn(10) + time.Sleep(time.Duration(wait) * time.Millisecond) + // all txs read and write to the same key to maximize conflicts + kv := ctx.MultiStore().GetKVStore(testStoreKey) + val := string(kv.Get(itemKey)) + time.Sleep(time.Duration(wait) * time.Millisecond) + // write to the store with this tx's index + newVal := val + fmt.Sprintf("%d", ctx.TxIndex()) + kv.Set(itemKey, []byte(newVal)) + + // return what was read from the store (final attempt should be index-1) + return types.ResponseDeliverTx{ + Info: newVal, + } + }, + assertions: func(t *testing.T, ctx sdk.Context, res []types.ResponseDeliverTx) { + expected := "" + for idx, response := range res { + expected = expected + fmt.Sprintf("%d", idx) + require.Equal(t, expected, response.Info) + } + // confirm last write made it to the parent store + latest := ctx.MultiStore().GetKVStore(testStoreKey).Get(itemKey) + require.Equal(t, expected, string(latest)) + }, + expectedErr: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + for i := 0; i < tt.runs; i++ { + // set a tracer provider + tp := trace.NewNoopTracerProvider() + otel.SetTracerProvider(trace.NewNoopTracerProvider()) + tr := tp.Tracer("scheduler-test") + ti := &tracing.Info{ + Tracer: &tr, + } + + s := NewScheduler(tt.workers, ti, tt.deliverTxFunc) + ctx := initTestCtx(tt.addStores) + + if tt.before != nil { + tt.before(ctx) + } + + res, err := s.ProcessAll(ctx, tt.requests) + require.Len(t, res, len(tt.requests)) + + if !errors.Is(err, tt.expectedErr) { + t.Errorf("Expected error %v, got %v", tt.expectedErr, err) + } else { + tt.assertions(t, ctx, res) + } + } + }) + } +} diff --git a/tasksv2/task.go b/tasksv2/task.go new file mode 100644 index 000000000..adc45d4d1 --- /dev/null +++ b/tasksv2/task.go @@ -0,0 +1,214 @@ +package tasksv2 + +import ( + "github.com/cosmos/cosmos-sdk/store/multiversion" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/occ" + "github.com/tendermint/tendermint/abci/types" + "sync" + "sync/atomic" +) + +type status string + +const ( + // statusPending tasks are ready for execution + // all executing tasks are in pending state + statusPending status = "pending" + // statusExecuted tasks are ready for validation + // these tasks did not abort during execution + statusExecuted status = "executed" + // statusAborted means the task has been aborted + // these tasks transition to pending upon next execution + statusAborted status = "aborted" + // statusValidated means the task has been validated + // tasks in this status can be reset if an earlier task fails validation + statusValidated status = "validated" + // statusInvalid means the task has been invalidated + statusInvalid status = "invalid" + // statusWaiting tasks are waiting for another tx to complete + statusWaiting status = "waiting" +) + +type TxTask struct { + Ctx sdk.Context + AbortCh chan occ.Abort + rwMx sync.RWMutex + mx sync.Mutex + taskType TaskType + status status + ExecutionID string + Parents []int + Dependents *intSetMap + Abort *occ.Abort + AbsoluteIndex int + Executing byte + Validating byte + Incarnation int + Request types.RequestDeliverTx + Response *types.ResponseDeliverTx + VersionStores map[sdk.StoreKey]*multiversion.VersionIndexedStore + + SdkTx sdk.Tx + Checksum [32]byte +} + +func (dt *TxTask) LockTask() { + dt.mx.Lock() +} + +func (dt *TxTask) TryLockTask() bool { + return dt.mx.TryLock() +} + +func (dt *TxTask) UnlockTask() { + dt.mx.Unlock() +} + +func (dt *TxTask) IsStatus(s status) bool { + dt.rwMx.RLock() + defer dt.rwMx.RUnlock() + return dt.status == s +} + +func (dt *TxTask) SetTaskType(tt TaskType) bool { + // Early check to potentially avoid locking. + if tt == TypeValidation && dt.taskType == TypeNone && dt.Response != nil { + return dt.updateTaskType(tt) + } else if tt == TypeExecution && dt.taskType != TypeExecution { + return dt.updateTaskType(tt) + } + return false +} + +// updateTaskType assumes that an update is likely needed and does the final check within the lock. +func (dt *TxTask) updateTaskType(tt TaskType) bool { + dt.rwMx.Lock() + defer dt.rwMx.Unlock() + if tt == TypeValidation && dt.taskType == TypeNone { + dt.taskType = tt + return true + } else if tt == TypeExecution && dt.taskType != TypeExecution { + dt.taskType = tt + return true + } + return false +} + +func (dt *TxTask) IsTaskType(tt TaskType) bool { + dt.rwMx.RLock() + defer dt.rwMx.RUnlock() + return dt.taskType == tt +} + +func (dt *TxTask) PopTaskType() (TaskType, bool) { + dt.rwMx.Lock() + defer dt.rwMx.Unlock() + tt := dt.taskType + dt.taskType = TypeNone + return tt, tt != TypeNone +} + +func (dt *TxTask) SetStatus(s status) { + dt.rwMx.Lock() + defer dt.rwMx.Unlock() + dt.status = s +} + +func (dt *TxTask) Status() status { + dt.rwMx.RLock() + defer dt.rwMx.RUnlock() + return dt.status +} + +func (dt *TxTask) IsInvalid() bool { + dt.rwMx.RLock() + defer dt.rwMx.RUnlock() + return dt.status == statusInvalid || dt.status == statusAborted +} + +func (dt *TxTask) IsValid() bool { + dt.rwMx.RLock() + defer dt.rwMx.RUnlock() + return dt.status == statusValidated +} + +func (dt *TxTask) IsWaiting() bool { + dt.rwMx.RLock() + defer dt.rwMx.RUnlock() + return dt.status == statusWaiting +} + +func (dt *TxTask) Reset() { + dt.rwMx.Lock() + defer dt.rwMx.Unlock() + dt.status = statusPending + dt.Response = nil + dt.Abort = nil + dt.AbortCh = nil + dt.Parents = nil + dt.VersionStores = nil +} + +func (dt *TxTask) ResetForExecution() { + dt.rwMx.Lock() + defer dt.rwMx.Unlock() + dt.status = statusPending + dt.Response = nil + dt.Abort = nil + dt.AbortCh = nil + dt.Parents = nil + dt.VersionStores = nil +} + +func (dt *TxTask) Increment() { + dt.Incarnation++ +} + +// syncSet uses byte slices instead of a map (fastest benchmark) +type syncSet struct { + locks []sync.RWMutex + state []byte + length int32 +} + +func newSyncSet(size int) *syncSet { + return &syncSet{ + state: make([]byte, size), + locks: make([]sync.RWMutex, size), + } +} + +func (ss *syncSet) Add(idx int) { + // First check without locking to reduce contention. + if ss.state[idx] == byte(0) { + ss.locks[idx].Lock() + // Check again to make sure it hasn't changed since acquiring the lock. + if ss.state[idx] == byte(0) { + ss.state[idx] = byte(1) + atomic.AddInt32(&ss.length, 1) + } + ss.locks[idx].Unlock() + } +} + +func (ss *syncSet) Delete(idx int) { + ss.locks[idx].Lock() + defer ss.locks[idx].Unlock() + + // Check again to make sure it hasn't changed since acquiring the lock. + if ss.state[idx] == byte(1) { + ss.state[idx] = byte(0) + atomic.AddInt32(&ss.length, -1) + } + +} + +func (ss *syncSet) Length() int { + return int(atomic.LoadInt32(&ss.length)) +} + +func (ss *syncSet) Exists(idx int) bool { + // Atomic read of a single byte is safe + return ss.state[idx] == byte(1) +} diff --git a/tasksv2/task_execution.go b/tasksv2/task_execution.go new file mode 100644 index 000000000..1d4503d43 --- /dev/null +++ b/tasksv2/task_execution.go @@ -0,0 +1,81 @@ +package tasksv2 + +import ( + "github.com/cosmos/cosmos-sdk/store/multiversion" + store "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/occ" +) + +// prepareTask initializes the context and version stores for a task +func (s *scheduler) prepareTask(task *TxTask) { + ctx := task.Ctx.WithTxIndex(task.AbsoluteIndex) + + _, span := s.traceSpan(ctx, "SchedulerPrepare", task) + defer span.End() + + // initialize the context + abortCh := make(chan occ.Abort, len(s.multiVersionStores)) + + // if there are no stores, don't try to wrap, because there's nothing to wrap + if len(s.multiVersionStores) > 0 { + // non-blocking + cms := ctx.MultiStore().CacheMultiStore() + + // init version stores by store key + vs := make(map[store.StoreKey]*multiversion.VersionIndexedStore) + for storeKey, mvs := range s.multiVersionStores { + vs[storeKey] = mvs.VersionedIndexedStore(task.AbsoluteIndex, task.Incarnation, abortCh) + } + + // save off version store so we can ask it things later + task.VersionStores = vs + ms := cms.SetKVStores(func(k store.StoreKey, kvs sdk.KVStore) store.CacheWrap { + return vs[k] + }) + + ctx = ctx.WithMultiStore(ms) + } + + task.AbortCh = abortCh + task.Ctx = ctx +} + +// executeTask executes a single task +func (s *scheduler) executeTask(task *TxTask) { + dCtx, dSpan := s.traceSpan(task.Ctx, "SchedulerExecuteTask", task) + defer dSpan.End() + task.Ctx = dCtx + + s.prepareTask(task) + + resp := s.deliverTx(task.Ctx, task.Request, task.SdkTx, task.Checksum) + + // if an abort occurred, we want to handle that at this level + if resp.Codespace == errors.ErrOCCAbort.Codespace() && resp.Code == errors.ErrOCCAbort.ABCICode() { + // close the abort channel + close(task.AbortCh) + + task.SetStatus(statusAborted) + // read the first abort from the channel + abort, ok := <-task.AbortCh + if ok { + // if there is an abort item that means we need to wait on the dependent tx + task.Abort = &abort + } + // write from version store to multiversion stores + for _, v := range task.VersionStores { + v.WriteEstimatesToMultiVersionStore() + } + return + } + + task.SetStatus(statusExecuted) + task.Response = &resp + + // write from version store to multiversion stores + for _, v := range task.VersionStores { + v.WriteToMultiVersionStore() + } +} diff --git a/tasksv2/task_queue.go b/tasksv2/task_queue.go new file mode 100644 index 000000000..bdd40c357 --- /dev/null +++ b/tasksv2/task_queue.go @@ -0,0 +1,234 @@ +package tasksv2 + +import ( + "fmt" + "sort" + "sync" + "sync/atomic" +) + +type TaskType string + +const ( + TypeNone TaskType = "NONE" + TypeExecution TaskType = "EXECUTE" + TypeValidation TaskType = "VALIDATE" +) + +type Queue interface { + // AddDependentToParents adds a dependent to the parents + AddDependentToParents(idx int) + // NextTask returns the next task to be executed, or nil if the queue is closed. + NextTask(workerID int) (*TxTask, bool) + // Close closes the queue, causing NextTask to return false. + Close() + // ExecuteAll executes all tasks in the queue. + ExecuteAll() + // Execute executes a task + Execute(idx int) + // ReValidate re-validates a task. + ReValidate(idx int) + // FinishExecute marks a task as finished executing. + FinishExecute(idx int) + // FinishTask marks a task as finished (only upon valid). + FinishTask(idx int) + // ValidateAll marks all tasks as pending validation. + ValidateAll() + // ValidateLaterTasks marks all tasks after the given index as pending validation. + ValidateLaterTasks(afterIdx int) + // IsCompleted returns true if all tasks have been executed and validated. + IsCompleted() bool + // DependenciesFinished returns whether all dependencies are finished + DependenciesFinished(idx int) bool +} + +type taskQueue struct { + lockTimerID string + qmx sync.RWMutex + once sync.Once + executing IntSet + finished IntSet + queueLen atomic.Int64 + closed bool + workers int + shards []chan int + tasks []*TxTask +} + +func NewTaskQueue(tasks []*TxTask, workers int) Queue { + shards := make([]chan int, 0, workers) + for i := 0; i < workers; i++ { + shards = append(shards, make(chan int, len(tasks)*2)) + } + sq := &taskQueue{ + workers: workers, + tasks: tasks, + shards: shards, + finished: newIntSet(len(tasks)), // newSyncSetMap(), //(len(tasks)), + executing: newIntSet(len(tasks)), + } + return sq +} + +func (sq *taskQueue) execute(idx int) { + if sq.getTask(idx).SetTaskType(TypeExecution) { + sq.finished.Delete(idx) + sq.executing.Add(idx) + sq.pushTask(idx, TypeExecution) + } +} + +func (sq *taskQueue) getTask(idx int) *TxTask { + return sq.tasks[idx] +} + +func (sq *taskQueue) validate(idx int) { + task := sq.getTask(idx) + if task.SetTaskType(TypeValidation) { + sq.pushTask(idx, TypeValidation) + } +} + +func (sq *taskQueue) isExecuting(idx int) bool { + return sq.executing.Exists(idx) +} + +// FinishExecute marks a task as finished executing and transitions directly validation +func (sq *taskQueue) FinishExecute(idx int) { + t := sq.getTask(idx) + defer TaskLog(t, "-> finished task execute") + + //if !sq.isExecuting(idx) { + // TaskLog(sq.getTask(idx), "not executing, but trying to finish execute") + // panic("not executing, but trying to finish execute") + //} + //TODO: optimize + t.LockTask() + if t.Dependents.Length() > 0 { + dependentTasks := t.Dependents.List() + sort.Ints(dependentTasks) + for _, d := range dependentTasks { + sq.execute(d) + } + } + t.UnlockTask() + + sq.executing.Delete(idx) + sq.validate(idx) +} + +// FinishTask marks a task as finished if nothing else queued it +// this drives whether the queue thinks everything is done processing +func (sq *taskQueue) FinishTask(idx int) { + sq.finished.Add(idx) + TaskLog(sq.getTask(idx), "FinishTask -> task is FINISHED (for now)") +} + +// ReValidate re-validates a task (back to queue from validation) +func (sq *taskQueue) ReValidate(idx int) { + //if sq.isExecuting(idx) { + // TaskLog(sq.getTask(idx), "task is executing (unexpected)") + // panic("cannot re-validate an executing task") + //} + sq.validate(idx) +} + +func (sq *taskQueue) Execute(idx int) { + task := sq.tasks[idx] + task.Increment() + sq.execute(idx) +} + +func (sq *taskQueue) ValidateAll() { + for idx := 0; idx < len(sq.tasks); idx++ { + sq.validate(idx) + } +} + +// ValidateLaterTasks marks all tasks after the given index as pending validation. +// any executing tasks are skipped +func (sq *taskQueue) ValidateLaterTasks(afterIdx int) { + for idx := afterIdx + 1; idx < len(sq.tasks); idx++ { + if !sq.isExecuting(idx) { + sq.validate(idx) + } + } +} + +func (sq *taskQueue) isFinished(idx int) bool { + return sq.finished.Exists(idx) && sq.getTask(idx).IsStatus(statusValidated) +} + +func (sq *taskQueue) DependenciesFinished(idx int) bool { + for _, dep := range sq.getTask(idx).Parents { + if !sq.isFinished(dep) { + return false + } + } + return true +} + +func (sq *taskQueue) AddDependentToParents(idx int) { + parents := sq.getTask(idx).Parents + for _, p := range parents { + sq.getTask(p).Dependents.Add(idx) + } +} + +// IsCompleted returns true if all tasks are "finished" +func (sq *taskQueue) IsCompleted() bool { + queued := sq.queueLen.Load() + if queued > 0 { + return false + } + finished := sq.finished.Length() + tasks := len(sq.tasks) + if finished != tasks { + return false + } + return true +} + +func (sq *taskQueue) pushTask(idx int, taskType TaskType) { + TaskLog(sq.getTask(idx), fmt.Sprintf("-> %s task", taskType)) + sq.queueLen.Add(1) + sq.qmx.RLock() + defer sq.qmx.RUnlock() + if sq.closed { + TaskLog(sq.getTask(idx), "queue is closed") + return + } + sq.shards[idx%sq.workers] <- idx +} + +// ExecuteAll executes all tasks in the queue (called to start processing) +func (sq *taskQueue) ExecuteAll() { + for idx := range sq.tasks { + sq.execute(idx) + } +} + +// NextTask returns the next task to be executed, or nil if the queue is closed. +// this hangs if no tasks are ready because it's possible a new task might arrive +// closing the queue causes NextTask to return false immediately +func (sq *taskQueue) NextTask(workerID int) (*TxTask, bool) { + idx, open := <-sq.shards[workerID] + if !open { + return nil, false + } + defer sq.queueLen.Add(-1) + res := sq.getTask(idx) + return res, true +} + +// Close closes the queue, causing NextTask to return false. +func (sq *taskQueue) Close() { + sq.once.Do(func() { + sq.qmx.Lock() + defer sq.qmx.Unlock() + sq.closed = true + for _, shard := range sq.shards { + close(shard) + } + }) +} diff --git a/tasksv2/task_queue_test.go b/tasksv2/task_queue_test.go new file mode 100644 index 000000000..2e4cba1b6 --- /dev/null +++ b/tasksv2/task_queue_test.go @@ -0,0 +1,89 @@ +package tasksv2 + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func generateTasks(count int) []*TxTask { + var res []*TxTask + for i := 0; i < count; i++ { + res = append(res, &TxTask{AbsoluteIndex: i}) + } + return res +} + +func assertExecuting(t *testing.T, task *TxTask) { + + assert.True(t, task.taskType == TypeExecution) +} + +func assertValidating(t *testing.T, task *TxTask) { + assert.True(t, task.taskType == TypeValidation) +} + +func testQueue() (Queue, []*TxTask) { + tasks := generateTasks(10) + return NewTaskQueue(tasks, 1), tasks +} + +func TestSchedulerQueue(t *testing.T) { + queue, tasks := testQueue() + + // Test ExecuteAll + queue.ExecuteAll() + for _, task := range tasks { + assertExecuting(t, task) + } + + // Test NextTask + nextTask, ok := queue.NextTask(0) + assert.True(t, ok) + assert.Equal(t, tasks[0], nextTask) + + // Test Close + queue.Close() + for ok { + nextTask, ok = queue.NextTask(0) + } + assert.False(t, ok) + + // Test FinishExecute leads to Validation + queue, tasks = testQueue() + queue.ExecuteAll() + nextTask, ok = queue.NextTask(0) + assert.True(t, ok) + nextTask.PopTaskType() + queue.FinishExecute(nextTask.AbsoluteIndex) + assertValidating(t, nextTask) + + // Test that validation doesn't happen for executing task + queue, tasks = testQueue() + queue.ExecuteAll() + queue.ValidateLaterTasks(-1) + nextTask, ok = queue.NextTask(0) + assert.True(t, ok) + assertExecuting(t, nextTask) // still executing + + // Test that validation happens for finished tasks + queue, tasks = testQueue() + queue.ExecuteAll() + queue.ValidateLaterTasks(-1) + nextTask, ok = queue.NextTask(0) + assert.True(t, ok) + assertExecuting(t, nextTask) + + // Test IsCompleted + queue, tasks = testQueue() + queue.ExecuteAll() + + for idx, task := range tasks { + task.SetStatus(statusValidated) + queue.NextTask(0) + queue.FinishTask(idx) + if idx == len(tasks)-1 { + queue.Close() + } + } + assert.True(t, queue.IsCompleted()) +} diff --git a/tasksv2/task_validation.go b/tasksv2/task_validation.go new file mode 100644 index 000000000..4ebc2ce33 --- /dev/null +++ b/tasksv2/task_validation.go @@ -0,0 +1,68 @@ +package tasksv2 + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "sort" +) + +func (s *scheduler) findConflicts(task *TxTask) (bool, []int) { + var conflicts []int + uniq := make(map[int]struct{}) + valid := true + for _, mv := range s.multiVersionStores { + ok, mvConflicts := mv.ValidateTransactionState(task.AbsoluteIndex) + for _, c := range mvConflicts { + if _, ok := uniq[c]; !ok { + conflicts = append(conflicts, c) + uniq[c] = struct{}{} + } + } + // any non-ok value makes valid false + valid = ok && valid + } + sort.Ints(conflicts) + return valid, conflicts +} + +func (s *scheduler) invalidateTask(task *TxTask) { + for _, mv := range s.multiVersionStores { + mv.InvalidateWriteset(task.AbsoluteIndex, task.Incarnation) + mv.ClearReadset(task.AbsoluteIndex) + mv.ClearIterateset(task.AbsoluteIndex) + } +} + +func (s *scheduler) mockValidateTask(ctx sdk.Context, task *TxTask) { + task.SetStatus(statusValidated) +} + +func (s *scheduler) validateTask(ctx sdk.Context, task *TxTask) { + _, span := s.traceSpan(ctx, "SchedulerValidate", task) + defer span.End() + + if task.Response == nil { + task.SetStatus(statusInvalid) + return + } + + valid, conflicts := s.findConflicts(task) + task.Parents = conflicts + + if !valid { + s.invalidateTask(task) + if len(conflicts) > 0 { + task.SetStatus(statusWaiting) + return + } + task.SetStatus(statusInvalid) + return + } + + if len(conflicts) > 0 { + task.SetStatus(statusWaiting) + return + } + + task.SetStatus(statusValidated) + +} diff --git a/tasksv2/timer.go b/tasksv2/timer.go new file mode 100644 index 000000000..ca2104efc --- /dev/null +++ b/tasksv2/timer.go @@ -0,0 +1,123 @@ +package tasksv2 + +import ( + "github.com/google/uuid" + + "fmt" + "sort" + "strings" + "sync" + "time" +) + +type Timer struct { + name string + mx sync.Mutex + reports map[string]*TimerReport + ch chan timeEvt +} + +type timeEvt struct { + start bool + name string + id string + timestamp time.Time +} + +type TimerReport struct { + name string + initial time.Time + starts map[string]time.Time + times []time.Duration +} + +func NewTimer(name string) *Timer { + t := &Timer{ + name: name, + reports: make(map[string]*TimerReport), + ch: make(chan timeEvt, 10000), + } + return t +} + +func (t *Timer) PrintReport() { + t.mx.Lock() + defer t.mx.Unlock() + + var reports []*TimerReport + for name, rpt := range t.reports { + rpt.name = name + reports = append(reports, rpt) + } + + // Sort the slice by the sum of durations + sort.Slice(reports, func(i, j int) bool { + sumI := time.Duration(0) + for _, d := range reports[i].times { + sumI += d + } + + sumJ := time.Duration(0) + for _, d := range reports[j].times { + sumJ += d + } + + return sumI < sumJ + }) + + lines := []string{} + for _, rpt := range reports { + var sum time.Duration + count := len(rpt.times) + minDuration := time.Hour + maxDuration := time.Duration(0) + for _, d := range rpt.times { + sum += d + if d < minDuration { + minDuration = d + } + if d > maxDuration { + maxDuration = d + } + } + if count == 0 { + continue + } + avg := sum / time.Duration(count) + lines = append(lines, fmt.Sprintf("%-15s: \tsum=%-15s\tavg=%-15s\tmin=%-15s\tmax=%-15s\tcount=%-15d %s", t.name, sum, avg, minDuration, maxDuration, count, rpt.name)) + } + fmt.Println(strings.Join(lines, "\n")) +} + +func WithTimer(t *Timer, name string, work func()) { + id := t.Start(name) + work() + t.End(name, id) +} + +func (t *Timer) Start(name string) string { + id := uuid.New().String() + go func() { + t.mx.Lock() + defer t.mx.Unlock() + + if _, ok := t.reports[name]; !ok { + t.reports[name] = &TimerReport{ + starts: make(map[string]time.Time), + times: nil, + } + } + t.reports[name].starts[id] = time.Now() + }() + return id +} + +func (t *Timer) End(name string, id string) { + t.mx.Lock() + defer t.mx.Unlock() + if rpt, ok := t.reports[name]; ok { + if start, ok := rpt.starts[id]; ok { + rpt.times = append(rpt.times, time.Now().Sub(start)) + } + } +} diff --git a/tasksv2/utils.go b/tasksv2/utils.go new file mode 100644 index 000000000..4fbd6a1b1 --- /dev/null +++ b/tasksv2/utils.go @@ -0,0 +1,104 @@ +package tasksv2 + +import ( + "context" + "github.com/cosmos/cosmos-sdk/store/multiversion" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/tendermint/tendermint/abci/types" + "go.opentelemetry.io/otel/trace" + "sort" + "time" +) + +// TODO: remove after things work +func TaskLog(task *TxTask, msg string) { + // helpful for debugging state transitions + //fmt.Println(fmt.Sprintf("%d: Task(%d/%s/%d):\t%s", time.Now().UnixMicro(), task.AbsoluteIndex, task.status, task.Incarnation, msg)) +} + +type Endable interface { + End(options ...trace.SpanEndOption) +} + +type mockEndable struct{} + +func (m *mockEndable) End(options ...trace.SpanEndOption) {} + +func (s *scheduler) traceSpan(ctx sdk.Context, name string, task *TxTask) (sdk.Context, Endable) { + //spanCtx, span := s.tracingInfo.StartWithContext(name, ctx.TraceSpanContext()) + //if task != nil { + // span.SetAttributes(attribute.String("txHash", fmt.Sprintf("%X", sha256.Sum256(task.Request.Tx)))) + // span.SetAttributes(attribute.Int("txIndex", task.AbsoluteIndex)) + // span.SetAttributes(attribute.Int("txIncarnation", task.Incarnation)) + //} + //ctx = ctx.WithTraceSpanContext(spanCtx) + //return ctx, span + return ctx, &mockEndable{} +} + +func hangDebug(msg func()) context.CancelFunc { + ctx, cancel := context.WithCancel(context.Background()) + ticker := time.NewTicker(1 * time.Second) + go func() { + for { + select { + case <-ticker.C: + msg() + case <-ctx.Done(): + return + } + } + }() + return cancel +} + +func toTasks(ctx sdk.Context, reqs []*sdk.DeliverTxEntry) []*TxTask { + res := make([]*TxTask, 0, len(reqs)) + for _, r := range reqs { + res = append(res, &TxTask{ + Request: r.Request, + AbsoluteIndex: r.AbsoluteIndex, + SdkTx: r.SdkTx, + Checksum: r.Checksum, + Dependents: &intSetMap{ + m: make(map[int]struct{}), + }, + Ctx: ctx, + status: statusPending, + }) + } + // sort by AbsoluteIndex + sort.Slice(res, func(i, j int) bool { + return res[i].AbsoluteIndex < res[j].AbsoluteIndex + }) + return res +} + +func collectResponses(tasks []*TxTask) []types.ResponseDeliverTx { + res := make([]types.ResponseDeliverTx, 0, len(tasks)) + for _, t := range tasks { + res = append(res, *t.Response) + } + return res +} + +func (s *scheduler) initMultiVersionStore(ctx sdk.Context) { + mvs := make(map[sdk.StoreKey]multiversion.MultiVersionStore) + keys := ctx.MultiStore().StoreKeys() + for _, sk := range keys { + mvs[sk] = multiversion.NewMultiVersionStore(ctx.MultiStore().GetKVStore(sk)) + } + s.multiVersionStores = mvs +} + +func (s *scheduler) PrefillEstimates(reqs []*sdk.DeliverTxEntry) { + // iterate over TXs, update estimated writesets where applicable + for i, req := range reqs { + mappedWritesets := req.EstimatedWritesets + // order shouldnt matter for storeKeys because each storeKey partitioned MVS is independent + for storeKey, writeset := range mappedWritesets { + // we use `-1` to indicate a prefill incarnation + s.multiVersionStores[storeKey].SetEstimatedWriteset(i, -1, writeset) + } + } +} From 73e95cb2ff07f43cd8c5fcba83dbad360b88246b Mon Sep 17 00:00:00 2001 From: Steven Landers Date: Fri, 15 Mar 2024 11:06:08 -0400 Subject: [PATCH 28/39] fix datarace --- tasksv2/task.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tasksv2/task.go b/tasksv2/task.go index adc45d4d1..920a8ecc8 100644 --- a/tasksv2/task.go +++ b/tasksv2/task.go @@ -72,7 +72,8 @@ func (dt *TxTask) IsStatus(s status) bool { } func (dt *TxTask) SetTaskType(tt TaskType) bool { - // Early check to potentially avoid locking. + dt.rwMx.Lock() + defer dt.rwMx.Unlock() if tt == TypeValidation && dt.taskType == TypeNone && dt.Response != nil { return dt.updateTaskType(tt) } else if tt == TypeExecution && dt.taskType != TypeExecution { @@ -83,8 +84,6 @@ func (dt *TxTask) SetTaskType(tt TaskType) bool { // updateTaskType assumes that an update is likely needed and does the final check within the lock. func (dt *TxTask) updateTaskType(tt TaskType) bool { - dt.rwMx.Lock() - defer dt.rwMx.Unlock() if tt == TypeValidation && dt.taskType == TypeNone { dt.taskType = tt return true From 1823afc9e983aa1ac8c3a25f746a8c35f017fc68 Mon Sep 17 00:00:00 2001 From: Steven Landers Date: Fri, 15 Mar 2024 11:30:21 -0400 Subject: [PATCH 29/39] fix stale tests --- tasksv2/scheduler.go | 2 +- tasksv2/task.go | 17 ++++++----------- tasksv2/task_queue.go | 4 ++-- tasksv2/task_queue_test.go | 16 ++++++++++++---- tasksv2/task_validation.go | 4 +++- tasksv2/utils.go | 3 +++ 6 files changed, 27 insertions(+), 19 deletions(-) diff --git a/tasksv2/scheduler.go b/tasksv2/scheduler.go index fdac27771..b11be45bc 100644 --- a/tasksv2/scheduler.go +++ b/tasksv2/scheduler.go @@ -186,7 +186,7 @@ func (s *scheduler) processTask(ctx sdk.Context, taskType TaskType, w int, t *Tx parent := s.tasks[t.Abort.DependentTxIdx] parent.LockTask() if parent.IsTaskType(TypeExecution) { - t.Parents = []int{t.Abort.DependentTxIdx} + t.Parents.Add(t.Abort.DependentTxIdx) queue.AddDependentToParents(t.AbsoluteIndex) } else { queue.Execute(t.AbsoluteIndex) diff --git a/tasksv2/task.go b/tasksv2/task.go index 920a8ecc8..0eb77c1cf 100644 --- a/tasksv2/task.go +++ b/tasksv2/task.go @@ -38,7 +38,7 @@ type TxTask struct { taskType TaskType status status ExecutionID string - Parents []int + Parents *intSetMap Dependents *intSetMap Abort *occ.Abort AbsoluteIndex int @@ -145,7 +145,6 @@ func (dt *TxTask) Reset() { dt.Response = nil dt.Abort = nil dt.AbortCh = nil - dt.Parents = nil dt.VersionStores = nil } @@ -156,7 +155,6 @@ func (dt *TxTask) ResetForExecution() { dt.Response = nil dt.Abort = nil dt.AbortCh = nil - dt.Parents = nil dt.VersionStores = nil } @@ -179,15 +177,12 @@ func newSyncSet(size int) *syncSet { } func (ss *syncSet) Add(idx int) { - // First check without locking to reduce contention. + ss.locks[idx].Lock() + defer ss.locks[idx].Unlock() + // Check again to make sure it hasn't changed since acquiring the lock. if ss.state[idx] == byte(0) { - ss.locks[idx].Lock() - // Check again to make sure it hasn't changed since acquiring the lock. - if ss.state[idx] == byte(0) { - ss.state[idx] = byte(1) - atomic.AddInt32(&ss.length, 1) - } - ss.locks[idx].Unlock() + ss.state[idx] = byte(1) + atomic.AddInt32(&ss.length, 1) } } diff --git a/tasksv2/task_queue.go b/tasksv2/task_queue.go index bdd40c357..534a00c7f 100644 --- a/tasksv2/task_queue.go +++ b/tasksv2/task_queue.go @@ -160,7 +160,7 @@ func (sq *taskQueue) isFinished(idx int) bool { } func (sq *taskQueue) DependenciesFinished(idx int) bool { - for _, dep := range sq.getTask(idx).Parents { + for _, dep := range sq.getTask(idx).Parents.List() { if !sq.isFinished(dep) { return false } @@ -170,7 +170,7 @@ func (sq *taskQueue) DependenciesFinished(idx int) bool { func (sq *taskQueue) AddDependentToParents(idx int) { parents := sq.getTask(idx).Parents - for _, p := range parents { + for _, p := range parents.List() { sq.getTask(p).Dependents.Add(idx) } } diff --git a/tasksv2/task_queue_test.go b/tasksv2/task_queue_test.go index 2e4cba1b6..777d6baf0 100644 --- a/tasksv2/task_queue_test.go +++ b/tasksv2/task_queue_test.go @@ -2,24 +2,30 @@ package tasksv2 import ( "github.com/stretchr/testify/assert" + "github.com/tendermint/tendermint/abci/types" "testing" ) func generateTasks(count int) []*TxTask { var res []*TxTask for i := 0; i < count; i++ { - res = append(res, &TxTask{AbsoluteIndex: i}) + res = append(res, &TxTask{AbsoluteIndex: i, + Parents: &intSetMap{ + m: make(map[int]struct{}), + }, + Dependents: &intSetMap{ + m: make(map[int]struct{}), + }}) } return res } func assertExecuting(t *testing.T, task *TxTask) { - - assert.True(t, task.taskType == TypeExecution) + assert.Equal(t, TypeExecution, task.taskType) } func assertValidating(t *testing.T, task *TxTask) { - assert.True(t, task.taskType == TypeValidation) + assert.Equal(t, TypeValidation, task.taskType) } func testQueue() (Queue, []*TxTask) { @@ -54,6 +60,8 @@ func TestSchedulerQueue(t *testing.T) { nextTask, ok = queue.NextTask(0) assert.True(t, ok) nextTask.PopTaskType() + // mock so it's not nil, because no execution actually happened here + nextTask.Response = &types.ResponseDeliverTx{} queue.FinishExecute(nextTask.AbsoluteIndex) assertValidating(t, nextTask) diff --git a/tasksv2/task_validation.go b/tasksv2/task_validation.go index 4ebc2ce33..2ad44c48c 100644 --- a/tasksv2/task_validation.go +++ b/tasksv2/task_validation.go @@ -46,7 +46,9 @@ func (s *scheduler) validateTask(ctx sdk.Context, task *TxTask) { } valid, conflicts := s.findConflicts(task) - task.Parents = conflicts + for _, c := range conflicts { + task.Parents.Add(c) + } if !valid { s.invalidateTask(task) diff --git a/tasksv2/utils.go b/tasksv2/utils.go index 4fbd6a1b1..c6fbe0d39 100644 --- a/tasksv2/utils.go +++ b/tasksv2/utils.go @@ -60,6 +60,9 @@ func toTasks(ctx sdk.Context, reqs []*sdk.DeliverTxEntry) []*TxTask { AbsoluteIndex: r.AbsoluteIndex, SdkTx: r.SdkTx, Checksum: r.Checksum, + Parents: &intSetMap{ + m: make(map[int]struct{}), + }, Dependents: &intSetMap{ m: make(map[int]struct{}), }, From d78d9346f22af908408c58679a8f8568e951d850 Mon Sep 17 00:00:00 2001 From: Steven Landers Date: Fri, 15 Mar 2024 11:37:58 -0400 Subject: [PATCH 30/39] fix other potential race --- tasksv2/int_set.go | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/tasksv2/int_set.go b/tasksv2/int_set.go index 282b15b85..2e823ee5e 100644 --- a/tasksv2/int_set.go +++ b/tasksv2/int_set.go @@ -115,28 +115,21 @@ func newIntSetByteSlice(size int) *syncSet { } func (ss *intSetByteSlice) Add(idx int) { - // First check without locking to reduce contention. + ss.locks[idx].Lock() + defer ss.locks[idx].Unlock() if ss.state[idx] == byte(0) { - ss.locks[idx].Lock() - // Check again to make sure it hasn't changed since acquiring the lock. - if ss.state[idx] == byte(0) { - ss.state[idx] = byte(1) - atomic.AddInt32(&ss.length, 1) - } - ss.locks[idx].Unlock() + ss.state[idx] = byte(1) + atomic.AddInt32(&ss.length, 1) } } func (ss *intSetByteSlice) Delete(idx int) { ss.locks[idx].Lock() defer ss.locks[idx].Unlock() - - // Check again to make sure it hasn't changed since acquiring the lock. if ss.state[idx] == byte(1) { ss.state[idx] = byte(0) atomic.AddInt32(&ss.length, -1) } - } func (ss *intSetByteSlice) Length() int { From 7d77cb83af3999be9ea0dbb4d9375cea49584651 Mon Sep 17 00:00:00 2001 From: Steven Landers Date: Fri, 15 Mar 2024 14:58:34 -0400 Subject: [PATCH 31/39] add sequential fallback --- tasksv2/scheduler.go | 30 ++++++++++++++++++++------- tasksv2/task_queue.go | 47 +++++++++++++++++++++++++++++-------------- 2 files changed, 55 insertions(+), 22 deletions(-) diff --git a/tasksv2/scheduler.go b/tasksv2/scheduler.go index b11be45bc..0f83b0271 100644 --- a/tasksv2/scheduler.go +++ b/tasksv2/scheduler.go @@ -62,6 +62,24 @@ func (s *scheduler) initScheduler(ctx sdk.Context, reqs []*sdk.DeliverTxEntry) ( return queue, workers } +func (s *scheduler) validateAll(ctx sdk.Context) { + for _, t := range s.tasks { + if t.IsStatus(statusValidated) { + s.validateTask(ctx, t) + if t.IsStatus(statusValidated) { + continue + } + } + t.ResetForExecution() + t.Increment() + s.executeTask(t) + s.validateTask(ctx, t) + if !t.IsStatus(statusValidated) { + panic("invalid task after sequential execution") + } + } +} + func (s *scheduler) ProcessAll(ctx sdk.Context, reqs []*sdk.DeliverTxEntry) ([]types.ResponseDeliverTx, error) { if len(reqs) == 0 { return []types.ResponseDeliverTx{}, nil @@ -85,16 +103,10 @@ func (s *scheduler) ProcessAll(ctx sdk.Context, reqs []*sdk.DeliverTxEntry) ([]t defer wg.Done() for { - if atomic.LoadInt32(&activeCount) == 0 { mx.Lock() if queue.IsCompleted() { - if final.Load() { - queue.Close() - } else { - final.Store(true) - queue.ValidateAll() - } + queue.Close() } mx.Unlock() } @@ -134,6 +146,10 @@ func (s *scheduler) ProcessAll(ctx sdk.Context, reqs []*sdk.DeliverTxEntry) ([]t wg.Wait() + // if there are any tasks left, process them sequentially + // this can happen with high conflict rates and high incarnations + s.validateAll(ctx) + for _, mv := range s.multiVersionStores { mv.WriteLatestToStore() } diff --git a/tasksv2/task_queue.go b/tasksv2/task_queue.go index 534a00c7f..4314e8da0 100644 --- a/tasksv2/task_queue.go +++ b/tasksv2/task_queue.go @@ -13,6 +13,7 @@ const ( TypeNone TaskType = "NONE" TypeExecution TaskType = "EXECUTE" TypeValidation TaskType = "VALIDATE" + maxRetryRatio = 3 ) type Queue interface { @@ -43,16 +44,18 @@ type Queue interface { } type taskQueue struct { - lockTimerID string - qmx sync.RWMutex - once sync.Once - executing IntSet - finished IntSet - queueLen atomic.Int64 - closed bool - workers int - shards []chan int - tasks []*TxTask + lockTimerID string + qmx sync.RWMutex + once sync.Once + executing IntSet + finished IntSet + queueLen atomic.Int64 + closed bool + workers int + shards []chan int + tasks []*TxTask + increments atomic.Int64 + maxIncarnations int64 } func NewTaskQueue(tasks []*TxTask, workers int) Queue { @@ -61,11 +64,12 @@ func NewTaskQueue(tasks []*TxTask, workers int) Queue { shards = append(shards, make(chan int, len(tasks)*2)) } sq := &taskQueue{ - workers: workers, - tasks: tasks, - shards: shards, - finished: newIntSet(len(tasks)), // newSyncSetMap(), //(len(tasks)), - executing: newIntSet(len(tasks)), + workers: workers, + tasks: tasks, + shards: shards, + finished: newIntSet(len(tasks)), // newSyncSetMap(), //(len(tasks)), + executing: newIntSet(len(tasks)), + maxIncarnations: int64(len(tasks) * maxRetryRatio), } return sq } @@ -133,9 +137,22 @@ func (sq *taskQueue) ReValidate(idx int) { sq.validate(idx) } +func (sq *taskQueue) retryRatioTooHigh() bool { + count := sq.increments.Add(1) + return count >= sq.maxIncarnations +} + func (sq *taskQueue) Execute(idx int) { task := sq.tasks[idx] task.Increment() + + // if this happens, all remaining tasks will run sequentially + // this is a safety behavior to prevent incredibly long runtimes + if sq.retryRatioTooHigh() { + sq.Close() + return + } + sq.execute(idx) } From b1599f5d2f5b2000860801c8b0740b2e0ffe26e8 Mon Sep 17 00:00:00 2001 From: Steven Landers Date: Fri, 15 Mar 2024 15:49:48 -0400 Subject: [PATCH 32/39] cleanup --- tasksv2/scheduler.go | 142 +++++++++++++------------------------ tasksv2/task.go | 11 +-- tasksv2/task_validation.go | 20 +++++- tasksv2/utils.go | 26 ++++--- 4 files changed, 85 insertions(+), 114 deletions(-) diff --git a/tasksv2/scheduler.go b/tasksv2/scheduler.go index 0f83b0271..51939c990 100644 --- a/tasksv2/scheduler.go +++ b/tasksv2/scheduler.go @@ -2,7 +2,6 @@ package tasksv2 import ( "fmt" - "strings" "sync" "sync/atomic" @@ -40,7 +39,7 @@ func NewScheduler(workers int, tracingInfo *tracing.Info, deliverTxFunc Schedule } } -func (s *scheduler) initScheduler(ctx sdk.Context, reqs []*sdk.DeliverTxEntry) (Queue, int) { +func (s *scheduler) initSchedulerAndQueue(ctx sdk.Context, reqs []*sdk.DeliverTxEntry) (Queue, int) { // initialize mutli-version stores s.initMultiVersionStore(ctx) // prefill estimates @@ -62,107 +61,61 @@ func (s *scheduler) initScheduler(ctx sdk.Context, reqs []*sdk.DeliverTxEntry) ( return queue, workers } -func (s *scheduler) validateAll(ctx sdk.Context) { - for _, t := range s.tasks { - if t.IsStatus(statusValidated) { - s.validateTask(ctx, t) - if t.IsStatus(statusValidated) { - continue - } - } - t.ResetForExecution() - t.Increment() - s.executeTask(t) - s.validateTask(ctx, t) - if !t.IsStatus(statusValidated) { - panic("invalid task after sequential execution") - } - } -} - func (s *scheduler) ProcessAll(ctx sdk.Context, reqs []*sdk.DeliverTxEntry) ([]types.ResponseDeliverTx, error) { if len(reqs) == 0 { return []types.ResponseDeliverTx{}, nil } var results []types.ResponseDeliverTx - var err error - counter := atomic.Int32{} - - WithTimer(s.timer, "ProcessAll", func() { - - queue, workers := s.initScheduler(ctx, reqs) - wg := sync.WaitGroup{} - wg.Add(workers) - mx := sync.Mutex{} - var activeCount int32 - final := atomic.Bool{} - - for i := 0; i < workers; i++ { - go func(worker int) { - defer wg.Done() - - for { - if atomic.LoadInt32(&activeCount) == 0 { - mx.Lock() - if queue.IsCompleted() { - queue.Close() - } - mx.Unlock() - } - cancel := hangDebug(func() { - if worker == 0 && !queue.IsCompleted() { - fmt.Printf("Logging tasks for height %d \n", ctx.BlockHeight()) - // produce a report of tasks mapped by status - var lines []string - for _, t := range s.tasks { - lines = append(lines, fmt.Sprintf("Task(idx=%d, status=%s, incarnation=%d):\t%s", t.AbsoluteIndex, t.status, t.Incarnation, "status")) - } - fmt.Println(strings.Join(lines, "\n")) - } - fmt.Printf("worker=%d, completed=%v\n", worker, queue.IsCompleted()) - }) - task, anyTasks := queue.NextTask(worker) - cancel() - atomic.AddInt32(&activeCount, 1) - - if !anyTasks { - return - } + queue, workers := s.initSchedulerAndQueue(ctx, reqs) + wg := sync.WaitGroup{} + wg.Add(workers) + var activeWorkers int32 + + for i := 0; i < workers; i++ { + go func(worker int) { + defer wg.Done() - // this safely gets the task type while someone could be editing it - if tt, ok := task.PopTaskType(); ok { - counter.Add(1) - if !s.processTask(ctx, tt, worker, task, queue) { - final.Store(false) - } + for { + if atomic.LoadInt32(&activeWorkers) == 0 { + if queue.IsCompleted() { + queue.Close() } - atomic.AddInt32(&activeCount, -1) } - }(i) - } + task, anyTasks := queue.NextTask(worker) + atomic.AddInt32(&activeWorkers, 1) - wg.Wait() + if !anyTasks { + return + } - // if there are any tasks left, process them sequentially - // this can happen with high conflict rates and high incarnations - s.validateAll(ctx) + // threadsafe acquisition of task type, avoids dual-execution + if tt, ok := task.PopTaskType(); ok { + s.processTask(ctx, tt, worker, task, queue) + } + atomic.AddInt32(&activeWorkers, -1) + } - for _, mv := range s.multiVersionStores { - mv.WriteLatestToStore() - } - results = collectResponses(s.tasks) - err = nil - }) - //s.timer.PrintReport() - //fmt.Printf("Total Tasks: %d\n", counter.Load()) + }(i) + } + + wg.Wait() + + // if there are any tasks left, process them sequentially + // this can happen with high conflict rates and high incarnations + s.validateAll(ctx) + + for _, mv := range s.multiVersionStores { + mv.WriteLatestToStore() + } + results = collectResponses(s.tasks) - return results, err + return results, nil } -func (s *scheduler) processTask(ctx sdk.Context, taskType TaskType, w int, t *TxTask, queue Queue) bool { +func (s *scheduler) processTask(ctx sdk.Context, taskType TaskType, w int, t *TxTask, queue Queue) { switch taskType { case TypeValidation: TaskLog(t, fmt.Sprintf("TypeValidation (worker=%d)", w)) @@ -176,10 +129,9 @@ func (s *scheduler) processTask(ctx sdk.Context, taskType TaskType, w int, t *Tx TaskLog(t, "*** VALIDATED ***") // informs queue that it's complete (counts towards overall completion) queue.FinishTask(t.AbsoluteIndex) - return true + case statusWaiting: // task should be re-validated (waiting on others) - // how can we wait on dependencies? TaskLog(t, "waiting, executing again") queue.Execute(t.AbsoluteIndex) @@ -187,9 +139,10 @@ func (s *scheduler) processTask(ctx sdk.Context, taskType TaskType, w int, t *Tx TaskLog(t, "invalid (re-executing, re-validating > tx)") queue.ValidateLaterTasks(t.AbsoluteIndex) queue.Execute(t.AbsoluteIndex) + default: TaskLog(t, "unexpected status") - panic("unexpected status ") + panic("unexpected status") } case TypeExecution: @@ -198,7 +151,8 @@ func (s *scheduler) processTask(ctx sdk.Context, taskType TaskType, w int, t *Tx s.executeTask(t) - if t.IsStatus(statusAborted) { + switch t.status { + case statusAborted: parent := s.tasks[t.Abort.DependentTxIdx] parent.LockTask() if parent.IsTaskType(TypeExecution) { @@ -208,14 +162,18 @@ func (s *scheduler) processTask(ctx sdk.Context, taskType TaskType, w int, t *Tx queue.Execute(t.AbsoluteIndex) } parent.UnlockTask() - } else { + + case statusExecuted: TaskLog(t, fmt.Sprintf("FINISHING task EXECUTION (worker=%d, incarnation=%d)", w, t.Incarnation)) queue.FinishExecute(t.AbsoluteIndex) + + default: + TaskLog(t, "unexpected status") + panic("unexpected status") } default: TaskLog(t, "unexpected type") panic("unexpected type") } - return false } diff --git a/tasksv2/task.go b/tasksv2/task.go index 0eb77c1cf..87aaca8f5 100644 --- a/tasksv2/task.go +++ b/tasksv2/task.go @@ -45,6 +45,7 @@ type TxTask struct { Executing byte Validating byte Incarnation int + TxHash string Request types.RequestDeliverTx Response *types.ResponseDeliverTx VersionStores map[sdk.StoreKey]*multiversion.VersionIndexedStore @@ -138,16 +139,6 @@ func (dt *TxTask) IsWaiting() bool { return dt.status == statusWaiting } -func (dt *TxTask) Reset() { - dt.rwMx.Lock() - defer dt.rwMx.Unlock() - dt.status = statusPending - dt.Response = nil - dt.Abort = nil - dt.AbortCh = nil - dt.VersionStores = nil -} - func (dt *TxTask) ResetForExecution() { dt.rwMx.Lock() defer dt.rwMx.Unlock() diff --git a/tasksv2/task_validation.go b/tasksv2/task_validation.go index 2ad44c48c..6ba1ab970 100644 --- a/tasksv2/task_validation.go +++ b/tasksv2/task_validation.go @@ -18,7 +18,7 @@ func (s *scheduler) findConflicts(task *TxTask) (bool, []int) { } } // any non-ok value makes valid false - valid = ok && valid + valid = valid && ok } sort.Ints(conflicts) return valid, conflicts @@ -36,6 +36,24 @@ func (s *scheduler) mockValidateTask(ctx sdk.Context, task *TxTask) { task.SetStatus(statusValidated) } +func (s *scheduler) validateAll(ctx sdk.Context) { + for _, t := range s.tasks { + if t.IsStatus(statusValidated) { + s.validateTask(ctx, t) + if t.IsStatus(statusValidated) { + continue + } + } + t.ResetForExecution() + t.Increment() + s.executeTask(t) + s.validateTask(ctx, t) + if !t.IsStatus(statusValidated) { + panic("invalid task after sequential execution") + } + } +} + func (s *scheduler) validateTask(ctx sdk.Context, task *TxTask) { _, span := s.traceSpan(ctx, "SchedulerValidate", task) defer span.End() diff --git a/tasksv2/utils.go b/tasksv2/utils.go index c6fbe0d39..e56661164 100644 --- a/tasksv2/utils.go +++ b/tasksv2/utils.go @@ -2,15 +2,18 @@ package tasksv2 import ( "context" + "crypto/sha256" + "fmt" "github.com/cosmos/cosmos-sdk/store/multiversion" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/tendermint/tendermint/abci/types" + "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" "sort" "time" ) -// TODO: remove after things work +// TaskLog logs basic task information for debugging purposes func TaskLog(task *TxTask, msg string) { // helpful for debugging state transitions //fmt.Println(fmt.Sprintf("%d: Task(%d/%s/%d):\t%s", time.Now().UnixMicro(), task.AbsoluteIndex, task.status, task.Incarnation, msg)) @@ -24,18 +27,18 @@ type mockEndable struct{} func (m *mockEndable) End(options ...trace.SpanEndOption) {} -func (s *scheduler) traceSpan(ctx sdk.Context, name string, task *TxTask) (sdk.Context, Endable) { - //spanCtx, span := s.tracingInfo.StartWithContext(name, ctx.TraceSpanContext()) - //if task != nil { - // span.SetAttributes(attribute.String("txHash", fmt.Sprintf("%X", sha256.Sum256(task.Request.Tx)))) - // span.SetAttributes(attribute.Int("txIndex", task.AbsoluteIndex)) - // span.SetAttributes(attribute.Int("txIncarnation", task.Incarnation)) - //} - //ctx = ctx.WithTraceSpanContext(spanCtx) - //return ctx, span - return ctx, &mockEndable{} +func (s *scheduler) traceSpan(ctx sdk.Context, name string, task *TxTask) (sdk.Context, trace.Span) { + spanCtx, span := s.tracingInfo.StartWithContext(name, ctx.TraceSpanContext()) + if task != nil { + span.SetAttributes(attribute.String("txHash", task.TxHash)) + span.SetAttributes(attribute.Int("absoluteIndex", task.AbsoluteIndex)) + span.SetAttributes(attribute.Int("txIncarnation", task.Incarnation)) + } + ctx = ctx.WithTraceSpanContext(spanCtx) + return ctx, span } +// hangDebug prints a message after 1s if not cancelled (detects hangs) func hangDebug(msg func()) context.CancelFunc { ctx, cancel := context.WithCancel(context.Background()) ticker := time.NewTicker(1 * time.Second) @@ -60,6 +63,7 @@ func toTasks(ctx sdk.Context, reqs []*sdk.DeliverTxEntry) []*TxTask { AbsoluteIndex: r.AbsoluteIndex, SdkTx: r.SdkTx, Checksum: r.Checksum, + TxHash: fmt.Sprintf("%X", sha256.Sum256(r.Request.Tx)), Parents: &intSetMap{ m: make(map[int]struct{}), }, From 7c6493a23c9187a0584027e5425c156aa731e9e8 Mon Sep 17 00:00:00 2001 From: Steven Landers Date: Mon, 18 Mar 2024 09:03:58 -0400 Subject: [PATCH 33/39] add occ-async flag --- baseapp/abci.go | 12 +++++++++--- baseapp/baseapp.go | 2 ++ server/config/config.go | 4 ++++ server/config/config_test.go | 8 ++++++++ simapp/simd/cmd/root.go | 1 + types/context.go | 11 +++++++++++ types/context_test.go | 5 ++++- 7 files changed, 39 insertions(+), 4 deletions(-) diff --git a/baseapp/abci.go b/baseapp/abci.go index 7e528d121..303f8be04 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "github.com/cosmos/cosmos-sdk/tasksv2" "os" "sort" "strings" @@ -252,13 +253,18 @@ func (app *BaseApp) CheckTx(ctx context.Context, req *abci.RequestCheckTx) (*abc // DeliverTxBatch executes multiple txs func (app *BaseApp) DeliverTxBatch(ctx sdk.Context, req sdk.DeliverTxBatchRequest) (res sdk.DeliverTxBatchResponse) { - scheduler := tasks.NewScheduler(app.concurrencyWorkers, app.TracingInfo, app.DeliverTx) - // This will basically no-op the actual prefill if the metadata for the txs is empty + var scheduler tasks.Scheduler + if ctx.IsOCCAsync() { + scheduler = tasksv2.NewScheduler(app.concurrencyWorkers, app.TracingInfo, app.DeliverTx) + } else { + scheduler = tasks.NewScheduler(app.concurrencyWorkers, app.TracingInfo, app.DeliverTx) + } // process all txs, this will also initializes the MVS if prefill estimates was disabled txRes, err := scheduler.ProcessAll(ctx, req.TxEntries) if err != nil { - // TODO: handle error + app.logger.Error("DeliverTxBatch failed", "err", err) + panic(err) } responses := make([]*sdk.DeliverTxResult, 0, len(req.TxEntries)) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 5aa821585..9c525e8a4 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -60,6 +60,8 @@ const ( FlagChainID = "chain-id" FlagConcurrencyWorkers = "concurrency-workers" FlagOccEnabled = "occ-enabled" + + FlagOccAsync = "occ-async" ) var ( diff --git a/server/config/config.go b/server/config/config.go index 116b3cdd3..67ed1506f 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -27,6 +27,7 @@ const ( // DefaultOccEanbled defines whether to use OCC for tx processing DefaultOccEnabled = false + DefaultOccAsync = false ) // BaseConfig defines the server's basic configuration @@ -100,6 +101,7 @@ type BaseConfig struct { ConcurrencyWorkers int `mapstructure:"concurrency-workers"` // Whether to enable optimistic concurrency control for tx execution, default is true OccEnabled bool `mapstructure:"occ-enabled"` + OccAsync bool `mapstructure:"occ-async"` } // APIConfig defines the API listener configuration. @@ -252,6 +254,7 @@ func DefaultConfig() *Config { NoVersioning: false, ConcurrencyWorkers: DefaultConcurrencyWorkers, OccEnabled: DefaultOccEnabled, + OccAsync: DefaultOccAsync, }, Telemetry: telemetry.Config{ Enabled: false, @@ -330,6 +333,7 @@ func GetConfig(v *viper.Viper) (Config, error) { OrphanDirectory: v.GetString("orphan-dir"), ConcurrencyWorkers: v.GetInt("concurrency-workers"), OccEnabled: v.GetBool("occ-enabled"), + OccAsync: v.GetBool("occ-async"), }, Telemetry: telemetry.Config{ ServiceName: v.GetString("telemetry.service-name"), diff --git a/server/config/config_test.go b/server/config/config_test.go index 963142cae..b1b9e45e2 100644 --- a/server/config/config_test.go +++ b/server/config/config_test.go @@ -36,3 +36,11 @@ func TestOCCEnabled(t *testing.T) { cfg.BaseConfig.OccEnabled = true require.True(t, cfg.OccEnabled) } + +func TestOCCAsync(t *testing.T) { + cfg := DefaultConfig() + require.False(t, cfg.OccAsync) + + cfg.BaseConfig.OccAsync = true + require.True(t, cfg.OccAsync) +} diff --git a/simapp/simd/cmd/root.go b/simapp/simd/cmd/root.go index 4b3f5dfee..6217eed5d 100644 --- a/simapp/simd/cmd/root.go +++ b/simapp/simd/cmd/root.go @@ -306,6 +306,7 @@ func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, t baseapp.SetIAVLDisableFastNode(cast.ToBool(appOpts.Get(server.FlagIAVLFastNode))), baseapp.SetCompactionInterval(cast.ToUint64(appOpts.Get(server.FlagCompactionInterval))), baseapp.SetOccEnabled(cast.ToBool(appOpts.Get(baseapp.FlagOccEnabled))), + baseapp.SetOccEnabled(cast.ToBool(appOpts.Get(baseapp.FlagOccAsync))), ) } diff --git a/types/context.go b/types/context.go index b2c467257..55359e1c6 100644 --- a/types/context.go +++ b/types/context.go @@ -34,6 +34,7 @@ type Context struct { voteInfo []abci.VoteInfo gasMeter GasMeter occEnabled bool + occAsync bool blockGasMeter GasMeter checkTx bool recheckTx bool // if recheckTx == true, then checkTx must also be true @@ -113,6 +114,10 @@ func (c Context) IsOCCEnabled() bool { return c.occEnabled } +func (c Context) IsOCCAsync() bool { + return c.occAsync +} + func (c Context) MinGasPrices() DecCoins { return c.minGasPrice } @@ -314,6 +319,12 @@ func (c Context) WithIsOCCEnabled(isOCCEnabled bool) Context { return c } +// WithIsOCCAsync enables or disables whether OCC is used as the concurrency algorithm +func (c Context) WithIsOCCAsync(isOccAsync bool) Context { + c.occAsync = isOccAsync + return c +} + // WithIsRecheckTx called with true will also set true on checkTx in order to // enforce the invariant that if recheckTx = true then checkTx = true as well. func (c Context) WithIsReCheckTx(isRecheckTx bool) Context { diff --git a/types/context_test.go b/types/context_test.go index 12d71b67b..de799da23 100644 --- a/types/context_test.go +++ b/types/context_test.go @@ -88,6 +88,7 @@ func (s *contextTestSuite) TestContextWithCustom() { chainid := "chainid" ischeck := true isOCC := true + isAsync := true txbytes := []byte("txbytes") logger := mocks.NewMockLogger(ctrl) voteinfos := []abci.VoteInfo{{}} @@ -106,12 +107,14 @@ func (s *contextTestSuite) TestContextWithCustom() { WithGasMeter(meter). WithMinGasPrices(minGasPrices). WithHeaderHash(headerHash). - WithIsOCCEnabled(isOCC) + WithIsOCCEnabled(isOCC). + WithIsOCCAsync(isAsync) s.Require().Equal(height, ctx.BlockHeight()) s.Require().Equal(chainid, ctx.ChainID()) s.Require().Equal(ischeck, ctx.IsCheckTx()) s.Require().Equal(isOCC, ctx.IsOCCEnabled()) + s.Require().Equal(isAsync, ctx.IsOCCAsync()) s.Require().Equal(txbytes, ctx.TxBytes()) s.Require().Equal(logger, ctx.Logger()) s.Require().Equal(voteinfos, ctx.VoteInfos()) From 76de9213df7938a27d235a35d7102ffaf2295d42 Mon Sep 17 00:00:00 2001 From: Steven Landers Date: Mon, 18 Mar 2024 09:30:08 -0400 Subject: [PATCH 34/39] cleanup on config --- baseapp/abci.go | 2 +- baseapp/baseapp.go | 7 ++++ baseapp/deliver_tx_batch_test.go | 65 ++++++++++++++++++++++++++++++++ types/context.go | 11 ------ types/context_test.go | 5 +-- 5 files changed, 74 insertions(+), 16 deletions(-) diff --git a/baseapp/abci.go b/baseapp/abci.go index 303f8be04..d38795817 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -254,7 +254,7 @@ func (app *BaseApp) CheckTx(ctx context.Context, req *abci.RequestCheckTx) (*abc // DeliverTxBatch executes multiple txs func (app *BaseApp) DeliverTxBatch(ctx sdk.Context, req sdk.DeliverTxBatchRequest) (res sdk.DeliverTxBatchResponse) { var scheduler tasks.Scheduler - if ctx.IsOCCAsync() { + if app.occAsync { scheduler = tasksv2.NewScheduler(app.concurrencyWorkers, app.TracingInfo, app.DeliverTx) } else { scheduler = tasks.NewScheduler(app.concurrencyWorkers, app.TracingInfo, app.DeliverTx) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 9c525e8a4..79d8847c0 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -172,6 +172,7 @@ type BaseApp struct { //nolint: maligned concurrencyWorkers int occEnabled bool + occAsync bool } type appStore struct { @@ -282,6 +283,7 @@ func NewBaseApp( } app.TracingInfo.SetContext(context.Background()) + app.occAsync = cast.ToBool(appOpts.Get(FlagOccAsync)) for _, option := range options { option(app) @@ -308,6 +310,11 @@ func NewBaseApp( app.concurrencyWorkers = config.DefaultConcurrencyWorkers } + //TODO: remove occAsync feature flag after it's the default version + if app.occAsync { + app.logger.Info("asynchronous occ scheduler is enabled") + } + return app } diff --git a/baseapp/deliver_tx_batch_test.go b/baseapp/deliver_tx_batch_test.go index 3cf6e0739..c443bb43d 100644 --- a/baseapp/deliver_tx_batch_test.go +++ b/baseapp/deliver_tx_batch_test.go @@ -144,3 +144,68 @@ func TestDeliverTxBatch(t *testing.T) { app.Commit(context.Background()) } } + +func TestDeliverTxBatchAsync(t *testing.T) { + // test increments in the ante + anteKey := []byte("ante-key") + + anteOpt := func(bapp *BaseApp) { + bapp.SetAnteHandler(anteHandler(capKey1, anteKey)) + } + + // test increments in the handler + routerOpt := func(bapp *BaseApp) { + r := sdk.NewRoute(routeMsgCounter, handlerKVStore(capKey1)) + bapp.Router().AddRoute(r) + } + + asyncOpt := func(bapp *BaseApp) { + bapp.occAsync = true + } + + app := setupBaseApp(t, anteOpt, routerOpt, asyncOpt) + app.InitChain(context.Background(), &abci.RequestInitChain{}) + + // Create same codec used in txDecoder + codec := codec.NewLegacyAmino() + registerTestCodec(codec) + + nBlocks := 3 + txPerHeight := 5 + + for blockN := 0; blockN < nBlocks; blockN++ { + header := tmproto.Header{Height: int64(blockN) + 1} + app.setDeliverState(header) + app.BeginBlock(app.deliverState.ctx, abci.RequestBeginBlock{Header: header}) + + var requests []*sdk.DeliverTxEntry + for i := 0; i < txPerHeight; i++ { + counter := int64(blockN*txPerHeight + i) + tx := newTxCounter(counter, counter) + + txBytes, err := codec.Marshal(tx) + require.NoError(t, err) + requests = append(requests, &sdk.DeliverTxEntry{ + Request: abci.RequestDeliverTx{Tx: txBytes}, + SdkTx: *tx, + AbsoluteIndex: i, + }) + } + + responses := app.DeliverTxBatch(app.deliverState.ctx, sdk.DeliverTxBatchRequest{TxEntries: requests}) + require.Len(t, responses.Results, txPerHeight) + + for idx, deliverTxRes := range responses.Results { + res := deliverTxRes.Response + require.Equal(t, abci.CodeTypeOK, res.Code) + requireAttribute(t, res.Events, "tx-id", fmt.Sprintf("%d", idx)) + requireAttribute(t, res.Events, "tx-val", fmt.Sprintf("%d", blockN+1)) + requireAttribute(t, res.Events, "shared-val", fmt.Sprintf("%d", blockN*txPerHeight+idx+1)) + } + + app.EndBlock(app.deliverState.ctx, abci.RequestEndBlock{}) + require.Empty(t, app.deliverState.ctx.MultiStore().GetEvents()) + app.SetDeliverStateToCommit() + app.Commit(context.Background()) + } +} diff --git a/types/context.go b/types/context.go index 55359e1c6..b2c467257 100644 --- a/types/context.go +++ b/types/context.go @@ -34,7 +34,6 @@ type Context struct { voteInfo []abci.VoteInfo gasMeter GasMeter occEnabled bool - occAsync bool blockGasMeter GasMeter checkTx bool recheckTx bool // if recheckTx == true, then checkTx must also be true @@ -114,10 +113,6 @@ func (c Context) IsOCCEnabled() bool { return c.occEnabled } -func (c Context) IsOCCAsync() bool { - return c.occAsync -} - func (c Context) MinGasPrices() DecCoins { return c.minGasPrice } @@ -319,12 +314,6 @@ func (c Context) WithIsOCCEnabled(isOCCEnabled bool) Context { return c } -// WithIsOCCAsync enables or disables whether OCC is used as the concurrency algorithm -func (c Context) WithIsOCCAsync(isOccAsync bool) Context { - c.occAsync = isOccAsync - return c -} - // WithIsRecheckTx called with true will also set true on checkTx in order to // enforce the invariant that if recheckTx = true then checkTx = true as well. func (c Context) WithIsReCheckTx(isRecheckTx bool) Context { diff --git a/types/context_test.go b/types/context_test.go index de799da23..12d71b67b 100644 --- a/types/context_test.go +++ b/types/context_test.go @@ -88,7 +88,6 @@ func (s *contextTestSuite) TestContextWithCustom() { chainid := "chainid" ischeck := true isOCC := true - isAsync := true txbytes := []byte("txbytes") logger := mocks.NewMockLogger(ctrl) voteinfos := []abci.VoteInfo{{}} @@ -107,14 +106,12 @@ func (s *contextTestSuite) TestContextWithCustom() { WithGasMeter(meter). WithMinGasPrices(minGasPrices). WithHeaderHash(headerHash). - WithIsOCCEnabled(isOCC). - WithIsOCCAsync(isAsync) + WithIsOCCEnabled(isOCC) s.Require().Equal(height, ctx.BlockHeight()) s.Require().Equal(chainid, ctx.ChainID()) s.Require().Equal(ischeck, ctx.IsCheckTx()) s.Require().Equal(isOCC, ctx.IsOCCEnabled()) - s.Require().Equal(isAsync, ctx.IsOCCAsync()) s.Require().Equal(txbytes, ctx.TxBytes()) s.Require().Equal(logger, ctx.Logger()) s.Require().Equal(voteinfos, ctx.VoteInfos()) From 5c113616eba192565df6dcb1cddeb1c349a872f4 Mon Sep 17 00:00:00 2001 From: Steven Landers Date: Mon, 18 Mar 2024 09:37:21 -0400 Subject: [PATCH 35/39] cleanup import format --- baseapp/abci.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/baseapp/abci.go b/baseapp/abci.go index d38795817..230d81bce 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -6,15 +6,12 @@ import ( "encoding/json" "errors" "fmt" - "github.com/cosmos/cosmos-sdk/tasksv2" "os" "sort" "strings" "syscall" "time" - "github.com/cosmos/cosmos-sdk/tasks" - "github.com/armon/go-metrics" "github.com/gogo/protobuf/proto" abci "github.com/tendermint/tendermint/abci/types" @@ -24,6 +21,8 @@ import ( "github.com/cosmos/cosmos-sdk/codec" snapshottypes "github.com/cosmos/cosmos-sdk/snapshots/types" + "github.com/cosmos/cosmos-sdk/tasks" + "github.com/cosmos/cosmos-sdk/tasksv2" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" From 150e7f1832bfa38a017e541e998bd8ba763bff60 Mon Sep 17 00:00:00 2001 From: Steven Landers Date: Mon, 18 Mar 2024 09:39:15 -0400 Subject: [PATCH 36/39] s p a c i n g --- baseapp/baseapp.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 79d8847c0..a39a99bad 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -60,8 +60,7 @@ const ( FlagChainID = "chain-id" FlagConcurrencyWorkers = "concurrency-workers" FlagOccEnabled = "occ-enabled" - - FlagOccAsync = "occ-async" + FlagOccAsync = "occ-async" ) var ( From 16136b17c514fcaa63088acb89c2ea34f98ece07 Mon Sep 17 00:00:00 2001 From: Steven Landers Date: Mon, 18 Mar 2024 16:15:05 -0400 Subject: [PATCH 37/39] add debug line --- tasksv2/task_validation.go | 1 + tasksv2/utils.go | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/tasksv2/task_validation.go b/tasksv2/task_validation.go index 6ba1ab970..0e544662e 100644 --- a/tasksv2/task_validation.go +++ b/tasksv2/task_validation.go @@ -49,6 +49,7 @@ func (s *scheduler) validateAll(ctx sdk.Context) { s.executeTask(t) s.validateTask(ctx, t) if !t.IsStatus(statusValidated) { + s.printSummary() panic("invalid task after sequential execution") } } diff --git a/tasksv2/utils.go b/tasksv2/utils.go index e56661164..ea8bae801 100644 --- a/tasksv2/utils.go +++ b/tasksv2/utils.go @@ -10,6 +10,7 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" "sort" + "strings" "time" ) @@ -109,3 +110,11 @@ func (s *scheduler) PrefillEstimates(reqs []*sdk.DeliverTxEntry) { } } } + +func (s *scheduler) printSummary() { + var lines []string + for _, t := range s.tasks { + lines = append(lines, fmt.Sprintf("Task index=%d status=%s parents=%v", t.AbsoluteIndex, t.status, t.Parents.List())) + } + fmt.Println(strings.Join(lines, "\n")) +} From 0edfa5e9b060a8f91afe3627be257a36f10fff2a Mon Sep 17 00:00:00 2001 From: Steven Landers Date: Mon, 18 Mar 2024 16:55:07 -0400 Subject: [PATCH 38/39] invalidate before executing a possibly-bad tx --- tasksv2/task_validation.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tasksv2/task_validation.go b/tasksv2/task_validation.go index 0e544662e..cdab5b4ef 100644 --- a/tasksv2/task_validation.go +++ b/tasksv2/task_validation.go @@ -1,8 +1,10 @@ package tasksv2 import ( - sdk "github.com/cosmos/cosmos-sdk/types" + "fmt" "sort" + + sdk "github.com/cosmos/cosmos-sdk/types" ) func (s *scheduler) findConflicts(task *TxTask) (bool, []int) { @@ -44,13 +46,15 @@ func (s *scheduler) validateAll(ctx sdk.Context) { continue } } + // invalidate before incrementing so that old incarnation is invalidated + s.invalidateTask(t) t.ResetForExecution() t.Increment() s.executeTask(t) s.validateTask(ctx, t) if !t.IsStatus(statusValidated) { s.printSummary() - panic("invalid task after sequential execution") + panic(fmt.Errorf("invalid task after sequential execution, index=%d, incarnation=%d", t.AbsoluteIndex, t.Incarnation)) } } } From 0cc2a9ba38538b11a87221394bbe51f2588f09ce Mon Sep 17 00:00:00 2001 From: Steven Landers Date: Mon, 18 Mar 2024 18:25:42 -0400 Subject: [PATCH 39/39] add debug --- tasksv2/task_validation.go | 9 +++++++-- tasksv2/utils.go | 6 ++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/tasksv2/task_validation.go b/tasksv2/task_validation.go index cdab5b4ef..9107021d4 100644 --- a/tasksv2/task_validation.go +++ b/tasksv2/task_validation.go @@ -39,22 +39,27 @@ func (s *scheduler) mockValidateTask(ctx sdk.Context, task *TxTask) { } func (s *scheduler) validateAll(ctx sdk.Context) { + rerun := make(map[int]struct{}) for _, t := range s.tasks { if t.IsStatus(statusValidated) { s.validateTask(ctx, t) if t.IsStatus(statusValidated) { continue } + } else { + // validateTask already invalidates, so we need to invalidate here + s.invalidateTask(t) } + rerun[t.AbsoluteIndex] = struct{}{} // invalidate before incrementing so that old incarnation is invalidated - s.invalidateTask(t) t.ResetForExecution() t.Increment() s.executeTask(t) s.validateTask(ctx, t) if !t.IsStatus(statusValidated) { s.printSummary() - panic(fmt.Errorf("invalid task after sequential execution, index=%d, incarnation=%d", t.AbsoluteIndex, t.Incarnation)) + _, reran := rerun[t.AbsoluteIndex] + panic(fmt.Errorf("invalid task after sequential execution, index=%d, incarnation=%d, reran=%v", t.AbsoluteIndex, t.Incarnation, reran)) } } } diff --git a/tasksv2/utils.go b/tasksv2/utils.go index ea8bae801..564b85308 100644 --- a/tasksv2/utils.go +++ b/tasksv2/utils.go @@ -113,8 +113,10 @@ func (s *scheduler) PrefillEstimates(reqs []*sdk.DeliverTxEntry) { func (s *scheduler) printSummary() { var lines []string - for _, t := range s.tasks { - lines = append(lines, fmt.Sprintf("Task index=%d status=%s parents=%v", t.AbsoluteIndex, t.status, t.Parents.List())) + for i, t := range s.tasks { + line := fmt.Sprintf("Task index=%d absoluteIndex=%d status=%s incarnation=%d parents=%v responseExists=%v", i, t.AbsoluteIndex, t.Status(), t.Incarnation, t.Parents.List(), t.Response != nil) + lines = append(lines, line) } + fmt.Println(strings.Join(lines, "\n")) }