From dbe43822b6e9c68a66450cb90da5c6110a2f61b3 Mon Sep 17 00:00:00 2001 From: "Kim, JinSan" Date: Thu, 14 Jan 2021 18:22:55 +0900 Subject: [PATCH 01/11] chore: simply implement abci.`CheckTxSync()` and abci.`CheckTxAsync()` --- baseapp/abci.go | 6 +++++- baseapp/baseapp_test.go | 2 +- go.mod | 2 +- go.sum | 2 -- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/baseapp/abci.go b/baseapp/abci.go index 254350274c..644b678250 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -161,7 +161,7 @@ func (app *BaseApp) EndBlock(req abci.RequestEndBlock) (res abci.ResponseEndBloc // 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(req abci.RequestCheckTx) abci.ResponseCheckTx { +func (app *BaseApp) CheckTxSync(req abci.RequestCheckTx) abci.ResponseCheckTx { tx, err := app.txDecoder(req.Tx) if err != nil { return sdkerrors.ResponseCheckTx(err, 0, 0, app.trace) @@ -182,6 +182,10 @@ func (app *BaseApp) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx { } } +func (app *BaseApp) CheckTxAsync(req abci.RequestCheckTx, callback abci.CheckTxCallback) { + callback(app.CheckTxSync(req)) +} + // BeginRecheckTx implements the ABCI interface and set the check state based on the given header func (app *BaseApp) BeginRecheckTx(req abci.RequestBeginRecheckTx) abci.ResponseBeginRecheckTx { // NOTE: This is safe because Tendermint holds a lock on the mempool for Rechecking. diff --git a/baseapp/baseapp_test.go b/baseapp/baseapp_test.go index 3551898457..e653ad150b 100644 --- a/baseapp/baseapp_test.go +++ b/baseapp/baseapp_test.go @@ -771,7 +771,7 @@ func TestCheckTx(t *testing.T) { tx := newTxCounter(i, 0) txBytes, err := codec.MarshalBinaryLengthPrefixed(tx) require.NoError(t, err) - r := app.CheckTx(abci.RequestCheckTx{Tx: txBytes}) + r := app.CheckTxSync(abci.RequestCheckTx{Tx: txBytes}) assert.True(t, r.IsOK(), fmt.Sprintf("%v", r)) } diff --git a/go.mod b/go.mod index 6d7f013700..d63731de89 100644 --- a/go.mod +++ b/go.mod @@ -47,5 +47,5 @@ require ( replace ( github.com/keybase/go-keychain => github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 github.com/tendermint/iavl => github.com/line/iavl v0.14.4-0.20201217063301-6b67687bfae9 - github.com/tendermint/tendermint => github.com/line/tendermint v0.33.10-0.20210113083242-8316c03342d5 + github.com/tendermint/tendermint => ../tendermint ) diff --git a/go.sum b/go.sum index 4ff962515c..336794c005 100644 --- a/go.sum +++ b/go.sum @@ -265,8 +265,6 @@ github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-b github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/line/iavl v0.14.4-0.20201217063301-6b67687bfae9 h1:n6YHVdTld8D0dAogBUcXTaqhk1ZMTAR9Phy4xdMVWDY= github.com/line/iavl v0.14.4-0.20201217063301-6b67687bfae9/go.mod h1:eG6hI8RbMxL1nR+nJBykXD//gKjUpKCAT2tvi9V93sA= -github.com/line/tendermint v0.33.10-0.20210113083242-8316c03342d5 h1:Fo4wCTrWWAmjqebHzOQ9IGSltnrV5Ea/OfCN2My2PM4= -github.com/line/tendermint v0.33.10-0.20210113083242-8316c03342d5/go.mod h1:0yUs9eIuuDq07nQql9BmI30FtYGcEC60Tu5JzB5IezM= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= From d29f0970e3b66be7594d218242853b850c7e68e9 Mon Sep 17 00:00:00 2001 From: "Kim, JinSan" Date: Thu, 14 Jan 2021 18:37:49 +0900 Subject: [PATCH 02/11] chore: move `accountLock` from `anteTx()` to `checkTxWithLock()` --- baseapp/abci.go | 2 +- baseapp/baseapp.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/baseapp/abci.go b/baseapp/abci.go index 644b678250..e78f7a4a13 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -171,7 +171,7 @@ func (app *BaseApp) CheckTxSync(req abci.RequestCheckTx) abci.ResponseCheckTx { panic(fmt.Sprintf("unknown RequestCheckTx type: %s", req.Type)) } - gInfo, err := app.checkTx(req.Tx, tx, req.Type == abci.CheckTxType_Recheck) + gInfo, err := app.checkTxWithLock(req.Tx, tx, req.Type == abci.CheckTxType_Recheck) if err != nil { return sdkerrors.ResponseCheckTx(err, gInfo.GasWanted, gInfo.GasUsed, app.trace) } diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 71a7052963..edb7696727 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -517,7 +517,7 @@ func (app *BaseApp) cacheTxContext(ctx sdk.Context, txBytes []byte) (sdk.Context return ctx.WithMultiStore(msCache), msCache } -func (app *BaseApp) checkTx(txBytes []byte, tx sdk.Tx, recheck bool) (gInfo sdk.GasInfo, err error) { +func (app *BaseApp) checkTxWithLock(txBytes []byte, tx sdk.Tx, recheck bool) (gInfo sdk.GasInfo, err error) { ctx := app.getCheckContextForTx(txBytes, recheck) gasCtx := &ctx From 5a1ddb71d51674e72b5bbcab514306e19bfcf42d Mon Sep 17 00:00:00 2001 From: "Kim, JinSan" Date: Fri, 15 Jan 2021 13:56:29 +0900 Subject: [PATCH 03/11] feat: impl `abci.CheckTxAsync()` with reactor # Conflicts: # baseapp/baseapp.go --- baseapp/abci.go | 27 +++++++++++---- baseapp/accountlock.go | 6 +--- baseapp/accountlock_test.go | 4 +-- baseapp/baseapp.go | 60 ++++++++++++++++++++++++---------- baseapp/reactor.go | 65 +++++++++++++++++++++++++++++++++++++ 5 files changed, 130 insertions(+), 32 deletions(-) create mode 100644 baseapp/reactor.go diff --git a/baseapp/abci.go b/baseapp/abci.go index e78f7a4a13..345a04ea75 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -162,16 +162,19 @@ func (app *BaseApp) EndBlock(req abci.RequestEndBlock) (res abci.ResponseEndBloc // will contain releveant error information. Regardless of tx execution outcome, // the ResponseCheckTx will contain relevant gas execution context. func (app *BaseApp) CheckTxSync(req abci.RequestCheckTx) abci.ResponseCheckTx { - tx, err := app.txDecoder(req.Tx) + if req.Type != abci.CheckTxType_New && req.Type != abci.CheckTxType_Recheck { + panic(fmt.Sprintf("unknown RequestCheckTx type: %s", req.Type)) + } + + tx, err := app.preCheckTx(req.Tx) if err != nil { return sdkerrors.ResponseCheckTx(err, 0, 0, app.trace) } - if req.Type != abci.CheckTxType_New && req.Type != abci.CheckTxType_Recheck { - panic(fmt.Sprintf("unknown RequestCheckTx type: %s", req.Type)) - } + accKeys := app.accountLock.Lock(tx) + defer app.accountLock.Unlock(accKeys) - gInfo, err := app.checkTxWithLock(req.Tx, tx, req.Type == abci.CheckTxType_Recheck) + gInfo, err := app.checkTx(req.Tx, tx, req.Type == abci.CheckTxType_Recheck) if err != nil { return sdkerrors.ResponseCheckTx(err, gInfo.GasWanted, gInfo.GasUsed, app.trace) } @@ -183,7 +186,19 @@ func (app *BaseApp) CheckTxSync(req abci.RequestCheckTx) abci.ResponseCheckTx { } func (app *BaseApp) CheckTxAsync(req abci.RequestCheckTx, callback abci.CheckTxCallback) { - callback(app.CheckTxSync(req)) + if req.Type != abci.CheckTxType_New && req.Type != abci.CheckTxType_Recheck { + panic(fmt.Sprintf("unknown RequestCheckTx type: %s", req.Type)) + } + + reqCheckTx := &RequestCheckTxAsync{ + txBytes: req.Tx, + recheck: req.Type == abci.CheckTxType_Recheck, + callback: callback, + prepare: waitGroup1(), + } + app.chCheckTx <- reqCheckTx + + go app.prepareCheckTx(reqCheckTx) } // BeginRecheckTx implements the ABCI interface and set the check state based on the given header diff --git a/baseapp/accountlock.go b/baseapp/accountlock.go index b2ec65b87e..dff5996816 100644 --- a/baseapp/accountlock.go +++ b/baseapp/accountlock.go @@ -15,11 +15,7 @@ type AccountLock struct { accMtx [1 << (sampleBytes * 8)]sync.Mutex } -func (al *AccountLock) Lock(ctx sdk.Context, tx sdk.Tx) []uint32 { - if !ctx.IsCheckTx() || ctx.IsReCheckTx() { - return nil - } - +func (al *AccountLock) Lock(tx sdk.Tx) []uint32 { signers := getSigners(tx) accKeys := getUniqSortedAddressKey(signers) diff --git a/baseapp/accountlock_test.go b/baseapp/accountlock_test.go index cb23944bef..c604e20d4c 100644 --- a/baseapp/accountlock_test.go +++ b/baseapp/accountlock_test.go @@ -8,7 +8,6 @@ import ( "github.com/stretchr/testify/require" - abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/secp256k1" @@ -17,12 +16,11 @@ import ( func TestAccountLock(t *testing.T) { app := setupBaseApp(t) - ctx := app.NewContext(true, abci.Header{}) privs := newTestPrivKeys(3) tx := newTestTx(privs) - accKeys := app.accountLock.Lock(ctx, tx) + accKeys := app.accountLock.Lock(tx) for _, accKey := range accKeys { require.True(t, isMutexLock(&app.accountLock.accMtx[accKey])) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index edb7696727..2489aa9169 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -78,6 +78,8 @@ type BaseApp struct { // nolint: maligned checkStateMtx sync.RWMutex accountLock AccountLock + chCheckTx chan *RequestCheckTxAsync + // an inter-block write-through cache provided to the context during deliverState interBlockCache sdk.MultiStorePersistentCache @@ -127,8 +129,10 @@ func NewBaseApp( queryRouter: NewQueryRouter(), txDecoder: txDecoder, fauxMerkleMode: false, - trace: false, - metrics: NopMetrics(), + // TODO config channel buffer size. It might be good to set it tendermint mempool.size + chCheckTx: make(chan *RequestCheckTxAsync, 10000), + trace: false, + metrics: NopMetrics(), } for _, option := range options { option(app) @@ -138,6 +142,8 @@ func NewBaseApp( app.cms.SetInterBlockCache(app.interBlockCache) } + app.startReactors() + return app } @@ -517,23 +523,37 @@ func (app *BaseApp) cacheTxContext(ctx sdk.Context, txBytes []byte) (sdk.Context return ctx.WithMultiStore(msCache), msCache } -func (app *BaseApp) checkTxWithLock(txBytes []byte, tx sdk.Tx, recheck bool) (gInfo sdk.GasInfo, err error) { +// stateless checkTx +func (app *BaseApp) preCheckTx(txBytes []byte) (tx sdk.Tx, err error) { + defer func() { + if r := recover(); r != nil { + err = app.recoverToError(r) + } + }() + + tx, err = app.txDecoder(txBytes) + if err != nil { + return tx, err + } + + msgs := tx.GetMsgs() + err = validateBasicTxMsgs(msgs) + + return tx, err +} + +func (app *BaseApp) checkTx(txBytes []byte, tx sdk.Tx, recheck bool) (gInfo sdk.GasInfo, err error) { ctx := app.getCheckContextForTx(txBytes, recheck) gasCtx := &ctx defer func() { if r := recover(); r != nil { - err = app.recoverToError(r, ctx.GasMeter()) + err = app.recoverToErrorWithGas(r, ctx.GasMeter()) } gInfo = sdk.GasInfo{GasWanted: gasCtx.GasMeter().Limit(), GasUsed: gasCtx.GasMeter().GasConsumed()} }() - msgs := tx.GetMsgs() - if err = validateBasicTxMsgs(msgs); err != nil { - return gInfo, err - } - - accKeys := app.accountLock.Lock(ctx, tx) + accKeys := app.accountLock.Lock(tx) defer app.accountLock.Unlock(accKeys) var anteCtx sdk.Context @@ -593,7 +613,7 @@ func (app *BaseApp) runTx(txBytes []byte, tx sdk.Tx, simulate bool) (gInfo sdk.G defer func() { if r := recover(); r != nil { - err = app.recoverToError(r, ctx.GasMeter()) + err = app.recoverToErrorWithGas(r, ctx.GasMeter()) result = nil } @@ -699,7 +719,7 @@ func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg) (*sdk.Result, error }, nil } -func (app *BaseApp) recoverToError(r interface{}, gasMeter sdk.GasMeter) error { +func (app *BaseApp) recoverToErrorWithGas(r interface{}, gasMeter sdk.GasMeter) error { switch rType := r.(type) { // TODO: Use ErrOutOfGas instead of ErrorOutOfGas which would allow us // to keep the stracktrace. @@ -712,11 +732,15 @@ func (app *BaseApp) recoverToError(r interface{}, gasMeter sdk.GasMeter) error { ) default: - app.logger.Error("recoverToError", "r", r, "stack", string(debug.Stack())) - return sdkerrors.Wrap( - sdkerrors.ErrPanic, fmt.Sprintf( - "recovered: %v\nstack:\n%v", r, string(debug.Stack()), - ), - ) + return app.recoverToError(r) } } + +func (app *BaseApp) recoverToError(r interface{}) error { + app.logger.Error("recoverToError", "r", r, "stack", string(debug.Stack())) + return sdkerrors.Wrap( + sdkerrors.ErrPanic, fmt.Sprintf( + "recovered: %v\nstack:\n%v", r, string(debug.Stack()), + ), + ) +} diff --git a/baseapp/reactor.go b/baseapp/reactor.go new file mode 100644 index 0000000000..efde5b8fba --- /dev/null +++ b/baseapp/reactor.go @@ -0,0 +1,65 @@ +package baseapp + +import ( + "sync" + + abci "github.com/tendermint/tendermint/abci/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +func (app *BaseApp) startReactors() { + go app.checkTxReactor() +} + +type RequestCheckTxAsync struct { + txBytes []byte + recheck bool + callback abci.CheckTxCallback + prepare *sync.WaitGroup + tx sdk.Tx + err error +} + +func (app *BaseApp) checkTxReactor() { + for { + req := <-app.chCheckTx + + req.prepare.Wait() + if req.err != nil { + req.callback(sdkerrors.ResponseCheckTx(req.err, 0, 0, app.trace)) + continue + } + + accKeys := app.accountLock.Lock(req.tx) + go app.checkTxWithUnlock(req, accKeys) + } +} + +func (app *BaseApp) prepareCheckTx(req *RequestCheckTxAsync) { + defer req.prepare.Done() + req.tx, req.err = app.preCheckTx(req.txBytes) +} + +func (app *BaseApp) checkTxWithUnlock(req *RequestCheckTxAsync, accKeys []uint32) { + gInfo, err := app.checkTx(req.txBytes, req.tx, req.recheck) + + app.accountLock.Unlock(accKeys) + + if err != nil { + req.callback(sdkerrors.ResponseCheckTx(err, gInfo.GasWanted, gInfo.GasUsed, app.trace)) + return + } + + req.callback(abci.ResponseCheckTx{ + GasWanted: int64(gInfo.GasWanted), // TODO: Should type accept unsigned ints? + GasUsed: int64(gInfo.GasUsed), // TODO: Should type accept unsigned ints? + }) +} + +func waitGroup1() (wg *sync.WaitGroup) { + wg = &sync.WaitGroup{} + wg.Add(1) + return +} From 6080fbde486fedfb1167223010833fd5c41e4faf Mon Sep 17 00:00:00 2001 From: "Kim, JinSan" Date: Mon, 18 Jan 2021 18:52:23 +0900 Subject: [PATCH 04/11] feat: impl `accountwgs` --- baseapp/abci.go | 6 +- baseapp/accountlock.go | 84 ------------------------- baseapp/accountlock_test.go | 117 ----------------------------------- baseapp/accountwgs.go | 85 ++++++++++++++++++++++++++ baseapp/accountwgs_test.go | 118 ++++++++++++++++++++++++++++++++++++ baseapp/baseapp.go | 30 ++++----- baseapp/reactor.go | 21 +++---- 7 files changed, 230 insertions(+), 231 deletions(-) delete mode 100644 baseapp/accountlock.go delete mode 100644 baseapp/accountlock_test.go create mode 100644 baseapp/accountwgs.go create mode 100644 baseapp/accountwgs_test.go diff --git a/baseapp/abci.go b/baseapp/abci.go index 345a04ea75..0b1899f99e 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -171,8 +171,10 @@ func (app *BaseApp) CheckTxSync(req abci.RequestCheckTx) abci.ResponseCheckTx { return sdkerrors.ResponseCheckTx(err, 0, 0, app.trace) } - accKeys := app.accountLock.Lock(tx) - defer app.accountLock.Unlock(accKeys) + waits, signals := app.checkAccountWGs.Register(tx) + + app.checkAccountWGs.Waits(waits) + defer app.checkAccountWGs.Done(signals) gInfo, err := app.checkTx(req.Tx, tx, req.Type == abci.CheckTxType_Recheck) if err != nil { diff --git a/baseapp/accountlock.go b/baseapp/accountlock.go deleted file mode 100644 index dff5996816..0000000000 --- a/baseapp/accountlock.go +++ /dev/null @@ -1,84 +0,0 @@ -package baseapp - -import ( - "encoding/binary" - "sort" - "sync" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -// NOTE should 1 <= sampleBytes <= 4. If modify it, you should revise `getAddressKey()` as well -const sampleBytes = 2 - -type AccountLock struct { - accMtx [1 << (sampleBytes * 8)]sync.Mutex -} - -func (al *AccountLock) Lock(tx sdk.Tx) []uint32 { - signers := getSigners(tx) - accKeys := getUniqSortedAddressKey(signers) - - for _, key := range accKeys { - al.accMtx[key].Lock() - } - - return accKeys -} - -func (al *AccountLock) Unlock(accKeys []uint32) { - // NOTE reverse order - for i, length := 0, len(accKeys); i < length; i++ { - key := accKeys[length-1-i] - al.accMtx[key].Unlock() - } -} - -func getSigners(tx sdk.Tx) []sdk.AccAddress { - seen := map[string]bool{} - var signers []sdk.AccAddress - for _, msg := range tx.GetMsgs() { - for _, addr := range msg.GetSigners() { - if !seen[addr.String()] { - signers = append(signers, addr) - seen[addr.String()] = true - } - } - } - return signers -} - -func getUniqSortedAddressKey(addrs []sdk.AccAddress) []uint32 { - accKeys := make([]uint32, 0, len(addrs)) - for _, addr := range addrs { - accKeys = append(accKeys, getAddressKey(addr)) - } - - accKeys = uniq(accKeys) - sort.Sort(uint32Slice(accKeys)) - - return accKeys -} - -func getAddressKey(addr sdk.AccAddress) uint32 { - return uint32(binary.BigEndian.Uint16(addr)) -} - -func uniq(u []uint32) []uint32 { - seen := map[uint32]bool{} - var ret []uint32 - for _, v := range u { - if !seen[v] { - ret = append(ret, v) - seen[v] = true - } - } - return ret -} - -// Uint32Slice attaches the methods of Interface to []uint32, sorting in increasing order. -type uint32Slice []uint32 - -func (p uint32Slice) Len() int { return len(p) } -func (p uint32Slice) Less(i, j int) bool { return p[i] < p[j] } -func (p uint32Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } diff --git a/baseapp/accountlock_test.go b/baseapp/accountlock_test.go deleted file mode 100644 index c604e20d4c..0000000000 --- a/baseapp/accountlock_test.go +++ /dev/null @@ -1,117 +0,0 @@ -package baseapp - -import ( - "reflect" - "sort" - "sync" - "testing" - - "github.com/stretchr/testify/require" - - "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/secp256k1" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -func TestAccountLock(t *testing.T) { - app := setupBaseApp(t) - - privs := newTestPrivKeys(3) - tx := newTestTx(privs) - - accKeys := app.accountLock.Lock(tx) - - for _, accKey := range accKeys { - require.True(t, isMutexLock(&app.accountLock.accMtx[accKey])) - } - - app.accountLock.Unlock(accKeys) - - for _, accKey := range accKeys { - require.False(t, isMutexLock(&app.accountLock.accMtx[accKey])) - } -} - -func TestUnlockDoNothingWithNil(t *testing.T) { - app := setupBaseApp(t) - require.NotPanics(t, func() { app.accountLock.Unlock(nil) }) -} - -func TestGetSigner(t *testing.T) { - privs := newTestPrivKeys(3) - tx := newTestTx(privs) - signers := getSigners(tx) - - require.Equal(t, getAddrs(privs), signers) -} - -func TestGetUniqSortedAddressKey(t *testing.T) { - privs := newTestPrivKeys(3) - - addrs := getAddrs(privs) - addrs = append(addrs, addrs[1], addrs[0]) - require.Equal(t, 5, len(addrs)) - - accKeys := getUniqSortedAddressKey(addrs) - - // length should be reduced because `duplicated` is removed - require.Less(t, len(accKeys), len(addrs)) - - // check uniqueness - for i, iv := range accKeys { - for j, jv := range accKeys { - if i != j { - require.True(t, iv != jv) - } - } - } - - // should be sorted - require.True(t, sort.IsSorted(uint32Slice(accKeys))) -} - -type AccountLockTestTx struct { - Msgs []sdk.Msg -} - -var _ sdk.Tx = AccountLockTestTx{} - -func (tx AccountLockTestTx) GetMsgs() []sdk.Msg { - return tx.Msgs -} - -func (tx AccountLockTestTx) ValidateBasic() error { - return nil -} - -func newTestPrivKeys(num int) []crypto.PrivKey { - privs := make([]crypto.PrivKey, 0, num) - for i := 0; i < num; i++ { - privs = append(privs, secp256k1.GenPrivKey()) - } - return privs -} - -func getAddrs(privs []crypto.PrivKey) []sdk.AccAddress { - addrs := make([]sdk.AccAddress, 0, len(privs)) - for _, priv := range privs { - addrs = append(addrs, sdk.AccAddress(priv.PubKey().Address())) - } - return addrs -} - -func newTestTx(privs []crypto.PrivKey) sdk.Tx { - addrs := getAddrs(privs) - msgs := make([]sdk.Msg, len(addrs)) - for i, addr := range addrs { - msgs[i] = sdk.NewTestMsg(addr) - } - return AccountLockTestTx{Msgs: msgs} -} - -// Hack (too slow) -func isMutexLock(mtx *sync.Mutex) bool { - state := reflect.ValueOf(mtx).Elem().FieldByName("state") - return state.Int() == 1 -} diff --git a/baseapp/accountwgs.go b/baseapp/accountwgs.go new file mode 100644 index 0000000000..1d417011b4 --- /dev/null +++ b/baseapp/accountwgs.go @@ -0,0 +1,85 @@ +package baseapp + +import ( + "sync" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type AccountWGs struct { + mtx sync.Mutex + wgs map[string]*sync.WaitGroup +} + +func NewAccountWGs() *AccountWGs { + return &AccountWGs{ + wgs: make(map[string]*sync.WaitGroup), + } +} + +func (aw *AccountWGs) Register(tx sdk.Tx) (waits []*sync.WaitGroup, signals []*AccountWG) { + signers := getUniqSigners(tx) + + aw.mtx.Lock() + defer aw.mtx.Unlock() + for _, signer := range signers { + if wg := aw.wgs[signer]; wg != nil { + waits = append(waits, wg) + } + sig := waitGroup1() + aw.wgs[signer] = sig + signals = append(signals, NewAccountWG(signer, sig)) + } + + return waits, signals +} + +func (aw *AccountWGs) Waits(waits []*sync.WaitGroup) { + for _, wait := range waits { + wait.Wait() + } +} + +func (aw *AccountWGs) Done(signals []*AccountWG) { + aw.mtx.Lock() + defer aw.mtx.Unlock() + + for _, signal := range signals { + signal.wg.Done() + if aw.wgs[signal.acc] == signal.wg { + delete(aw.wgs, signal.acc) + } + } +} + +func getUniqSigners(tx sdk.Tx) []string { + seen := map[string]bool{} + var signers []string + for _, msg := range tx.GetMsgs() { + for _, addr := range msg.GetSigners() { + if !seen[addr.String()] { + signers = append(signers, string(addr)) + seen[addr.String()] = true + } + } + } + return signers +} + +type AccountWG struct { + acc string + wg *sync.WaitGroup +} + +func NewAccountWG(acc string, wg *sync.WaitGroup) *AccountWG { + return &AccountWG{ + acc: acc, + wg: wg, + } +} + +func waitGroup1() (wg *sync.WaitGroup) { + wg = &sync.WaitGroup{} + wg.Add(1) + return wg +} diff --git a/baseapp/accountwgs_test.go b/baseapp/accountwgs_test.go new file mode 100644 index 0000000000..74fa860e5f --- /dev/null +++ b/baseapp/accountwgs_test.go @@ -0,0 +1,118 @@ +package baseapp + +// TODO +// import ( +// "reflect" +// "sort" +// "sync" +// "testing" +// +// "github.com/stretchr/testify/require" +// +// "github.com/tendermint/tendermint/crypto" +// "github.com/tendermint/tendermint/crypto/secp256k1" +// +// sdk "github.com/cosmos/cosmos-sdk/types" +// ) +// +// func TestAccountLock(t *testing.T) { +// app := setupBaseApp(t) +// +// privs := newTestPrivKeys(3) +// tx := newTestTx(privs) +// +// accKeys := app.accountLock.Lock(tx) +// +// for _, accKey := range accKeys { +// require.True(t, isMutexLock(&app.accountLock.accMtx[accKey])) +// } +// +// app.accountLock.Unlock(accKeys) +// +// for _, accKey := range accKeys { +// require.False(t, isMutexLock(&app.accountLock.accMtx[accKey])) +// } +// } +// +// func TestUnlockDoNothingWithNil(t *testing.T) { +// app := setupBaseApp(t) +// require.NotPanics(t, func() { app.accountLock.Unlock(nil) }) +// } +// +// func TestGetSigner(t *testing.T) { +// privs := newTestPrivKeys(3) +// tx := newTestTx(privs) +// signers := getSigners(tx) +// +// require.Equal(t, getAddrs(privs), signers) +// } +// +// func TestGetUniqSortedAddressKey(t *testing.T) { +// privs := newTestPrivKeys(3) +// +// addrs := getAddrs(privs) +// addrs = append(addrs, addrs[1], addrs[0]) +// require.Equal(t, 5, len(addrs)) +// +// accKeys := getUniqSortedAddressKey(addrs) +// +// // length should be reduced because `duplicated` is removed +// require.Less(t, len(accKeys), len(addrs)) +// +// // check uniqueness +// for i, iv := range accKeys { +// for j, jv := range accKeys { +// if i != j { +// require.True(t, iv != jv) +// } +// } +// } +// +// // should be sorted +// require.True(t, sort.IsSorted(uint32Slice(accKeys))) +// } +// +// type AccountLockTestTx struct { +// Msgs []sdk.Msg +// } +// +// var _ sdk.Tx = AccountLockTestTx{} +// +// func (tx AccountLockTestTx) GetMsgs() []sdk.Msg { +// return tx.Msgs +// } +// +// func (tx AccountLockTestTx) ValidateBasic() error { +// return nil +// } +// +// func newTestPrivKeys(num int) []crypto.PrivKey { +// privs := make([]crypto.PrivKey, 0, num) +// for i := 0; i < num; i++ { +// privs = append(privs, secp256k1.GenPrivKey()) +// } +// return privs +// } +// +// func getAddrs(privs []crypto.PrivKey) []sdk.AccAddress { +// addrs := make([]sdk.AccAddress, 0, len(privs)) +// for _, priv := range privs { +// addrs = append(addrs, sdk.AccAddress(priv.PubKey().Address())) +// } +// return addrs +// } +// +// func newTestTx(privs []crypto.PrivKey) sdk.Tx { +// addrs := getAddrs(privs) +// msgs := make([]sdk.Msg, len(addrs)) +// for i, addr := range addrs { +// msgs[i] = sdk.NewTestMsg(addr) +// } +// return AccountLockTestTx{Msgs: msgs} +// } +// +// // Hack (too slow) +// func isMutexLock(mtx *sync.Mutex) bool { +// state := reflect.ValueOf(mtx).Elem().FieldByName("state") +// return state.Int() == 1 +// } diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 2489aa9169..e232517b81 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -76,9 +76,9 @@ type BaseApp struct { // nolint: maligned deliverState *state // for DeliverTx checkStateMtx sync.RWMutex - accountLock AccountLock - chCheckTx chan *RequestCheckTxAsync + checkAccountWGs *AccountWGs + chCheckTx chan *RequestCheckTxAsync // an inter-block write-through cache provided to the context during deliverState interBlockCache sdk.MultiStorePersistentCache @@ -120,19 +120,19 @@ func NewBaseApp( ) *BaseApp { app := &BaseApp{ - logger: logger, - name: name, - db: db, - cms: store.NewCommitMultiStore(db), - storeLoader: DefaultStoreLoader, - router: NewRouter(), - queryRouter: NewQueryRouter(), - txDecoder: txDecoder, - fauxMerkleMode: false, - // TODO config channel buffer size. It might be good to set it tendermint mempool.size - chCheckTx: make(chan *RequestCheckTxAsync, 10000), - trace: false, - metrics: NopMetrics(), + logger: logger, + name: name, + db: db, + cms: store.NewCommitMultiStore(db), + storeLoader: DefaultStoreLoader, + router: NewRouter(), + queryRouter: NewQueryRouter(), + txDecoder: txDecoder, + fauxMerkleMode: false, + checkAccountWGs: NewAccountWGs(), + chCheckTx: make(chan *RequestCheckTxAsync, 10000), // TODO config channel buffer size. It might be good to set it tendermint mempool.size + trace: false, + metrics: NopMetrics(), } for _, option := range options { option(app) diff --git a/baseapp/reactor.go b/baseapp/reactor.go index efde5b8fba..78e31b744b 100644 --- a/baseapp/reactor.go +++ b/baseapp/reactor.go @@ -23,17 +23,16 @@ type RequestCheckTxAsync struct { } func (app *BaseApp) checkTxReactor() { - for { - req := <-app.chCheckTx - + for req := range app.chCheckTx { req.prepare.Wait() if req.err != nil { req.callback(sdkerrors.ResponseCheckTx(req.err, 0, 0, app.trace)) continue } - accKeys := app.accountLock.Lock(req.tx) - go app.checkTxWithUnlock(req, accKeys) + waits, signals := app.checkAccountWGs.Register(req.tx) + + go app.checkTxWithUnlock(req, waits, signals) } } @@ -42,10 +41,12 @@ func (app *BaseApp) prepareCheckTx(req *RequestCheckTxAsync) { req.tx, req.err = app.preCheckTx(req.txBytes) } -func (app *BaseApp) checkTxWithUnlock(req *RequestCheckTxAsync, accKeys []uint32) { +func (app *BaseApp) checkTxWithUnlock(req *RequestCheckTxAsync, waits []*sync.WaitGroup, signals []*AccountWG) { + app.checkAccountWGs.Waits(waits) + gInfo, err := app.checkTx(req.txBytes, req.tx, req.recheck) - app.accountLock.Unlock(accKeys) + app.checkAccountWGs.Done(signals) if err != nil { req.callback(sdkerrors.ResponseCheckTx(err, gInfo.GasWanted, gInfo.GasUsed, app.trace)) @@ -57,9 +58,3 @@ func (app *BaseApp) checkTxWithUnlock(req *RequestCheckTxAsync, accKeys []uint32 GasUsed: int64(gInfo.GasUsed), // TODO: Should type accept unsigned ints? }) } - -func waitGroup1() (wg *sync.WaitGroup) { - wg = &sync.WaitGroup{} - wg.Add(1) - return -} From 6a12e07a71319baf7844165409a6ec48fd01c53b Mon Sep 17 00:00:00 2001 From: "Kim, JinSan" Date: Mon, 18 Jan 2021 20:48:47 +0900 Subject: [PATCH 05/11] feat: impl `accountwgs_test` --- baseapp/accountwgs_test.go | 215 +++++++++++++++++-------------------- 1 file changed, 99 insertions(+), 116 deletions(-) diff --git a/baseapp/accountwgs_test.go b/baseapp/accountwgs_test.go index 74fa860e5f..47fb8ba64e 100644 --- a/baseapp/accountwgs_test.go +++ b/baseapp/accountwgs_test.go @@ -1,118 +1,101 @@ package baseapp -// TODO -// import ( -// "reflect" -// "sort" -// "sync" -// "testing" -// -// "github.com/stretchr/testify/require" -// -// "github.com/tendermint/tendermint/crypto" -// "github.com/tendermint/tendermint/crypto/secp256k1" -// -// sdk "github.com/cosmos/cosmos-sdk/types" -// ) -// -// func TestAccountLock(t *testing.T) { -// app := setupBaseApp(t) -// -// privs := newTestPrivKeys(3) -// tx := newTestTx(privs) -// -// accKeys := app.accountLock.Lock(tx) -// -// for _, accKey := range accKeys { -// require.True(t, isMutexLock(&app.accountLock.accMtx[accKey])) -// } -// -// app.accountLock.Unlock(accKeys) -// -// for _, accKey := range accKeys { -// require.False(t, isMutexLock(&app.accountLock.accMtx[accKey])) -// } -// } -// -// func TestUnlockDoNothingWithNil(t *testing.T) { -// app := setupBaseApp(t) -// require.NotPanics(t, func() { app.accountLock.Unlock(nil) }) -// } -// -// func TestGetSigner(t *testing.T) { -// privs := newTestPrivKeys(3) -// tx := newTestTx(privs) -// signers := getSigners(tx) -// -// require.Equal(t, getAddrs(privs), signers) -// } -// -// func TestGetUniqSortedAddressKey(t *testing.T) { -// privs := newTestPrivKeys(3) -// -// addrs := getAddrs(privs) -// addrs = append(addrs, addrs[1], addrs[0]) -// require.Equal(t, 5, len(addrs)) -// -// accKeys := getUniqSortedAddressKey(addrs) -// -// // length should be reduced because `duplicated` is removed -// require.Less(t, len(accKeys), len(addrs)) -// -// // check uniqueness -// for i, iv := range accKeys { -// for j, jv := range accKeys { -// if i != j { -// require.True(t, iv != jv) -// } -// } -// } -// -// // should be sorted -// require.True(t, sort.IsSorted(uint32Slice(accKeys))) -// } -// -// type AccountLockTestTx struct { -// Msgs []sdk.Msg -// } -// -// var _ sdk.Tx = AccountLockTestTx{} -// -// func (tx AccountLockTestTx) GetMsgs() []sdk.Msg { -// return tx.Msgs -// } -// -// func (tx AccountLockTestTx) ValidateBasic() error { -// return nil -// } -// -// func newTestPrivKeys(num int) []crypto.PrivKey { -// privs := make([]crypto.PrivKey, 0, num) -// for i := 0; i < num; i++ { -// privs = append(privs, secp256k1.GenPrivKey()) -// } -// return privs -// } -// -// func getAddrs(privs []crypto.PrivKey) []sdk.AccAddress { -// addrs := make([]sdk.AccAddress, 0, len(privs)) -// for _, priv := range privs { -// addrs = append(addrs, sdk.AccAddress(priv.PubKey().Address())) -// } -// return addrs -// } -// -// func newTestTx(privs []crypto.PrivKey) sdk.Tx { -// addrs := getAddrs(privs) -// msgs := make([]sdk.Msg, len(addrs)) -// for i, addr := range addrs { -// msgs[i] = sdk.NewTestMsg(addr) -// } -// return AccountLockTestTx{Msgs: msgs} -// } -// -// // Hack (too slow) -// func isMutexLock(mtx *sync.Mutex) bool { -// state := reflect.ValueOf(mtx).Elem().FieldByName("state") -// return state.Int() == 1 -// } +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/secp256k1" + "testing" +) + +func TestConvertByteSliceToString(t *testing.T) { + b := []byte{65, 66, 67, 0, 65, 66, 67} + s := string(b) + require.Equal(t, len(b), len(s)) + require.Equal(t, uint8(0), s[3]) +} + +func TestRegister(t *testing.T) { + app := setupBaseApp(t) + + privs := newTestPrivKeys(3) + tx := newTestTx(privs) + + waits, signals := app.checkAccountWGs.Register(tx) + + require.Equal(t, 0, len(waits)) + require.Equal(t, 3, len(signals)) + + for _, signal := range signals { + require.Equal(t, app.checkAccountWGs.wgs[signal.acc], signal.wg) + } +} + +func TestDontPanicWithNil(t *testing.T) { + app := setupBaseApp(t) + + require.NotPanics(t, func() { app.checkAccountWGs.Waits(nil) }) + require.NotPanics(t, func() { app.checkAccountWGs.Done(nil) }) +} + +func TestGetUniqSigners(t *testing.T) { + privs := newTestPrivKeys(3) + + addrs := getAddrs(privs) + addrs = append(addrs, addrs[1], addrs[0]) + require.Equal(t, 5, len(addrs)) + + tx := newTestTx(privs) + signers := getUniqSigners(tx) + + // length should be reduced because `duplicated` is removed + require.Less(t, len(signers), len(addrs)) + + // check uniqueness + for i, iv := range signers { + for j, jv := range signers { + if i != j { + require.True(t, iv != jv) + } + } + } +} + +type AccountLockTestTx struct { + Msgs []sdk.Msg +} + +var _ sdk.Tx = AccountLockTestTx{} + +func (tx AccountLockTestTx) GetMsgs() []sdk.Msg { + return tx.Msgs +} + +func (tx AccountLockTestTx) ValidateBasic() error { + return nil +} + +func newTestPrivKeys(num int) []crypto.PrivKey { + privs := make([]crypto.PrivKey, 0, num) + for i := 0; i < num; i++ { + privs = append(privs, secp256k1.GenPrivKey()) + } + return privs +} + +func getAddrs(privs []crypto.PrivKey) []sdk.AccAddress { + addrs := make([]sdk.AccAddress, 0, len(privs)) + for _, priv := range privs { + addrs = append(addrs, sdk.AccAddress(priv.PubKey().Address())) + } + return addrs +} + +func newTestTx(privs []crypto.PrivKey) sdk.Tx { + addrs := getAddrs(privs) + msgs := make([]sdk.Msg, len(addrs)) + for i, addr := range addrs { + msgs[i] = sdk.NewTestMsg(addr) + } + return AccountLockTestTx{Msgs: msgs} +} From 1b06bae994effd1d8c5c0f69219cf21dd0f16d00 Mon Sep 17 00:00:00 2001 From: "Kim, JinSan" Date: Mon, 25 Jan 2021 15:47:05 +0900 Subject: [PATCH 06/11] chore: revise code after cherry-pick --- baseapp/baseapp.go | 3 --- baseapp/reactor.go | 11 +++++------ 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index e232517b81..e33d3848f9 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -553,9 +553,6 @@ func (app *BaseApp) checkTx(txBytes []byte, tx sdk.Tx, recheck bool) (gInfo sdk. gInfo = sdk.GasInfo{GasWanted: gasCtx.GasMeter().Limit(), GasUsed: gasCtx.GasMeter().GasConsumed()} }() - accKeys := app.accountLock.Lock(tx) - defer app.accountLock.Unlock(accKeys) - var anteCtx sdk.Context anteCtx, err = app.anteTx(ctx, txBytes, tx, false) if !anteCtx.IsZero() { diff --git a/baseapp/reactor.go b/baseapp/reactor.go index 78e31b744b..7e3830f447 100644 --- a/baseapp/reactor.go +++ b/baseapp/reactor.go @@ -10,7 +10,7 @@ import ( ) func (app *BaseApp) startReactors() { - go app.checkTxReactor() + go app.startCheckTxAsyncReactor() } type RequestCheckTxAsync struct { @@ -22,7 +22,7 @@ type RequestCheckTxAsync struct { err error } -func (app *BaseApp) checkTxReactor() { +func (app *BaseApp) startCheckTxAsyncReactor() { for req := range app.chCheckTx { req.prepare.Wait() if req.err != nil { @@ -32,7 +32,7 @@ func (app *BaseApp) checkTxReactor() { waits, signals := app.checkAccountWGs.Register(req.tx) - go app.checkTxWithUnlock(req, waits, signals) + go app.checkTxAsync(req, waits, signals) } } @@ -41,13 +41,12 @@ func (app *BaseApp) prepareCheckTx(req *RequestCheckTxAsync) { req.tx, req.err = app.preCheckTx(req.txBytes) } -func (app *BaseApp) checkTxWithUnlock(req *RequestCheckTxAsync, waits []*sync.WaitGroup, signals []*AccountWG) { +func (app *BaseApp) checkTxAsync(req *RequestCheckTxAsync, waits []*sync.WaitGroup, signals []*AccountWG) { app.checkAccountWGs.Waits(waits) + defer app.checkAccountWGs.Done(signals) gInfo, err := app.checkTx(req.txBytes, req.tx, req.recheck) - app.checkAccountWGs.Done(signals) - if err != nil { req.callback(sdkerrors.ResponseCheckTx(err, gInfo.GasWanted, gInfo.GasUsed, app.trace)) return From 6e5a503354b62e200ce0b04aff7a715f63e750d8 Mon Sep 17 00:00:00 2001 From: "Kim, JinSan" Date: Mon, 25 Jan 2021 15:51:55 +0900 Subject: [PATCH 07/11] chore: bump-up tendermint & iavl --- go.mod | 4 ++-- go.sum | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index d63731de89..df8ef25491 100644 --- a/go.mod +++ b/go.mod @@ -46,6 +46,6 @@ require ( replace ( github.com/keybase/go-keychain => github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 - github.com/tendermint/iavl => github.com/line/iavl v0.14.4-0.20201217063301-6b67687bfae9 - github.com/tendermint/tendermint => ../tendermint + github.com/tendermint/iavl => github.com/line/iavl v0.14.4-0.20210122121727-7c33089230bd + github.com/tendermint/tendermint => github.com/line/tendermint v0.33.10-0.20210125064725-d1c50067c78a ) diff --git a/go.sum b/go.sum index 336794c005..68306fe99e 100644 --- a/go.sum +++ b/go.sum @@ -263,8 +263,10 @@ github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOS github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/line/iavl v0.14.4-0.20201217063301-6b67687bfae9 h1:n6YHVdTld8D0dAogBUcXTaqhk1ZMTAR9Phy4xdMVWDY= -github.com/line/iavl v0.14.4-0.20201217063301-6b67687bfae9/go.mod h1:eG6hI8RbMxL1nR+nJBykXD//gKjUpKCAT2tvi9V93sA= +github.com/line/iavl v0.14.4-0.20210122121727-7c33089230bd h1:IdJCRyraxeVrsrOTopF47yzZtRrWyCeAZh9iUiIHwqw= +github.com/line/iavl v0.14.4-0.20210122121727-7c33089230bd/go.mod h1:eG6hI8RbMxL1nR+nJBykXD//gKjUpKCAT2tvi9V93sA= +github.com/line/tendermint v0.33.10-0.20210125064725-d1c50067c78a h1:X8RHWLo+gqS7Dx9wenEl7oO1Zcy5W+RWhVyrhI7iL9M= +github.com/line/tendermint v0.33.10-0.20210125064725-d1c50067c78a/go.mod h1:0yUs9eIuuDq07nQql9BmI30FtYGcEC60Tu5JzB5IezM= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= From 52b3f3af3aa2c732574a0737609d957ede265222 Mon Sep 17 00:00:00 2001 From: "Kim, JinSan" Date: Mon, 25 Jan 2021 15:56:32 +0900 Subject: [PATCH 08/11] chore: rename func from `startCheckTxAsyncReactor()` to `checkTxAsyncReactor()` --- baseapp/reactor.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/baseapp/reactor.go b/baseapp/reactor.go index 7e3830f447..4cf748b61b 100644 --- a/baseapp/reactor.go +++ b/baseapp/reactor.go @@ -10,7 +10,7 @@ import ( ) func (app *BaseApp) startReactors() { - go app.startCheckTxAsyncReactor() + go app.checkTxAsyncReactor() } type RequestCheckTxAsync struct { @@ -22,7 +22,7 @@ type RequestCheckTxAsync struct { err error } -func (app *BaseApp) startCheckTxAsyncReactor() { +func (app *BaseApp) checkTxAsyncReactor() { for req := range app.chCheckTx { req.prepare.Wait() if req.err != nil { From bfa80ce678c3ddcb7a7b24847e3fdd3dde5d9ede Mon Sep 17 00:00:00 2001 From: "Kim, JinSan" Date: Mon, 25 Jan 2021 16:03:14 +0900 Subject: [PATCH 09/11] fix: imports for lint --- baseapp/accountwgs_test.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/baseapp/accountwgs_test.go b/baseapp/accountwgs_test.go index 47fb8ba64e..47e3264467 100644 --- a/baseapp/accountwgs_test.go +++ b/baseapp/accountwgs_test.go @@ -1,11 +1,13 @@ package baseapp import ( - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" + "testing" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/secp256k1" - "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" ) func TestConvertByteSliceToString(t *testing.T) { From 5ac1c566e1bdc56b8782a88320c886cd3c646691 Mon Sep 17 00:00:00 2001 From: "Kim, JinSan" Date: Mon, 25 Jan 2021 16:10:59 +0900 Subject: [PATCH 10/11] fix: imports for lint --- baseapp/accountwgs_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/baseapp/accountwgs_test.go b/baseapp/accountwgs_test.go index 47e3264467..d92a902bc2 100644 --- a/baseapp/accountwgs_test.go +++ b/baseapp/accountwgs_test.go @@ -1,9 +1,10 @@ package baseapp import ( - "github.com/stretchr/testify/require" "testing" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/secp256k1" From cc6f354b4e24118dfe60d3723a6f937e4c6c07f2 Mon Sep 17 00:00:00 2001 From: "Kim, JinSan" Date: Mon, 25 Jan 2021 21:32:19 +0900 Subject: [PATCH 11/11] chore: rename `Waits()` to `Wait()` --- baseapp/abci.go | 2 +- baseapp/accountwgs.go | 2 +- baseapp/accountwgs_test.go | 2 +- baseapp/reactor.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/baseapp/abci.go b/baseapp/abci.go index 0b1899f99e..2feabf2104 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -173,7 +173,7 @@ func (app *BaseApp) CheckTxSync(req abci.RequestCheckTx) abci.ResponseCheckTx { waits, signals := app.checkAccountWGs.Register(tx) - app.checkAccountWGs.Waits(waits) + app.checkAccountWGs.Wait(waits) defer app.checkAccountWGs.Done(signals) gInfo, err := app.checkTx(req.Tx, tx, req.Type == abci.CheckTxType_Recheck) diff --git a/baseapp/accountwgs.go b/baseapp/accountwgs.go index 1d417011b4..e9d3f74777 100644 --- a/baseapp/accountwgs.go +++ b/baseapp/accountwgs.go @@ -34,7 +34,7 @@ func (aw *AccountWGs) Register(tx sdk.Tx) (waits []*sync.WaitGroup, signals []*A return waits, signals } -func (aw *AccountWGs) Waits(waits []*sync.WaitGroup) { +func (aw *AccountWGs) Wait(waits []*sync.WaitGroup) { for _, wait := range waits { wait.Wait() } diff --git a/baseapp/accountwgs_test.go b/baseapp/accountwgs_test.go index d92a902bc2..7eecc39ee8 100644 --- a/baseapp/accountwgs_test.go +++ b/baseapp/accountwgs_test.go @@ -37,7 +37,7 @@ func TestRegister(t *testing.T) { func TestDontPanicWithNil(t *testing.T) { app := setupBaseApp(t) - require.NotPanics(t, func() { app.checkAccountWGs.Waits(nil) }) + require.NotPanics(t, func() { app.checkAccountWGs.Wait(nil) }) require.NotPanics(t, func() { app.checkAccountWGs.Done(nil) }) } diff --git a/baseapp/reactor.go b/baseapp/reactor.go index 4cf748b61b..5e54661438 100644 --- a/baseapp/reactor.go +++ b/baseapp/reactor.go @@ -42,7 +42,7 @@ func (app *BaseApp) prepareCheckTx(req *RequestCheckTxAsync) { } func (app *BaseApp) checkTxAsync(req *RequestCheckTxAsync, waits []*sync.WaitGroup, signals []*AccountWG) { - app.checkAccountWGs.Waits(waits) + app.checkAccountWGs.Wait(waits) defer app.checkAccountWGs.Done(signals) gInfo, err := app.checkTx(req.txBytes, req.tx, req.recheck)