From 0de4bec862d391cd0a581a3c63ad008b86477455 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Mon, 30 Nov 2020 12:13:25 +0000 Subject: [PATCH 1/2] use Cleanup(),TempDir() in test cases (#5723) Replace defer with t.Cleanup(). Replace the combination of ioutil.TempDir, error checking and defer os.RemoveAll() with Go testing.T's new TempDir() helper. Mark auxiliary functions as test helpers. --- .github/workflows/coverage.yml | 8 +- .github/workflows/docker.yml | 2 +- .github/workflows/e2e-nightly.yml | 2 +- .github/workflows/e2e.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/tests.yml | 8 +- consensus/invalid_test.go | 4 +- consensus/mempool_test.go | 8 +- consensus/replay_test.go | 17 ++-- consensus/wal_test.go | 34 +++----- p2p/conn/connection_test.go | 115 +++++++++++++------------- p2p/conn/secret_connection_test.go | 9 +-- p2p/pex/addrbook_test.go | 88 +++++++------------- p2p/pex/pex_reactor_test.go | 125 +++++++++-------------------- p2p/trust/store_test.go | 6 +- 15 files changed, 167 insertions(+), 263 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 2751b7c15..344ac8a18 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -44,7 +44,7 @@ jobs: steps: - uses: actions/setup-go@v2 with: - go-version: "^1.15.4" + go-version: "1.15" - uses: actions/checkout@v2 - uses: technote-space/get-diff-action@v4 with: @@ -66,7 +66,7 @@ jobs: steps: - uses: actions/setup-go@v2 with: - go-version: "^1.15.4" + go-version: "1.15" - uses: actions/checkout@v2 - uses: technote-space/get-diff-action@v4 with: @@ -78,6 +78,10 @@ jobs: with: name: "${{ github.sha }}-${{ matrix.part }}" if: env.GIT_DIFF + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: 1.15 - name: test & coverage report creation run: | cat pkgs.txt.part.${{ matrix.part }} | xargs go test -mod=readonly -timeout 8m -race -coverprofile=${{ matrix.part }}profile.out -covermode=atomic diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 0a1dab464..a5bfbc861 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -16,7 +16,7 @@ jobs: steps: - uses: actions/setup-go@v2 with: - go-version: "^1.15.4" + go-version: "1.15" - uses: actions/checkout@master - name: Prepare id: prep diff --git a/.github/workflows/e2e-nightly.yml b/.github/workflows/e2e-nightly.yml index b21a482c0..c56e41e68 100644 --- a/.github/workflows/e2e-nightly.yml +++ b/.github/workflows/e2e-nightly.yml @@ -18,7 +18,7 @@ jobs: steps: - uses: actions/setup-go@v2 with: - go-version: '^1.15.4' + go-version: '1.15' - uses: actions/checkout@v2 diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 6ac2077ac..ed26718ca 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -15,7 +15,7 @@ jobs: steps: - uses: actions/setup-go@v2 with: - go-version: '^1.15.4' + go-version: '1.15' - uses: actions/checkout@v2 - uses: technote-space/get-diff-action@v4 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6411a2d3f..46b55eee2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/setup-go@v2 with: - go-version: '^1.15.4' + go-version: '1.15' - run: echo https://github.com/tendermint/tendermint/blob/${GITHUB_REF#refs/tags/}/CHANGELOG.md#${GITHUB_REF#refs/tags/} > ../release_notes.md diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 56f5ca437..fba5a9913 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -25,7 +25,7 @@ jobs: steps: - uses: actions/setup-go@v2 with: - go-version: "^1.15.4" + go-version: "1.15" - uses: actions/checkout@v2 - uses: technote-space/get-diff-action@v4 with: @@ -57,7 +57,7 @@ jobs: steps: - uses: actions/setup-go@v2 with: - go-version: "^1.15.4" + go-version: "1.15" - uses: actions/checkout@v2 - uses: technote-space/get-diff-action@v4 with: @@ -89,7 +89,7 @@ jobs: steps: - uses: actions/setup-go@v2 with: - go-version: "^1.15.4" + go-version: "1.15" - uses: actions/checkout@v2 - uses: technote-space/get-diff-action@v4 with: @@ -120,7 +120,7 @@ jobs: steps: - uses: actions/setup-go@v2 with: - go-version: "^1.15.4" + go-version: "1.15" - uses: actions/checkout@v2 - uses: technote-space/get-diff-action@v4 with: diff --git a/consensus/invalid_test.go b/consensus/invalid_test.go index 907693c57..5b161dd71 100644 --- a/consensus/invalid_test.go +++ b/consensus/invalid_test.go @@ -19,7 +19,7 @@ import ( func TestReactorInvalidPrecommit(t *testing.T) { N := 4 css, cleanup := randConsensusNet(N, "consensus_reactor_test", newMockTickerFunc(true), newCounter) - defer cleanup() + t.Cleanup(cleanup) for i := 0; i < 4; i++ { ticker := NewTimeoutTicker() @@ -43,7 +43,7 @@ func TestReactorInvalidPrecommit(t *testing.T) { invalidDoPrevoteFunc(t, height, round, byzVal, byzR.Switch, pv) } byzVal.mtx.Unlock() - defer stopConsensusNet(log.TestingLogger(), reactors, eventBuses) + t.Cleanup(func() { stopConsensusNet(log.TestingLogger(), reactors, eventBuses) }) // wait for a bunch of blocks // TODO: make this tighter by ensuring the halt happens by block 2 diff --git a/consensus/mempool_test.go b/consensus/mempool_test.go index db9662acb..c53185048 100644 --- a/consensus/mempool_test.go +++ b/consensus/mempool_test.go @@ -26,7 +26,8 @@ func assertMempool(txn txNotifier) mempl.Mempool { func TestMempoolNoProgressUntilTxsAvailable(t *testing.T) { config := ResetConfig("consensus_mempool_txs_available_test") - defer os.RemoveAll(config.RootDir) + t.Cleanup(func() { _ = os.RemoveAll(config.RootDir) }) + config.Consensus.CreateEmptyBlocks = false state, privVals := randGenesisState(1, false, 10) cs := newStateWithConfig(config, state, privVals[0], NewCounterApplication()) @@ -45,7 +46,7 @@ func TestMempoolNoProgressUntilTxsAvailable(t *testing.T) { func TestMempoolProgressAfterCreateEmptyBlocksInterval(t *testing.T) { config := ResetConfig("consensus_mempool_txs_available_test") - defer os.RemoveAll(config.RootDir) + t.Cleanup(func() { _ = os.RemoveAll(config.RootDir) }) config.Consensus.CreateEmptyBlocksInterval = ensureTimeout state, privVals := randGenesisState(1, false, 10) @@ -63,7 +64,8 @@ func TestMempoolProgressAfterCreateEmptyBlocksInterval(t *testing.T) { func TestMempoolProgressInHigherRound(t *testing.T) { config := ResetConfig("consensus_mempool_txs_available_test") - defer os.RemoveAll(config.RootDir) + t.Cleanup(func() { _ = os.RemoveAll(config.RootDir) }) + config.Consensus.CreateEmptyBlocks = false state, privVals := randGenesisState(1, false, 10) cs := newStateWithConfig(config, state, privVals[0], NewCounterApplication()) diff --git a/consensus/replay_test.go b/consensus/replay_test.go index 2970f15ed..b40d408c2 100644 --- a/consensus/replay_test.go +++ b/consensus/replay_test.go @@ -83,11 +83,11 @@ func startNewStateAndWaitForBlock(t *testing.T, consensusReplayConfig *cfg.Confi err := cs.Start() require.NoError(t, err) - defer func() { + t.Cleanup(func() { if err := cs.Stop(); err != nil { t.Error(err) } - }() + }) // This is just a signal that we haven't halted; its not something contained // in the WAL itself. Assuming the consensus state is running, replay of any @@ -136,10 +136,10 @@ func TestWALCrash(t *testing.T) { 3}, } - for i, tc := range testCases { + for _, tc := range testCases { tc := tc - consensusReplayConfig := ResetConfig(fmt.Sprintf("%s_%d", t.Name(), i)) t.Run(tc.name, func(t *testing.T) { + consensusReplayConfig := ResetConfig(tc.name) crashWALandCheckLiveness(t, consensusReplayConfig, tc.initFn, tc.heightToStop) }) } @@ -658,7 +658,7 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin var genesisState sm.State if testValidatorsChange { testConfig := ResetConfig(fmt.Sprintf("%s_%v_m", t.Name(), mode)) - defer os.RemoveAll(testConfig.RootDir) + t.Cleanup(func() { _ = os.RemoveAll(testConfig.RootDir) }) stateDB = dbm.NewMemDB() genesisState = sim.GenesisState @@ -668,7 +668,7 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin store = newMockBlockStore(config, genesisState.ConsensusParams) } else { // test single node testConfig := ResetConfig(fmt.Sprintf("%s_%v_s", t.Name(), mode)) - defer os.RemoveAll(testConfig.RootDir) + t.Cleanup(func() { _ = os.RemoveAll(testConfig.RootDir) }) walBody, err := WALWithNBlocks(t, numBlocks) require.NoError(t, err) walFile := tempWALWithData(walBody) @@ -885,7 +885,7 @@ func TestHandshakePanicsIfAppReturnsWrongAppHash(t *testing.T) { // - 0x02 // - 0x03 config := ResetConfig("handshake_test_") - defer os.RemoveAll(config.RootDir) + t.Cleanup(func() { os.RemoveAll(config.RootDir) }) privVal := privval.LoadFilePV(config.PrivValidatorKeyFile(), config.PrivValidatorStateFile()) const appVersion = 0x0 pubKey, err := privVal.GetPubKey() @@ -1220,7 +1220,8 @@ func TestHandshakeUpdatesValidators(t *testing.T) { clientCreator := proxy.NewLocalClientCreator(app) config := ResetConfig("handshake_test_") - defer os.RemoveAll(config.RootDir) + t.Cleanup(func() { _ = os.RemoveAll(config.RootDir) }) + privVal := privval.LoadFilePV(config.PrivValidatorKeyFile(), config.PrivValidatorStateFile()) pubKey, err := privVal.GetPubKey() require.NoError(t, err) diff --git a/consensus/wal_test.go b/consensus/wal_test.go index 4ee813609..a64ecc9a5 100644 --- a/consensus/wal_test.go +++ b/consensus/wal_test.go @@ -3,8 +3,6 @@ package consensus import ( "bytes" "crypto/rand" - "io/ioutil" - "os" "path/filepath" // "sync" @@ -27,10 +25,7 @@ const ( ) func TestWALTruncate(t *testing.T) { - walDir, err := ioutil.TempDir("", "wal") - require.NoError(t, err) - defer os.RemoveAll(walDir) - + walDir := t.TempDir() walFile := filepath.Join(walDir, "wal") // this magic number 4K can truncate the content when RotateFile. @@ -45,14 +40,14 @@ func TestWALTruncate(t *testing.T) { wal.SetLogger(log.TestingLogger()) err = wal.Start() require.NoError(t, err) - defer func() { + t.Cleanup(func() { if err := wal.Stop(); err != nil { t.Error(err) } // wait for the wal to finish shutting down so we // can safely remove the directory wal.Wait() - }() + }) // 60 block's size nearly 70K, greater than group's headBuf size(4096 * 10), // when headBuf is full, truncate content will Flush to the file. at this @@ -71,7 +66,7 @@ func TestWALTruncate(t *testing.T) { assert.NoError(t, err, "expected not to err on height %d", h) assert.True(t, found, "expected to find end height for %d", h) assert.NotNil(t, gr) - defer gr.Close() + t.Cleanup(func() { _ = gr.Close() }) dec := NewWALDecoder(gr) msg, err := dec.Decode() @@ -109,23 +104,21 @@ func TestWALEncoderDecoder(t *testing.T) { } func TestWALWrite(t *testing.T) { - walDir, err := ioutil.TempDir("", "wal") - require.NoError(t, err) - defer os.RemoveAll(walDir) + walDir := t.TempDir() walFile := filepath.Join(walDir, "wal") wal, err := NewWAL(walFile) require.NoError(t, err) err = wal.Start() require.NoError(t, err) - defer func() { + t.Cleanup(func() { if err := wal.Stop(); err != nil { t.Error(err) } // wait for the wal to finish shutting down so we // can safely remove the directory wal.Wait() - }() + }) // 1) Write returns an error if msg is too big msg := &BlockPartMessage{ @@ -166,7 +159,7 @@ func TestWALSearchForEndHeight(t *testing.T) { assert.NoError(t, err, "expected not to err on height %d", h) assert.True(t, found, "expected to find end height for %d", h) assert.NotNil(t, gr) - defer gr.Close() + t.Cleanup(func() { _ = gr.Close() }) dec := NewWALDecoder(gr) msg, err := dec.Decode() @@ -177,12 +170,10 @@ func TestWALSearchForEndHeight(t *testing.T) { } func TestWALPeriodicSync(t *testing.T) { - walDir, err := ioutil.TempDir("", "wal") - require.NoError(t, err) - defer os.RemoveAll(walDir) - + walDir := t.TempDir() walFile := filepath.Join(walDir, "wal") wal, err := NewWAL(walFile, autofile.GroupCheckDuration(1*time.Millisecond)) + require.NoError(t, err) wal.SetFlushInterval(walTestFlushInterval) @@ -196,12 +187,12 @@ func TestWALPeriodicSync(t *testing.T) { assert.NotZero(t, wal.Group().Buffered()) require.NoError(t, wal.Start()) - defer func() { + t.Cleanup(func() { if err := wal.Stop(); err != nil { t.Error(err) } wal.Wait() - }() + }) time.Sleep(walTestFlushInterval + (10 * time.Millisecond)) @@ -239,7 +230,6 @@ func nBytes(n int) []byte { func benchmarkWalDecode(b *testing.B, n int) { // registerInterfacesOnce() - buf := new(bytes.Buffer) enc := NewWALEncoder(buf) diff --git a/p2p/conn/connection_test.go b/p2p/conn/connection_test.go index a189e8b89..12f68f437 100644 --- a/p2p/conn/connection_test.go +++ b/p2p/conn/connection_test.go @@ -45,13 +45,12 @@ func createMConnectionWithCallbacks( func TestMConnectionSendFlushStop(t *testing.T) { server, client := NetPipe() - defer server.Close() - defer client.Close() + t.Cleanup(closeAll(t, client, server)) clientConn := createTestMConnection(client) err := clientConn.Start() require.Nil(t, err) - defer clientConn.Stop() // nolint:errcheck // ignore for tests + t.Cleanup(stopAll(t, clientConn)) msg := []byte("abc") assert.True(t, clientConn.Send(0x01, msg)) @@ -83,13 +82,12 @@ func TestMConnectionSendFlushStop(t *testing.T) { func TestMConnectionSend(t *testing.T) { server, client := NetPipe() - defer server.Close() - defer client.Close() + t.Cleanup(closeAll(t, client, server)) mconn := createTestMConnection(client) err := mconn.Start() require.Nil(t, err) - defer mconn.Stop() // nolint:errcheck // ignore for tests + t.Cleanup(stopAll(t, mconn)) msg := []byte("Ant-Man") assert.True(t, mconn.Send(0x01, msg)) @@ -114,8 +112,7 @@ func TestMConnectionSend(t *testing.T) { func TestMConnectionReceive(t *testing.T) { server, client := NetPipe() - defer server.Close() - defer client.Close() + t.Cleanup(closeAll(t, client, server)) receivedCh := make(chan []byte) errorsCh := make(chan interface{}) @@ -128,12 +125,12 @@ func TestMConnectionReceive(t *testing.T) { mconn1 := createMConnectionWithCallbacks(client, onReceive, onError) err := mconn1.Start() require.Nil(t, err) - defer mconn1.Stop() // nolint:errcheck // ignore for tests + t.Cleanup(stopAll(t, mconn1)) mconn2 := createTestMConnection(server) err = mconn2.Start() require.Nil(t, err) - defer mconn2.Stop() // nolint:errcheck // ignore for tests + t.Cleanup(stopAll(t, mconn2)) msg := []byte("Cyclops") assert.True(t, mconn2.Send(0x01, msg)) @@ -150,13 +147,12 @@ func TestMConnectionReceive(t *testing.T) { func TestMConnectionStatus(t *testing.T) { server, client := NetPipe() - defer server.Close() - defer client.Close() + t.Cleanup(closeAll(t, client, server)) mconn := createTestMConnection(client) err := mconn.Start() require.Nil(t, err) - defer mconn.Stop() // nolint:errcheck // ignore for tests + t.Cleanup(stopAll(t, mconn)) status := mconn.Status() assert.NotNil(t, status) @@ -165,8 +161,7 @@ func TestMConnectionStatus(t *testing.T) { func TestMConnectionPongTimeoutResultsInError(t *testing.T) { server, client := net.Pipe() - defer server.Close() - defer client.Close() + t.Cleanup(closeAll(t, client, server)) receivedCh := make(chan []byte) errorsCh := make(chan interface{}) @@ -179,7 +174,7 @@ func TestMConnectionPongTimeoutResultsInError(t *testing.T) { mconn := createMConnectionWithCallbacks(client, onReceive, onError) err := mconn.Start() require.Nil(t, err) - defer mconn.Stop() // nolint:errcheck // ignore for tests + t.Cleanup(stopAll(t, mconn)) serverGotPing := make(chan struct{}) go func() { @@ -204,8 +199,7 @@ func TestMConnectionPongTimeoutResultsInError(t *testing.T) { func TestMConnectionMultiplePongsInTheBeginning(t *testing.T) { server, client := net.Pipe() - defer server.Close() - defer client.Close() + t.Cleanup(closeAll(t, client, server)) receivedCh := make(chan []byte) errorsCh := make(chan interface{}) @@ -218,7 +212,7 @@ func TestMConnectionMultiplePongsInTheBeginning(t *testing.T) { mconn := createMConnectionWithCallbacks(client, onReceive, onError) err := mconn.Start() require.Nil(t, err) - defer mconn.Stop() // nolint:errcheck // ignore for tests + t.Cleanup(stopAll(t, mconn)) // sending 3 pongs in a row (abuse) protoWriter := protoio.NewDelimitedWriter(server) @@ -259,8 +253,7 @@ func TestMConnectionMultiplePongsInTheBeginning(t *testing.T) { func TestMConnectionMultiplePings(t *testing.T) { server, client := net.Pipe() - defer server.Close() - defer client.Close() + t.Cleanup(closeAll(t, client, server)) receivedCh := make(chan []byte) errorsCh := make(chan interface{}) @@ -273,7 +266,7 @@ func TestMConnectionMultiplePings(t *testing.T) { mconn := createMConnectionWithCallbacks(client, onReceive, onError) err := mconn.Start() require.Nil(t, err) - defer mconn.Stop() // nolint:errcheck // ignore for tests + t.Cleanup(stopAll(t, mconn)) // sending 3 pings in a row (abuse) // see https://github.com/tendermint/tendermint/issues/1190 @@ -304,12 +297,10 @@ func TestMConnectionMultiplePings(t *testing.T) { func TestMConnectionPingPongs(t *testing.T) { // check that we are not leaking any go-routines - defer leaktest.CheckTimeout(t, 10*time.Second)() + t.Cleanup(leaktest.CheckTimeout(t, 10*time.Second)) server, client := net.Pipe() - - defer server.Close() - defer client.Close() + t.Cleanup(closeAll(t, client, server)) receivedCh := make(chan []byte) errorsCh := make(chan interface{}) @@ -322,7 +313,7 @@ func TestMConnectionPingPongs(t *testing.T) { mconn := createMConnectionWithCallbacks(client, onReceive, onError) err := mconn.Start() require.Nil(t, err) - defer mconn.Stop() // nolint:errcheck // ignore for tests + t.Cleanup(stopAll(t, mconn)) serverGotPing := make(chan struct{}) go func() { @@ -366,8 +357,7 @@ func TestMConnectionPingPongs(t *testing.T) { func TestMConnectionStopsAndReturnsError(t *testing.T) { server, client := NetPipe() - defer server.Close() - defer client.Close() + t.Cleanup(closeAll(t, client, server)) receivedCh := make(chan []byte) errorsCh := make(chan interface{}) @@ -380,7 +370,7 @@ func TestMConnectionStopsAndReturnsError(t *testing.T) { mconn := createMConnectionWithCallbacks(client, onReceive, onError) err := mconn.Start() require.Nil(t, err) - defer mconn.Stop() // nolint:errcheck // ignore for tests + t.Cleanup(stopAll(t, mconn)) if err := client.Close(); err != nil { t.Error(err) @@ -446,18 +436,7 @@ func TestMConnectionReadErrorBadEncoding(t *testing.T) { _, err := client.Write([]byte{1, 2, 3, 4, 5}) require.NoError(t, err) assert.True(t, expectSend(chOnErr), "badly encoded msgPacket") - - t.Cleanup(func() { - if err := mconnClient.Stop(); err != nil { - t.Log(err) - } - }) - - t.Cleanup(func() { - if err := mconnServer.Stop(); err != nil { - t.Log(err) - } - }) + t.Cleanup(stopAll(t, mconnClient, mconnServer)) } func TestMConnectionReadErrorUnknownChannel(t *testing.T) { @@ -473,18 +452,7 @@ func TestMConnectionReadErrorUnknownChannel(t *testing.T) { // should cause an error assert.True(t, mconnClient.Send(0x02, msg)) assert.True(t, expectSend(chOnErr), "unknown channel") - - t.Cleanup(func() { - if err := mconnClient.Stop(); err != nil { - t.Log(err) - } - }) - - t.Cleanup(func() { - if err := mconnServer.Stop(); err != nil { - t.Log(err) - } - }) + t.Cleanup(stopAll(t, mconnClient, mconnServer)) } func TestMConnectionReadErrorLongMessage(t *testing.T) { @@ -492,8 +460,7 @@ func TestMConnectionReadErrorLongMessage(t *testing.T) { chOnRcv := make(chan struct{}) mconnClient, mconnServer := newClientAndServerConnsForReadErrors(t, chOnErr) - defer mconnClient.Stop() // nolint:errcheck // ignore for tests - defer mconnServer.Stop() // nolint:errcheck // ignore for tests + t.Cleanup(stopAll(t, mconnClient, mconnServer)) mconnServer.onReceive = func(chID byte, msgBytes []byte) { chOnRcv <- struct{}{} @@ -528,8 +495,7 @@ func TestMConnectionReadErrorLongMessage(t *testing.T) { func TestMConnectionReadErrorUnknownMsgType(t *testing.T) { chOnErr := make(chan struct{}) mconnClient, mconnServer := newClientAndServerConnsForReadErrors(t, chOnErr) - defer mconnClient.Stop() // nolint:errcheck // ignore for tests - defer mconnServer.Stop() // nolint:errcheck // ignore for tests + t.Cleanup(stopAll(t, mconnClient, mconnServer)) // send msg with unknown msg type _, err := protoio.NewDelimitedWriter(mconnClient.conn).WriteMsg(&types.Header{ChainID: "x"}) @@ -539,13 +505,12 @@ func TestMConnectionReadErrorUnknownMsgType(t *testing.T) { func TestMConnectionTrySend(t *testing.T) { server, client := NetPipe() - defer server.Close() - defer client.Close() + t.Cleanup(closeAll(t, client, server)) mconn := createTestMConnection(client) err := mconn.Start() require.Nil(t, err) - defer mconn.Stop() // nolint:errcheck // ignore for tests + t.Cleanup(stopAll(t, mconn)) msg := []byte("Semicolon-Woman") resultCh := make(chan string, 2) @@ -587,3 +552,31 @@ func TestConnVectors(t *testing.T) { require.Equal(t, tc.expBytes, hex.EncodeToString(bz), tc.testName) } } + +type stopper interface { + Stop() error +} + +func stopAll(t *testing.T, stoppers ...stopper) func() { + return func() { + for _, s := range stoppers { + if err := s.Stop(); err != nil { + t.Log(err) + } + } + } +} + +type closer interface { + Close() error +} + +func closeAll(t *testing.T, closers ...closer) func() { + return func() { + for _, s := range closers { + if err := s.Close(); err != nil { + t.Log(err) + } + } + } +} diff --git a/p2p/conn/secret_connection_test.go b/p2p/conn/secret_connection_test.go index e787e1348..2bbe31fef 100644 --- a/p2p/conn/secret_connection_test.go +++ b/p2p/conn/secret_connection_test.go @@ -234,7 +234,7 @@ func TestDeriveSecretsAndChallengeGolden(t *testing.T) { if err != nil { log.Fatal(err) } - defer f.Close() + t.Cleanup(closeAll(t, f)) scanner := bufio.NewScanner(f) for scanner.Scan() { line := scanner.Text() @@ -258,8 +258,7 @@ func TestDeriveSecretsAndChallengeGolden(t *testing.T) { func TestNilPubkey(t *testing.T) { var fooConn, barConn = makeKVStoreConnPair() - defer fooConn.Close() - defer barConn.Close() + t.Cleanup(closeAll(t, fooConn, barConn)) var fooPrvKey = ed25519.GenPrivKey() var barPrvKey = privKeyWithNilPubKey{ed25519.GenPrivKey()} @@ -272,8 +271,8 @@ func TestNilPubkey(t *testing.T) { func TestNonEd25519Pubkey(t *testing.T) { var fooConn, barConn = makeKVStoreConnPair() - defer fooConn.Close() - defer barConn.Close() + t.Cleanup(closeAll(t, fooConn, barConn)) + var fooPrvKey = ed25519.GenPrivKey() var barPrvKey = sr25519.GenPrivKey() diff --git a/p2p/pex/addrbook_test.go b/p2p/pex/addrbook_test.go index ad41d5562..21e098499 100644 --- a/p2p/pex/addrbook_test.go +++ b/p2p/pex/addrbook_test.go @@ -22,8 +22,7 @@ import ( // FIXME These tests should not rely on .(*addrBook) assertions func TestAddrBookPickAddress(t *testing.T) { - fname := createTempFileName("addrbook_test") - defer deleteTempFile(fname) + fname := createTempFileName(t, "addrbook_test") // 0 addresses book := NewAddrBook(fname, true) @@ -59,8 +58,7 @@ func TestAddrBookPickAddress(t *testing.T) { } func TestAddrBookSaveLoad(t *testing.T) { - fname := createTempFileName("addrbook_test") - defer deleteTempFile(fname) + fname := createTempFileName(t, "addrbook_test") // 0 addresses book := NewAddrBook(fname, true) @@ -94,9 +92,7 @@ func TestAddrBookSaveLoad(t *testing.T) { } func TestAddrBookLookup(t *testing.T) { - fname := createTempFileName("addrbook_test") - defer deleteTempFile(fname) - + fname := createTempFileName(t, "addrbook_test") randAddrs := randNetAddressPairs(t, 100) book := NewAddrBook(fname, true) @@ -113,9 +109,7 @@ func TestAddrBookLookup(t *testing.T) { } func TestAddrBookPromoteToOld(t *testing.T) { - fname := createTempFileName("addrbook_test") - defer deleteTempFile(fname) - + fname := createTempFileName(t, "addrbook_test") randAddrs := randNetAddressPairs(t, 100) book := NewAddrBook(fname, true) @@ -157,10 +151,9 @@ func TestAddrBookPromoteToOld(t *testing.T) { } func TestAddrBookHandlesDuplicates(t *testing.T) { - fname := createTempFileName("addrbook_test") - defer deleteTempFile(fname) - + fname := createTempFileName(t, "addrbook_test") book := NewAddrBook(fname, true) + book.SetLogger(log.TestingLogger()) randAddrs := randNetAddressPairs(t, 100) @@ -211,9 +204,7 @@ func randIPv4Address(t *testing.T) *p2p.NetAddress { } func TestAddrBookRemoveAddress(t *testing.T) { - fname := createTempFileName("addrbook_test") - defer deleteTempFile(fname) - + fname := createTempFileName(t, "addrbook_test") book := NewAddrBook(fname, true) book.SetLogger(log.TestingLogger()) @@ -232,9 +223,7 @@ func TestAddrBookRemoveAddress(t *testing.T) { func TestAddrBookGetSelectionWithOneMarkedGood(t *testing.T) { // create a book with 10 addresses, 1 good/old and 9 new - book, fname := createAddrBookWithMOldAndNNewAddrs(t, 1, 9) - defer deleteTempFile(fname) - + book, _ := createAddrBookWithMOldAndNNewAddrs(t, 1, 9) addrs := book.GetSelectionWithBias(biasToSelectNewPeers) assert.NotNil(t, addrs) assertMOldAndNNewAddrsInSelection(t, 1, 9, addrs, book) @@ -242,26 +231,20 @@ func TestAddrBookGetSelectionWithOneMarkedGood(t *testing.T) { func TestAddrBookGetSelectionWithOneNotMarkedGood(t *testing.T) { // create a book with 10 addresses, 9 good/old and 1 new - book, fname := createAddrBookWithMOldAndNNewAddrs(t, 9, 1) - defer deleteTempFile(fname) - + book, _ := createAddrBookWithMOldAndNNewAddrs(t, 9, 1) addrs := book.GetSelectionWithBias(biasToSelectNewPeers) assert.NotNil(t, addrs) assertMOldAndNNewAddrsInSelection(t, 9, 1, addrs, book) } func TestAddrBookGetSelectionReturnsNilWhenAddrBookIsEmpty(t *testing.T) { - book, fname := createAddrBookWithMOldAndNNewAddrs(t, 0, 0) - defer deleteTempFile(fname) - + book, _ := createAddrBookWithMOldAndNNewAddrs(t, 0, 0) addrs := book.GetSelectionWithBias(biasToSelectNewPeers) assert.Nil(t, addrs) } func TestAddrBookGetSelection(t *testing.T) { - fname := createTempFileName("addrbook_test") - defer deleteTempFile(fname) - + fname := createTempFileName(t, "addrbook_test") book := NewAddrBook(fname, true) book.SetLogger(log.TestingLogger()) @@ -301,9 +284,7 @@ func TestAddrBookGetSelection(t *testing.T) { func TestAddrBookGetSelectionWithBias(t *testing.T) { const biasTowardsNewAddrs = 30 - fname := createTempFileName("addrbook_test") - defer deleteTempFile(fname) - + fname := createTempFileName(t, "addrbook_test") book := NewAddrBook(fname, true) book.SetLogger(log.TestingLogger()) @@ -384,9 +365,7 @@ func TestAddrBookGetSelectionWithBias(t *testing.T) { } func TestAddrBookHasAddress(t *testing.T) { - fname := createTempFileName("addrbook_test") - defer deleteTempFile(fname) - + fname := createTempFileName(t, "addrbook_test") book := NewAddrBook(fname, true) book.SetLogger(log.TestingLogger()) addr := randIPv4Address(t) @@ -401,6 +380,7 @@ func TestAddrBookHasAddress(t *testing.T) { } func testCreatePrivateAddrs(t *testing.T, numAddrs int) ([]*p2p.NetAddress, []string) { + t.Helper() addrs := make([]*p2p.NetAddress, numAddrs) for i := 0; i < numAddrs; i++ { addrs[i] = randIPv4Address(t) @@ -414,9 +394,7 @@ func testCreatePrivateAddrs(t *testing.T, numAddrs int) ([]*p2p.NetAddress, []st } func TestBanBadPeers(t *testing.T) { - fname := createTempFileName("addrbook_test") - defer deleteTempFile(fname) - + fname := createTempFileName(t, "addrbook_test") book := NewAddrBook(fname, true) book.SetLogger(log.TestingLogger()) @@ -441,9 +419,7 @@ func TestBanBadPeers(t *testing.T) { } func TestAddrBookEmpty(t *testing.T) { - fname := createTempFileName("addrbook_test") - defer deleteTempFile(fname) - + fname := createTempFileName(t, "addrbook_test") book := NewAddrBook(fname, true) book.SetLogger(log.TestingLogger()) // Check that empty book is empty @@ -463,9 +439,7 @@ func TestAddrBookEmpty(t *testing.T) { } func TestPrivatePeers(t *testing.T) { - fname := createTempFileName("addrbook_test") - defer deleteTempFile(fname) - + fname := createTempFileName(t, "addrbook_test") book := NewAddrBook(fname, true) book.SetLogger(log.TestingLogger()) @@ -496,8 +470,7 @@ func testAddrBookAddressSelection(t *testing.T, bookSize int) { dbgStr := fmt.Sprintf("book of size %d (new %d, old %d)", bookSize, nBookNew, nBookOld) // create book and get selection - book, fname := createAddrBookWithMOldAndNNewAddrs(t, nBookOld, nBookNew) - defer deleteTempFile(fname) + book, _ := createAddrBookWithMOldAndNNewAddrs(t, nBookOld, nBookNew) addrs := book.GetSelectionWithBias(biasToSelectNewPeers) assert.NotNil(t, addrs, "%s - expected a non-nil selection", dbgStr) nAddrs := len(addrs) @@ -590,8 +563,7 @@ func TestMultipleAddrBookAddressSelection(t *testing.T) { } func TestAddrBookAddDoesNotOverwriteOldIP(t *testing.T) { - fname := createTempFileName("addrbook_test") - defer deleteTempFile(fname) + fname := createTempFileName(t, "addrbook_test") // This test creates adds a peer to the address book and marks it good // It then attempts to override the peer's IP, by adding a peer with the same ID @@ -717,28 +689,26 @@ func assertMOldAndNNewAddrsInSelection(t *testing.T, m, n int, addrs []*p2p.NetA assert.Equal(t, n, nNew, "new addresses") } -func createTempFileName(prefix string) string { +func createTempFileName(t *testing.T, prefix string) string { + t.Helper() f, err := ioutil.TempFile("", prefix) if err != nil { panic(err) } + fname := f.Name() - err = f.Close() - if err != nil { - panic(err) + if err := f.Close(); err != nil { + t.Fatal(err) } + + t.Cleanup(func() { _ = os.Remove(fname) }) + return fname } -func deleteTempFile(fname string) { - err := os.Remove(fname) - if err != nil { - panic(err) - } -} - func createAddrBookWithMOldAndNNewAddrs(t *testing.T, nOld, nNew int) (book *addrBook, fname string) { - fname = createTempFileName("addrbook_test") + t.Helper() + fname = createTempFileName(t, "addrbook_test") book = NewAddrBook(fname, true).(*addrBook) book.SetLogger(log.TestingLogger()) diff --git a/p2p/pex/pex_reactor_test.go b/p2p/pex/pex_reactor_test.go index 4ed1254ef..aee18bb11 100644 --- a/p2p/pex/pex_reactor_test.go +++ b/p2p/pex/pex_reactor_test.go @@ -3,8 +3,6 @@ package pex import ( "encoding/hex" "fmt" - "io/ioutil" - "os" "path/filepath" "testing" "time" @@ -31,16 +29,14 @@ func init() { } func TestPEXReactorBasic(t *testing.T) { - r, book := createReactor(&ReactorConfig{}) - defer teardownReactor(book) + r, _ := createReactor(t, &ReactorConfig{}) assert.NotNil(t, r) assert.NotEmpty(t, r.GetChannels()) } func TestPEXReactorAddRemovePeer(t *testing.T) { - r, book := createReactor(&ReactorConfig{}) - defer teardownReactor(book) + r, book := createReactor(t, &ReactorConfig{}) size := book.Size() peer := p2p.CreateRandomPeer(false) @@ -73,9 +69,7 @@ func TestPEXReactorRunning(t *testing.T) { switches := make([]*p2p.Switch, N) // directory to store address books - dir, err := ioutil.TempDir("", "pex_reactor") - require.Nil(t, err) - defer os.RemoveAll(dir) + dir := t.TempDir() books := make([]AddrBook, N) logger := log.TestingLogger() @@ -123,9 +117,7 @@ func TestPEXReactorRunning(t *testing.T) { } func TestPEXReactorReceive(t *testing.T) { - r, book := createReactor(&ReactorConfig{}) - defer teardownReactor(book) - + r, book := createReactor(t, &ReactorConfig{}) peer := p2p.CreateRandomPeer(false) // we have to send a request to receive responses @@ -141,9 +133,7 @@ func TestPEXReactorReceive(t *testing.T) { } func TestPEXReactorRequestMessageAbuse(t *testing.T) { - r, book := createReactor(&ReactorConfig{}) - defer teardownReactor(book) - + r, book := createReactor(t, &ReactorConfig{}) sw := createSwitchAndAddReactors(r) sw.SetAddrBook(book) @@ -176,9 +166,7 @@ func TestPEXReactorRequestMessageAbuse(t *testing.T) { } func TestPEXReactorAddrsMessageAbuse(t *testing.T) { - r, book := createReactor(&ReactorConfig{}) - defer teardownReactor(book) - + r, book := createReactor(t, &ReactorConfig{}) sw := createSwitchAndAddReactors(r) sw.SetAddrBook(book) @@ -208,9 +196,7 @@ func TestPEXReactorAddrsMessageAbuse(t *testing.T) { func TestCheckSeeds(t *testing.T) { // directory to store address books - dir, err := ioutil.TempDir("", "pex_reactor") - require.Nil(t, err) - defer os.RemoveAll(dir) + dir := t.TempDir() // 1. test creating peer with no seeds works peerSwitch := testCreateDefaultPeer(dir, 0) @@ -247,19 +233,17 @@ func TestCheckSeeds(t *testing.T) { func TestPEXReactorUsesSeedsIfNeeded(t *testing.T) { // directory to store address books - dir, err := ioutil.TempDir("", "pex_reactor") - require.Nil(t, err) - defer os.RemoveAll(dir) + dir := t.TempDir() // 1. create seed seed := testCreateSeed(dir, 0, []*p2p.NetAddress{}, []*p2p.NetAddress{}) require.Nil(t, seed.Start()) - defer seed.Stop() // nolint:errcheck // ignore for tests + t.Cleanup(func() { _ = seed.Stop() }) // 2. create usual peer with only seed configured. peer := testCreatePeerWithSeed(dir, 1, seed) require.Nil(t, peer.Start()) - defer peer.Stop() // nolint:errcheck // ignore for tests + t.Cleanup(func() { _ = seed.Stop() }) // 3. check that the peer connects to seed immediately assertPeersWithTimeout(t, []*p2p.Switch{peer}, 10*time.Millisecond, 3*time.Second, 1) @@ -267,25 +251,23 @@ func TestPEXReactorUsesSeedsIfNeeded(t *testing.T) { func TestConnectionSpeedForPeerReceivedFromSeed(t *testing.T) { // directory to store address books - dir, err := ioutil.TempDir("", "pex_reactor") - require.Nil(t, err) - defer os.RemoveAll(dir) + dir := t.TempDir() // 1. create peer peerSwitch := testCreateDefaultPeer(dir, 1) require.Nil(t, peerSwitch.Start()) - defer peerSwitch.Stop() // nolint:errcheck // ignore for tests + t.Cleanup(func() { _ = peerSwitch.Stop() }) // 2. Create seed which knows about the peer peerAddr := peerSwitch.NetAddress() seed := testCreateSeed(dir, 2, []*p2p.NetAddress{peerAddr}, []*p2p.NetAddress{peerAddr}) require.Nil(t, seed.Start()) - defer seed.Stop() // nolint:errcheck // ignore for tests + t.Cleanup(func() { _ = seed.Stop() }) // 3. create another peer with only seed configured. secondPeer := testCreatePeerWithSeed(dir, 3, seed) require.Nil(t, secondPeer.Start()) - defer secondPeer.Stop() // nolint:errcheck // ignore for tests + t.Cleanup(func() { _ = secondPeer.Stop() }) // 4. check that the second peer connects to seed immediately assertPeersWithTimeout(t, []*p2p.Switch{secondPeer}, 10*time.Millisecond, 3*time.Second, 1) @@ -296,25 +278,21 @@ func TestConnectionSpeedForPeerReceivedFromSeed(t *testing.T) { func TestPEXReactorSeedMode(t *testing.T) { // directory to store address books - dir, err := ioutil.TempDir("", "pex_reactor") - require.Nil(t, err) - defer os.RemoveAll(dir) + dir := t.TempDir() pexRConfig := &ReactorConfig{SeedMode: true, SeedDisconnectWaitPeriod: 10 * time.Millisecond} - pexR, book := createReactor(pexRConfig) - defer teardownReactor(book) - + pexR, book := createReactor(t, pexRConfig) sw := createSwitchAndAddReactors(pexR) + sw.SetAddrBook(book) - err = sw.Start() - require.NoError(t, err) - defer sw.Stop() // nolint:errcheck // ignore for tests + require.NoError(t, sw.Start()) + t.Cleanup(func() { _ = sw.Stop() }) assert.Zero(t, sw.Peers().Size()) peerSwitch := testCreateDefaultPeer(dir, 1) require.NoError(t, peerSwitch.Start()) - defer peerSwitch.Stop() // nolint:errcheck // ignore for tests + t.Cleanup(func() { _ = peerSwitch.Stop() }) // 1. Test crawlPeers dials the peer pexR.crawlPeers([]*p2p.NetAddress{peerSwitch.NetAddress()}) @@ -335,28 +313,23 @@ func TestPEXReactorSeedMode(t *testing.T) { func TestPEXReactorDoesNotDisconnectFromPersistentPeerInSeedMode(t *testing.T) { // directory to store address books - dir, err := ioutil.TempDir("", "pex_reactor") - require.Nil(t, err) - defer os.RemoveAll(dir) + dir := t.TempDir() pexRConfig := &ReactorConfig{SeedMode: true, SeedDisconnectWaitPeriod: 1 * time.Millisecond} - pexR, book := createReactor(pexRConfig) - defer teardownReactor(book) - + pexR, book := createReactor(t, pexRConfig) sw := createSwitchAndAddReactors(pexR) + sw.SetAddrBook(book) - err = sw.Start() - require.NoError(t, err) - defer sw.Stop() // nolint:errcheck // ignore for tests + require.NoError(t, sw.Start()) + t.Cleanup(func() { _ = sw.Stop() }) assert.Zero(t, sw.Peers().Size()) peerSwitch := testCreateDefaultPeer(dir, 1) require.NoError(t, peerSwitch.Start()) - defer peerSwitch.Stop() // nolint:errcheck // ignore for tests + t.Cleanup(func() { _ = peerSwitch.Stop() }) - err = sw.AddPersistentPeers([]string{peerSwitch.NetAddress().String()}) - require.NoError(t, err) + require.NoError(t, sw.AddPersistentPeers([]string{peerSwitch.NetAddress().String()})) // 1. Test crawlPeers dials the peer pexR.crawlPeers([]*p2p.NetAddress{peerSwitch.NetAddress()}) @@ -373,22 +346,16 @@ func TestPEXReactorDoesNotDisconnectFromPersistentPeerInSeedMode(t *testing.T) { func TestPEXReactorDialsPeerUpToMaxAttemptsInSeedMode(t *testing.T) { // directory to store address books - dir, err := ioutil.TempDir("", "pex_reactor") - require.Nil(t, err) - defer os.RemoveAll(dir) - - pexR, book := createReactor(&ReactorConfig{SeedMode: true}) - defer teardownReactor(book) - + pexR, book := createReactor(t, &ReactorConfig{SeedMode: true}) sw := createSwitchAndAddReactors(pexR) + sw.SetAddrBook(book) // No need to start sw since crawlPeers is called manually here. peer := mock.NewPeer(nil) addr := peer.SocketAddr() - err = book.AddAddress(addr, addr) - require.NoError(t, err) + require.NoError(t, book.AddAddress(addr, addr)) assert.True(t, book.HasAddress(addr)) @@ -409,9 +376,7 @@ func TestPEXReactorSeedModeFlushStop(t *testing.T) { switches := make([]*p2p.Switch, N) // directory to store address books - dir, err := ioutil.TempDir("", "pex_reactor") - require.Nil(t, err) - defer os.RemoveAll(dir) + dir := t.TempDir() books := make([]AddrBook, N) logger := log.TestingLogger() @@ -447,8 +412,7 @@ func TestPEXReactorSeedModeFlushStop(t *testing.T) { reactor := switches[0].Reactors()["pex"].(*Reactor) peerID := switches[1].NodeInfo().ID() - err = switches[1].DialPeerWithAddress(switches[0].NetAddress()) - assert.NoError(t, err) + assert.NoError(t, switches[1].DialPeerWithAddress(switches[0].NetAddress())) // sleep up to a second while waiting for the peer to send us a message. // this isn't perfect since it's possible the peer sends us a msg and we FlushStop @@ -479,9 +443,8 @@ func TestPEXReactorSeedModeFlushStop(t *testing.T) { func TestPEXReactorDoesNotAddPrivatePeersToAddrBook(t *testing.T) { peer := p2p.CreateRandomPeer(false) - pexR, book := createReactor(&ReactorConfig{}) + pexR, book := createReactor(t, &ReactorConfig{}) book.AddPrivateIDs([]string{string(peer.NodeInfo().ID())}) - defer teardownReactor(book) // we have to send a request to receive responses pexR.RequestAddrs(peer) @@ -496,10 +459,9 @@ func TestPEXReactorDoesNotAddPrivatePeersToAddrBook(t *testing.T) { } func TestPEXReactorDialPeer(t *testing.T) { - pexR, book := createReactor(&ReactorConfig{}) - defer teardownReactor(book) - + pexR, book := createReactor(t, &ReactorConfig{}) sw := createSwitchAndAddReactors(pexR) + sw.SetAddrBook(book) peer := mock.NewPeer(nil) @@ -644,13 +606,9 @@ func testCreatePeerWithSeed(dir string, id int, seed *p2p.Switch) *p2p.Switch { return testCreatePeerWithConfig(dir, id, conf) } -func createReactor(conf *ReactorConfig) (r *Reactor, book AddrBook) { +func createReactor(t *testing.T, conf *ReactorConfig) (r *Reactor, book AddrBook) { // directory to store address book - dir, err := ioutil.TempDir("", "pex_reactor") - if err != nil { - panic(err) - } - book = NewAddrBook(filepath.Join(dir, "addrbook.json"), true) + book = NewAddrBook(filepath.Join(t.TempDir(), "addrbook.json"), true) book.SetLogger(log.TestingLogger()) r = NewReactor(book, conf) @@ -658,14 +616,6 @@ func createReactor(conf *ReactorConfig) (r *Reactor, book AddrBook) { return } -func teardownReactor(book AddrBook) { - // FIXME Shouldn't rely on .(*addrBook) assertion - err := os.RemoveAll(filepath.Dir(book.(*addrBook).FilePath())) - if err != nil { - panic(err) - } -} - func createSwitchAndAddReactors(reactors ...p2p.Reactor) *p2p.Switch { sw := p2p.MakeSwitch(cfg, 0, "127.0.0.1", "123.123.123", func(i int, sw *p2p.Switch) *p2p.Switch { return sw }) sw.SetLogger(log.TestingLogger()) @@ -677,7 +627,6 @@ func createSwitchAndAddReactors(reactors ...p2p.Reactor) *p2p.Switch { } func TestPexVectors(t *testing.T) { - addr := tmp2p.NetAddress{ ID: "1", IP: "127.0.0.1", diff --git a/p2p/trust/store_test.go b/p2p/trust/store_test.go index df0f14a04..ecf17dc4a 100644 --- a/p2p/trust/store_test.go +++ b/p2p/trust/store_test.go @@ -5,8 +5,6 @@ package trust import ( "fmt" - "io/ioutil" - "os" "testing" "github.com/stretchr/testify/assert" @@ -17,9 +15,7 @@ import ( ) func TestTrustMetricStoreSaveLoad(t *testing.T) { - dir, err := ioutil.TempDir("", "trust_test") - require.NoError(t, err) - defer os.Remove(dir) + dir := t.TempDir() historyDB, err := dbm.NewDB("trusthistory", "goleveldb", dir) require.NoError(t, err) From e13b4386ff1a46a5e8879e11bd653b62d4ca0992 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Mon, 30 Nov 2020 16:46:16 +0400 Subject: [PATCH 2/2] abci: modify Client interface and socket client (#5673) `abci.Client`: - Sync and Async methods now accept a context for cancellation * grpc client uses context to cancel both Sync and Async requests * local client ignores context parameter * socket client uses context to cancel Sync requests and to drop Async requests before sending them if context was cancelled prior to that - Async methods return an error * socket client returns an error immediately if queue is full for Async requests * local client always returns nil error * grpc client returns an error if context was cancelled before we got response or the receiving queue had a space for response (do not confuse with the sending queue from the socket client) - specify clients semantics in [doc.go](https://raw.githubusercontent.com/tendermint/tendermint/27112fffa62276bc016d56741f686f0f77931748/abci/client/doc.go) `mempool.TxInfo` - add optional `Context` to `TxInfo`, which can be used to cancel `CheckTx` request Closes #5190 --- CHANGELOG_PENDING.md | 3 + abci/client/client.go | 68 ++-- abci/client/doc.go | 29 ++ abci/client/grpc_client.go | 305 +++++++++------ abci/client/local_client.go | 130 ++++--- abci/client/mocks/client.go | 529 ++++++++++++++++----------- abci/client/socket_client.go | 334 +++++++++++------ abci/client/socket_client_test.go | 22 +- abci/cmd/abci-cli/abci-cli.go | 15 +- abci/example/example_test.go | 31 +- abci/example/kvstore/kvstore_test.go | 15 +- abci/tests/server/client.go | 11 +- abci/tests/test_app/app.go | 7 +- abci/types/application.go | 2 +- consensus/replay.go | 5 +- consensus/replay_test.go | 9 +- mempool/clist_mempool.go | 27 +- mempool/clist_mempool_test.go | 11 +- mempool/mempool.go | 3 + node/node.go | 4 +- proxy/app_conn.go | 111 +++--- proxy/app_conn_test.go | 59 ++- proxy/mocks/app_conn_consensus.go | 80 ++-- proxy/mocks/app_conn_mempool.go | 67 ++-- proxy/mocks/app_conn_query.go | 44 +-- proxy/mocks/app_conn_snapshot.go | 58 +-- rpc/core/abci.go | 4 +- rpc/core/mempool.go | 8 +- rpc/grpc/client_server.go | 2 +- state/execution.go | 27 +- statesync/reactor.go | 5 +- statesync/reactor_test.go | 5 +- statesync/syncer.go | 6 +- statesync/syncer_test.go | 67 ++-- test/maverick/consensus/replay.go | 5 +- test/maverick/node/node.go | 4 +- 36 files changed, 1318 insertions(+), 794 deletions(-) create mode 100644 abci/client/doc.go diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index e202c899b..ef2586f6a 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -16,6 +16,7 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi - P2P Protocol - Go API + - [abci/client, proxy] \#5673 `Async` funcs return an error, `Sync` and `Async` funcs accept `context.Context` (@melekes) - [p2p] Removed unused function `MakePoWTarget`. (@erikgrinaker) - [libs/os] Kill() and {Must,}{Read,Write}File() functions have been removed. (@alessio) @@ -28,6 +29,8 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi - [crypto/ed25519] \#5632 Adopt zip215 `ed25519` verification. (@marbar3778) - [privval] \#5603 Add `--key` to `init`, `gen_validator`, `testnet` & `unsafe_reset_priv_validator` for use in generating `secp256k1` keys. +- [abci/client] \#5673 `Async` requests return an error if queue is full (@melekes) +- [mempool] \#5673 Cancel `CheckTx` requests if RPC client disconnects or times out (@melekes) - [abci] \#5706 Added `AbciVersion` to `RequestInfo` allowing applications to check ABCI version when connecting to Tendermint. (@marbar3778) ### BUG FIXES diff --git a/abci/client/client.go b/abci/client/client.go index ede559fdc..3b55aebae 100644 --- a/abci/client/client.go +++ b/abci/client/client.go @@ -1,6 +1,7 @@ package abcicli import ( + "context" "fmt" "sync" @@ -17,45 +18,50 @@ const ( //go:generate mockery --case underscore --name Client // Client defines an interface for an ABCI client. -// All `Async` methods return a `ReqRes` object. +// +// All `Async` methods return a `ReqRes` object and an error. // All `Sync` methods return the appropriate protobuf ResponseXxx struct and an error. -// Note these are client errors, eg. ABCI socket connectivity issues. -// Application-related errors are reflected in response via ABCI error codes and logs. +// +// NOTE these are client errors, eg. ABCI socket connectivity issues. +// Application-related errors are reflected in response via ABCI error codes +// and logs. type Client interface { service.Service SetResponseCallback(Callback) Error() error - FlushAsync() *ReqRes - EchoAsync(msg string) *ReqRes - InfoAsync(types.RequestInfo) *ReqRes - DeliverTxAsync(types.RequestDeliverTx) *ReqRes - CheckTxAsync(types.RequestCheckTx) *ReqRes - QueryAsync(types.RequestQuery) *ReqRes - CommitAsync() *ReqRes - InitChainAsync(types.RequestInitChain) *ReqRes - BeginBlockAsync(types.RequestBeginBlock) *ReqRes - EndBlockAsync(types.RequestEndBlock) *ReqRes - ListSnapshotsAsync(types.RequestListSnapshots) *ReqRes - OfferSnapshotAsync(types.RequestOfferSnapshot) *ReqRes - LoadSnapshotChunkAsync(types.RequestLoadSnapshotChunk) *ReqRes - ApplySnapshotChunkAsync(types.RequestApplySnapshotChunk) *ReqRes + // Asynchronous requests + FlushAsync(context.Context) (*ReqRes, error) + EchoAsync(ctx context.Context, msg string) (*ReqRes, error) + InfoAsync(context.Context, types.RequestInfo) (*ReqRes, error) + DeliverTxAsync(context.Context, types.RequestDeliverTx) (*ReqRes, error) + CheckTxAsync(context.Context, types.RequestCheckTx) (*ReqRes, error) + QueryAsync(context.Context, types.RequestQuery) (*ReqRes, error) + CommitAsync(context.Context) (*ReqRes, error) + InitChainAsync(context.Context, types.RequestInitChain) (*ReqRes, error) + BeginBlockAsync(context.Context, types.RequestBeginBlock) (*ReqRes, error) + EndBlockAsync(context.Context, types.RequestEndBlock) (*ReqRes, error) + ListSnapshotsAsync(context.Context, types.RequestListSnapshots) (*ReqRes, error) + OfferSnapshotAsync(context.Context, types.RequestOfferSnapshot) (*ReqRes, error) + LoadSnapshotChunkAsync(context.Context, types.RequestLoadSnapshotChunk) (*ReqRes, error) + ApplySnapshotChunkAsync(context.Context, types.RequestApplySnapshotChunk) (*ReqRes, error) - FlushSync() error - EchoSync(msg string) (*types.ResponseEcho, error) - InfoSync(types.RequestInfo) (*types.ResponseInfo, error) - DeliverTxSync(types.RequestDeliverTx) (*types.ResponseDeliverTx, error) - CheckTxSync(types.RequestCheckTx) (*types.ResponseCheckTx, error) - QuerySync(types.RequestQuery) (*types.ResponseQuery, error) - CommitSync() (*types.ResponseCommit, error) - InitChainSync(types.RequestInitChain) (*types.ResponseInitChain, error) - BeginBlockSync(types.RequestBeginBlock) (*types.ResponseBeginBlock, error) - EndBlockSync(types.RequestEndBlock) (*types.ResponseEndBlock, error) - ListSnapshotsSync(types.RequestListSnapshots) (*types.ResponseListSnapshots, error) - OfferSnapshotSync(types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) - LoadSnapshotChunkSync(types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) - ApplySnapshotChunkSync(types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) + // Synchronous requests + FlushSync(context.Context) error + EchoSync(ctx context.Context, msg string) (*types.ResponseEcho, error) + InfoSync(context.Context, types.RequestInfo) (*types.ResponseInfo, error) + DeliverTxSync(context.Context, types.RequestDeliverTx) (*types.ResponseDeliverTx, error) + CheckTxSync(context.Context, types.RequestCheckTx) (*types.ResponseCheckTx, error) + QuerySync(context.Context, types.RequestQuery) (*types.ResponseQuery, error) + CommitSync(context.Context) (*types.ResponseCommit, error) + InitChainSync(context.Context, types.RequestInitChain) (*types.ResponseInitChain, error) + BeginBlockSync(context.Context, types.RequestBeginBlock) (*types.ResponseBeginBlock, error) + EndBlockSync(context.Context, types.RequestEndBlock) (*types.ResponseEndBlock, error) + ListSnapshotsSync(context.Context, types.RequestListSnapshots) (*types.ResponseListSnapshots, error) + OfferSnapshotSync(context.Context, types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) + LoadSnapshotChunkSync(context.Context, types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) + ApplySnapshotChunkSync(context.Context, types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) } //---------------------------------------- diff --git a/abci/client/doc.go b/abci/client/doc.go new file mode 100644 index 000000000..eac40fe11 --- /dev/null +++ b/abci/client/doc.go @@ -0,0 +1,29 @@ +// Package abcicli provides an ABCI implementation in Go. +// +// There are 3 clients available: +// 1. socket (unix or TCP) +// 2. local (in memory) +// 3. gRPC +// +// ## Socket client +// +// async: the client maintains an internal buffer of a fixed size. when the +// buffer becomes full, all Async calls will return an error immediately. +// +// sync: the client blocks on 1) enqueuing the Sync request 2) enqueuing the +// Flush requests 3) waiting for the Flush response +// +// ## Local client +// +// async: global mutex is locked during each call (meaning it's not really async!) +// sync: global mutex is locked during each call +// +// ## gRPC client +// +// async: gRPC is synchronous, but an internal buffer of a fixed size is used +// to store responses and later call callbacks (separate goroutine per +// response). +// +// sync: waits for all Async calls to complete (essentially what Flush does in +// the socket client) and calls Sync method. +package abcicli diff --git a/abci/client/grpc_client.go b/abci/client/grpc_client.go index 98ae9073f..e7c8491eb 100644 --- a/abci/client/grpc_client.go +++ b/abci/client/grpc_client.go @@ -1,12 +1,12 @@ package abcicli import ( + "context" "fmt" "net" "sync" "time" - "golang.org/x/net/context" "google.golang.org/grpc" "github.com/tendermint/tendermint/abci/types" @@ -15,10 +15,7 @@ import ( tmsync "github.com/tendermint/tendermint/libs/sync" ) -var _ Client = (*grpcClient)(nil) - -// A stripped copy of the remoteClient that makes -// synchronous calls using grpc +// A gRPC client. type grpcClient struct { service.BaseService mustConnect bool @@ -33,6 +30,18 @@ type grpcClient struct { resCb func(*types.Request, *types.Response) // listens to all callbacks } +var _ Client = (*grpcClient)(nil) + +// NewGRPCClient creates a gRPC client, which will connect to addr upon the +// start. Note Client#Start returns an error if connection is unsuccessful and +// mustConnect is true. +// +// GRPC calls are synchronous, but some callbacks expect to be called +// asynchronously (eg. the mempool expects to be able to lock to remove bad txs +// from cache). To accommodate, we finish each call in its own go-routine, +// which is expensive, but easy - if you want something better, use the socket +// protocol! maybe one day, if people really want it, we use grpc streams, but +// hopefully not :D func NewGRPCClient(addr string, mustConnect bool) Client { cli := &grpcClient{ addr: addr, @@ -54,10 +63,6 @@ func dialerFunc(ctx context.Context, addr string) (net.Conn, error) { } func (cli *grpcClient) OnStart() error { - if err := cli.BaseService.OnStart(); err != nil { - return err - } - // This processes asynchronous request/response messages and dispatches // them to callbacks. go func() { @@ -120,8 +125,6 @@ RETRY_LOOP: } func (cli *grpcClient) OnStop() { - cli.BaseService.OnStop() - if cli.conn != nil { cli.conn.Close() } @@ -160,146 +163,168 @@ func (cli *grpcClient) SetResponseCallback(resCb Callback) { } //---------------------------------------- -// GRPC calls are synchronous, but some callbacks expect to be called asynchronously -// (eg. the mempool expects to be able to lock to remove bad txs from cache). -// To accommodate, we finish each call in its own go-routine, -// which is expensive, but easy - if you want something better, use the socket protocol! -// maybe one day, if people really want it, we use grpc streams, -// but hopefully not :D -func (cli *grpcClient) EchoAsync(msg string) *ReqRes { +// NOTE: call is synchronous, use ctx to break early if needed +func (cli *grpcClient) EchoAsync(ctx context.Context, msg string) (*ReqRes, error) { req := types.ToRequestEcho(msg) - res, err := cli.client.Echo(context.Background(), req.GetEcho(), grpc.WaitForReady(true)) + res, err := cli.client.Echo(ctx, req.GetEcho(), grpc.WaitForReady(true)) if err != nil { - cli.StopForError(err) + return nil, err } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_Echo{Echo: res}}) + return cli.finishAsyncCall(ctx, req, &types.Response{Value: &types.Response_Echo{Echo: res}}) } -func (cli *grpcClient) FlushAsync() *ReqRes { +// NOTE: call is synchronous, use ctx to break early if needed +func (cli *grpcClient) FlushAsync(ctx context.Context) (*ReqRes, error) { req := types.ToRequestFlush() - res, err := cli.client.Flush(context.Background(), req.GetFlush(), grpc.WaitForReady(true)) + res, err := cli.client.Flush(ctx, req.GetFlush(), grpc.WaitForReady(true)) if err != nil { - cli.StopForError(err) + return nil, err } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_Flush{Flush: res}}) + return cli.finishAsyncCall(ctx, req, &types.Response{Value: &types.Response_Flush{Flush: res}}) } -func (cli *grpcClient) InfoAsync(params types.RequestInfo) *ReqRes { +// NOTE: call is synchronous, use ctx to break early if needed +func (cli *grpcClient) InfoAsync(ctx context.Context, params types.RequestInfo) (*ReqRes, error) { req := types.ToRequestInfo(params) - res, err := cli.client.Info(context.Background(), req.GetInfo(), grpc.WaitForReady(true)) + res, err := cli.client.Info(ctx, req.GetInfo(), grpc.WaitForReady(true)) if err != nil { - cli.StopForError(err) + return nil, err } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_Info{Info: res}}) + return cli.finishAsyncCall(ctx, req, &types.Response{Value: &types.Response_Info{Info: res}}) } -func (cli *grpcClient) DeliverTxAsync(params types.RequestDeliverTx) *ReqRes { +// NOTE: call is synchronous, use ctx to break early if needed +func (cli *grpcClient) DeliverTxAsync(ctx context.Context, params types.RequestDeliverTx) (*ReqRes, error) { req := types.ToRequestDeliverTx(params) - res, err := cli.client.DeliverTx(context.Background(), req.GetDeliverTx(), grpc.WaitForReady(true)) + res, err := cli.client.DeliverTx(ctx, req.GetDeliverTx(), grpc.WaitForReady(true)) if err != nil { - cli.StopForError(err) + return nil, err } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_DeliverTx{DeliverTx: res}}) + return cli.finishAsyncCall(ctx, req, &types.Response{Value: &types.Response_DeliverTx{DeliverTx: res}}) } -func (cli *grpcClient) CheckTxAsync(params types.RequestCheckTx) *ReqRes { +// NOTE: call is synchronous, use ctx to break early if needed +func (cli *grpcClient) CheckTxAsync(ctx context.Context, params types.RequestCheckTx) (*ReqRes, error) { req := types.ToRequestCheckTx(params) - res, err := cli.client.CheckTx(context.Background(), req.GetCheckTx(), grpc.WaitForReady(true)) + res, err := cli.client.CheckTx(ctx, req.GetCheckTx(), grpc.WaitForReady(true)) if err != nil { - cli.StopForError(err) + return nil, err } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_CheckTx{CheckTx: res}}) + return cli.finishAsyncCall(ctx, req, &types.Response{Value: &types.Response_CheckTx{CheckTx: res}}) } -func (cli *grpcClient) QueryAsync(params types.RequestQuery) *ReqRes { +// NOTE: call is synchronous, use ctx to break early if needed +func (cli *grpcClient) QueryAsync(ctx context.Context, params types.RequestQuery) (*ReqRes, error) { req := types.ToRequestQuery(params) - res, err := cli.client.Query(context.Background(), req.GetQuery(), grpc.WaitForReady(true)) + res, err := cli.client.Query(ctx, req.GetQuery(), grpc.WaitForReady(true)) if err != nil { - cli.StopForError(err) + return nil, err } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_Query{Query: res}}) + return cli.finishAsyncCall(ctx, req, &types.Response{Value: &types.Response_Query{Query: res}}) } -func (cli *grpcClient) CommitAsync() *ReqRes { +// NOTE: call is synchronous, use ctx to break early if needed +func (cli *grpcClient) CommitAsync(ctx context.Context) (*ReqRes, error) { req := types.ToRequestCommit() - res, err := cli.client.Commit(context.Background(), req.GetCommit(), grpc.WaitForReady(true)) + res, err := cli.client.Commit(ctx, req.GetCommit(), grpc.WaitForReady(true)) if err != nil { - cli.StopForError(err) + return nil, err } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_Commit{Commit: res}}) + return cli.finishAsyncCall(ctx, req, &types.Response{Value: &types.Response_Commit{Commit: res}}) } -func (cli *grpcClient) InitChainAsync(params types.RequestInitChain) *ReqRes { +// NOTE: call is synchronous, use ctx to break early if needed +func (cli *grpcClient) InitChainAsync(ctx context.Context, params types.RequestInitChain) (*ReqRes, error) { req := types.ToRequestInitChain(params) - res, err := cli.client.InitChain(context.Background(), req.GetInitChain(), grpc.WaitForReady(true)) + res, err := cli.client.InitChain(ctx, req.GetInitChain(), grpc.WaitForReady(true)) if err != nil { - cli.StopForError(err) + return nil, err } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_InitChain{InitChain: res}}) + return cli.finishAsyncCall(ctx, req, &types.Response{Value: &types.Response_InitChain{InitChain: res}}) } -func (cli *grpcClient) BeginBlockAsync(params types.RequestBeginBlock) *ReqRes { +// NOTE: call is synchronous, use ctx to break early if needed +func (cli *grpcClient) BeginBlockAsync(ctx context.Context, params types.RequestBeginBlock) (*ReqRes, error) { req := types.ToRequestBeginBlock(params) - res, err := cli.client.BeginBlock(context.Background(), req.GetBeginBlock(), grpc.WaitForReady(true)) + res, err := cli.client.BeginBlock(ctx, req.GetBeginBlock(), grpc.WaitForReady(true)) if err != nil { - cli.StopForError(err) + return nil, err } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_BeginBlock{BeginBlock: res}}) + return cli.finishAsyncCall(ctx, req, &types.Response{Value: &types.Response_BeginBlock{BeginBlock: res}}) } -func (cli *grpcClient) EndBlockAsync(params types.RequestEndBlock) *ReqRes { +// NOTE: call is synchronous, use ctx to break early if needed +func (cli *grpcClient) EndBlockAsync(ctx context.Context, params types.RequestEndBlock) (*ReqRes, error) { req := types.ToRequestEndBlock(params) - res, err := cli.client.EndBlock(context.Background(), req.GetEndBlock(), grpc.WaitForReady(true)) + res, err := cli.client.EndBlock(ctx, req.GetEndBlock(), grpc.WaitForReady(true)) if err != nil { - cli.StopForError(err) + return nil, err } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_EndBlock{EndBlock: res}}) + return cli.finishAsyncCall(ctx, req, &types.Response{Value: &types.Response_EndBlock{EndBlock: res}}) } -func (cli *grpcClient) ListSnapshotsAsync(params types.RequestListSnapshots) *ReqRes { +// NOTE: call is synchronous, use ctx to break early if needed +func (cli *grpcClient) ListSnapshotsAsync(ctx context.Context, params types.RequestListSnapshots) (*ReqRes, error) { req := types.ToRequestListSnapshots(params) - res, err := cli.client.ListSnapshots(context.Background(), req.GetListSnapshots(), grpc.WaitForReady(true)) + res, err := cli.client.ListSnapshots(ctx, req.GetListSnapshots(), grpc.WaitForReady(true)) if err != nil { - cli.StopForError(err) + return nil, err } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_ListSnapshots{ListSnapshots: res}}) + return cli.finishAsyncCall(ctx, req, &types.Response{Value: &types.Response_ListSnapshots{ListSnapshots: res}}) } -func (cli *grpcClient) OfferSnapshotAsync(params types.RequestOfferSnapshot) *ReqRes { +// NOTE: call is synchronous, use ctx to break early if needed +func (cli *grpcClient) OfferSnapshotAsync(ctx context.Context, params types.RequestOfferSnapshot) (*ReqRes, error) { req := types.ToRequestOfferSnapshot(params) - res, err := cli.client.OfferSnapshot(context.Background(), req.GetOfferSnapshot(), grpc.WaitForReady(true)) + res, err := cli.client.OfferSnapshot(ctx, req.GetOfferSnapshot(), grpc.WaitForReady(true)) if err != nil { - cli.StopForError(err) + return nil, err } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_OfferSnapshot{OfferSnapshot: res}}) + return cli.finishAsyncCall(ctx, req, &types.Response{Value: &types.Response_OfferSnapshot{OfferSnapshot: res}}) } -func (cli *grpcClient) LoadSnapshotChunkAsync(params types.RequestLoadSnapshotChunk) *ReqRes { +// NOTE: call is synchronous, use ctx to break early if needed +func (cli *grpcClient) LoadSnapshotChunkAsync( + ctx context.Context, + params types.RequestLoadSnapshotChunk, +) (*ReqRes, error) { req := types.ToRequestLoadSnapshotChunk(params) - res, err := cli.client.LoadSnapshotChunk(context.Background(), req.GetLoadSnapshotChunk(), grpc.WaitForReady(true)) + res, err := cli.client.LoadSnapshotChunk(ctx, req.GetLoadSnapshotChunk(), grpc.WaitForReady(true)) if err != nil { - cli.StopForError(err) + return nil, err } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_LoadSnapshotChunk{LoadSnapshotChunk: res}}) + return cli.finishAsyncCall(ctx, req, &types.Response{Value: &types.Response_LoadSnapshotChunk{LoadSnapshotChunk: res}}) } -func (cli *grpcClient) ApplySnapshotChunkAsync(params types.RequestApplySnapshotChunk) *ReqRes { +// NOTE: call is synchronous, use ctx to break early if needed +func (cli *grpcClient) ApplySnapshotChunkAsync( + ctx context.Context, + params types.RequestApplySnapshotChunk, +) (*ReqRes, error) { req := types.ToRequestApplySnapshotChunk(params) - res, err := cli.client.ApplySnapshotChunk(context.Background(), req.GetApplySnapshotChunk(), grpc.WaitForReady(true)) + res, err := cli.client.ApplySnapshotChunk(ctx, req.GetApplySnapshotChunk(), grpc.WaitForReady(true)) if err != nil { - cli.StopForError(err) + return nil, err } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_ApplySnapshotChunk{ApplySnapshotChunk: res}}) + return cli.finishAsyncCall( + ctx, + req, + &types.Response{Value: &types.Response_ApplySnapshotChunk{ApplySnapshotChunk: res}}, + ) } // finishAsyncCall creates a ReqRes for an async call, and immediately populates it // with the response. We don't complete it until it's been ordered via the channel. -func (cli *grpcClient) finishAsyncCall(req *types.Request, res *types.Response) *ReqRes { +func (cli *grpcClient) finishAsyncCall(ctx context.Context, req *types.Request, res *types.Response) (*ReqRes, error) { reqres := NewReqRes(req) reqres.Response = res - cli.chReqRes <- reqres // use channel for async responses, since they must be ordered - return reqres + select { + case cli.chReqRes <- reqres: // use channel for async responses, since they must be ordered + return reqres, nil + case <-ctx.Done(): + return nil, ctx.Err() + } } // finishSyncCall waits for an async call to complete. It is necessary to call all @@ -332,74 +357,150 @@ func (cli *grpcClient) finishSyncCall(reqres *ReqRes) *types.Response { //---------------------------------------- -func (cli *grpcClient) FlushSync() error { +func (cli *grpcClient) FlushSync(ctx context.Context) error { return nil } -func (cli *grpcClient) EchoSync(msg string) (*types.ResponseEcho, error) { - reqres := cli.EchoAsync(msg) - // StopForError should already have been called if error is set +func (cli *grpcClient) EchoSync(ctx context.Context, msg string) (*types.ResponseEcho, error) { + reqres, err := cli.EchoAsync(ctx, msg) + if err != nil { + return nil, err + } return cli.finishSyncCall(reqres).GetEcho(), cli.Error() } -func (cli *grpcClient) InfoSync(req types.RequestInfo) (*types.ResponseInfo, error) { - reqres := cli.InfoAsync(req) +func (cli *grpcClient) InfoSync( + ctx context.Context, + req types.RequestInfo, +) (*types.ResponseInfo, error) { + reqres, err := cli.InfoAsync(ctx, req) + if err != nil { + return nil, err + } return cli.finishSyncCall(reqres).GetInfo(), cli.Error() } -func (cli *grpcClient) DeliverTxSync(params types.RequestDeliverTx) (*types.ResponseDeliverTx, error) { - reqres := cli.DeliverTxAsync(params) +func (cli *grpcClient) DeliverTxSync( + ctx context.Context, + params types.RequestDeliverTx, +) (*types.ResponseDeliverTx, error) { + + reqres, err := cli.DeliverTxAsync(ctx, params) + if err != nil { + return nil, err + } return cli.finishSyncCall(reqres).GetDeliverTx(), cli.Error() } -func (cli *grpcClient) CheckTxSync(params types.RequestCheckTx) (*types.ResponseCheckTx, error) { - reqres := cli.CheckTxAsync(params) +func (cli *grpcClient) CheckTxSync( + ctx context.Context, + params types.RequestCheckTx, +) (*types.ResponseCheckTx, error) { + + reqres, err := cli.CheckTxAsync(ctx, params) + if err != nil { + return nil, err + } return cli.finishSyncCall(reqres).GetCheckTx(), cli.Error() } -func (cli *grpcClient) QuerySync(req types.RequestQuery) (*types.ResponseQuery, error) { - reqres := cli.QueryAsync(req) +func (cli *grpcClient) QuerySync( + ctx context.Context, + req types.RequestQuery, +) (*types.ResponseQuery, error) { + reqres, err := cli.QueryAsync(ctx, req) + if err != nil { + return nil, err + } return cli.finishSyncCall(reqres).GetQuery(), cli.Error() } -func (cli *grpcClient) CommitSync() (*types.ResponseCommit, error) { - reqres := cli.CommitAsync() +func (cli *grpcClient) CommitSync(ctx context.Context) (*types.ResponseCommit, error) { + reqres, err := cli.CommitAsync(ctx) + if err != nil { + return nil, err + } return cli.finishSyncCall(reqres).GetCommit(), cli.Error() } -func (cli *grpcClient) InitChainSync(params types.RequestInitChain) (*types.ResponseInitChain, error) { - reqres := cli.InitChainAsync(params) +func (cli *grpcClient) InitChainSync( + ctx context.Context, + params types.RequestInitChain, +) (*types.ResponseInitChain, error) { + + reqres, err := cli.InitChainAsync(ctx, params) + if err != nil { + return nil, err + } return cli.finishSyncCall(reqres).GetInitChain(), cli.Error() } -func (cli *grpcClient) BeginBlockSync(params types.RequestBeginBlock) (*types.ResponseBeginBlock, error) { - reqres := cli.BeginBlockAsync(params) +func (cli *grpcClient) BeginBlockSync( + ctx context.Context, + params types.RequestBeginBlock, +) (*types.ResponseBeginBlock, error) { + + reqres, err := cli.BeginBlockAsync(ctx, params) + if err != nil { + return nil, err + } return cli.finishSyncCall(reqres).GetBeginBlock(), cli.Error() } -func (cli *grpcClient) EndBlockSync(params types.RequestEndBlock) (*types.ResponseEndBlock, error) { - reqres := cli.EndBlockAsync(params) +func (cli *grpcClient) EndBlockSync( + ctx context.Context, + params types.RequestEndBlock, +) (*types.ResponseEndBlock, error) { + + reqres, err := cli.EndBlockAsync(ctx, params) + if err != nil { + return nil, err + } return cli.finishSyncCall(reqres).GetEndBlock(), cli.Error() } -func (cli *grpcClient) ListSnapshotsSync(params types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { - reqres := cli.ListSnapshotsAsync(params) +func (cli *grpcClient) ListSnapshotsSync( + ctx context.Context, + params types.RequestListSnapshots, +) (*types.ResponseListSnapshots, error) { + + reqres, err := cli.ListSnapshotsAsync(ctx, params) + if err != nil { + return nil, err + } return cli.finishSyncCall(reqres).GetListSnapshots(), cli.Error() } -func (cli *grpcClient) OfferSnapshotSync(params types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { - reqres := cli.OfferSnapshotAsync(params) +func (cli *grpcClient) OfferSnapshotSync( + ctx context.Context, + params types.RequestOfferSnapshot, +) (*types.ResponseOfferSnapshot, error) { + + reqres, err := cli.OfferSnapshotAsync(ctx, params) + if err != nil { + return nil, err + } return cli.finishSyncCall(reqres).GetOfferSnapshot(), cli.Error() } func (cli *grpcClient) LoadSnapshotChunkSync( + ctx context.Context, params types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { - reqres := cli.LoadSnapshotChunkAsync(params) + + reqres, err := cli.LoadSnapshotChunkAsync(ctx, params) + if err != nil { + return nil, err + } return cli.finishSyncCall(reqres).GetLoadSnapshotChunk(), cli.Error() } func (cli *grpcClient) ApplySnapshotChunkSync( + ctx context.Context, params types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { - reqres := cli.ApplySnapshotChunkAsync(params) + + reqres, err := cli.ApplySnapshotChunkAsync(ctx, params) + if err != nil { + return nil, err + } return cli.finishSyncCall(reqres).GetApplySnapshotChunk(), cli.Error() } diff --git a/abci/client/local_client.go b/abci/client/local_client.go index 293d5f549..92ca0804f 100644 --- a/abci/client/local_client.go +++ b/abci/client/local_client.go @@ -1,13 +1,13 @@ package abcicli import ( + "context" + types "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/libs/service" tmsync "github.com/tendermint/tendermint/libs/sync" ) -var _ Client = (*localClient)(nil) - // NOTE: use defer to unlock mutex because Application might panic (e.g., in // case of malicious tx or query). It only makes sense for publicly exposed // methods like CheckTx (/broadcast_tx_* RPC endpoint) or Query (/abci_query @@ -20,6 +20,12 @@ type localClient struct { Callback } +var _ Client = (*localClient)(nil) + +// NewLocalClient creates a local client, which will be directly calling the +// methods of the given app. +// +// Both Async and Sync methods ignore the given context.Context parameter. func NewLocalClient(mtx *tmsync.Mutex, app types.Application) Client { if mtx == nil { mtx = new(tmsync.Mutex) @@ -43,22 +49,22 @@ func (app *localClient) Error() error { return nil } -func (app *localClient) FlushAsync() *ReqRes { +func (app *localClient) FlushAsync(ctx context.Context) (*ReqRes, error) { // Do nothing - return newLocalReqRes(types.ToRequestFlush(), nil) + return newLocalReqRes(types.ToRequestFlush(), nil), nil } -func (app *localClient) EchoAsync(msg string) *ReqRes { +func (app *localClient) EchoAsync(ctx context.Context, msg string) (*ReqRes, error) { app.mtx.Lock() defer app.mtx.Unlock() return app.callback( types.ToRequestEcho(msg), types.ToResponseEcho(msg), - ) + ), nil } -func (app *localClient) InfoAsync(req types.RequestInfo) *ReqRes { +func (app *localClient) InfoAsync(ctx context.Context, req types.RequestInfo) (*ReqRes, error) { app.mtx.Lock() defer app.mtx.Unlock() @@ -66,10 +72,10 @@ func (app *localClient) InfoAsync(req types.RequestInfo) *ReqRes { return app.callback( types.ToRequestInfo(req), types.ToResponseInfo(res), - ) + ), nil } -func (app *localClient) DeliverTxAsync(params types.RequestDeliverTx) *ReqRes { +func (app *localClient) DeliverTxAsync(ctx context.Context, params types.RequestDeliverTx) (*ReqRes, error) { app.mtx.Lock() defer app.mtx.Unlock() @@ -77,10 +83,10 @@ func (app *localClient) DeliverTxAsync(params types.RequestDeliverTx) *ReqRes { return app.callback( types.ToRequestDeliverTx(params), types.ToResponseDeliverTx(res), - ) + ), nil } -func (app *localClient) CheckTxAsync(req types.RequestCheckTx) *ReqRes { +func (app *localClient) CheckTxAsync(ctx context.Context, req types.RequestCheckTx) (*ReqRes, error) { app.mtx.Lock() defer app.mtx.Unlock() @@ -88,10 +94,10 @@ func (app *localClient) CheckTxAsync(req types.RequestCheckTx) *ReqRes { return app.callback( types.ToRequestCheckTx(req), types.ToResponseCheckTx(res), - ) + ), nil } -func (app *localClient) QueryAsync(req types.RequestQuery) *ReqRes { +func (app *localClient) QueryAsync(ctx context.Context, req types.RequestQuery) (*ReqRes, error) { app.mtx.Lock() defer app.mtx.Unlock() @@ -99,10 +105,10 @@ func (app *localClient) QueryAsync(req types.RequestQuery) *ReqRes { return app.callback( types.ToRequestQuery(req), types.ToResponseQuery(res), - ) + ), nil } -func (app *localClient) CommitAsync() *ReqRes { +func (app *localClient) CommitAsync(ctx context.Context) (*ReqRes, error) { app.mtx.Lock() defer app.mtx.Unlock() @@ -110,10 +116,10 @@ func (app *localClient) CommitAsync() *ReqRes { return app.callback( types.ToRequestCommit(), types.ToResponseCommit(res), - ) + ), nil } -func (app *localClient) InitChainAsync(req types.RequestInitChain) *ReqRes { +func (app *localClient) InitChainAsync(ctx context.Context, req types.RequestInitChain) (*ReqRes, error) { app.mtx.Lock() defer app.mtx.Unlock() @@ -121,10 +127,10 @@ func (app *localClient) InitChainAsync(req types.RequestInitChain) *ReqRes { return app.callback( types.ToRequestInitChain(req), types.ToResponseInitChain(res), - ) + ), nil } -func (app *localClient) BeginBlockAsync(req types.RequestBeginBlock) *ReqRes { +func (app *localClient) BeginBlockAsync(ctx context.Context, req types.RequestBeginBlock) (*ReqRes, error) { app.mtx.Lock() defer app.mtx.Unlock() @@ -132,10 +138,10 @@ func (app *localClient) BeginBlockAsync(req types.RequestBeginBlock) *ReqRes { return app.callback( types.ToRequestBeginBlock(req), types.ToResponseBeginBlock(res), - ) + ), nil } -func (app *localClient) EndBlockAsync(req types.RequestEndBlock) *ReqRes { +func (app *localClient) EndBlockAsync(ctx context.Context, req types.RequestEndBlock) (*ReqRes, error) { app.mtx.Lock() defer app.mtx.Unlock() @@ -143,10 +149,10 @@ func (app *localClient) EndBlockAsync(req types.RequestEndBlock) *ReqRes { return app.callback( types.ToRequestEndBlock(req), types.ToResponseEndBlock(res), - ) + ), nil } -func (app *localClient) ListSnapshotsAsync(req types.RequestListSnapshots) *ReqRes { +func (app *localClient) ListSnapshotsAsync(ctx context.Context, req types.RequestListSnapshots) (*ReqRes, error) { app.mtx.Lock() defer app.mtx.Unlock() @@ -154,10 +160,10 @@ func (app *localClient) ListSnapshotsAsync(req types.RequestListSnapshots) *ReqR return app.callback( types.ToRequestListSnapshots(req), types.ToResponseListSnapshots(res), - ) + ), nil } -func (app *localClient) OfferSnapshotAsync(req types.RequestOfferSnapshot) *ReqRes { +func (app *localClient) OfferSnapshotAsync(ctx context.Context, req types.RequestOfferSnapshot) (*ReqRes, error) { app.mtx.Lock() defer app.mtx.Unlock() @@ -165,10 +171,13 @@ func (app *localClient) OfferSnapshotAsync(req types.RequestOfferSnapshot) *ReqR return app.callback( types.ToRequestOfferSnapshot(req), types.ToResponseOfferSnapshot(res), - ) + ), nil } -func (app *localClient) LoadSnapshotChunkAsync(req types.RequestLoadSnapshotChunk) *ReqRes { +func (app *localClient) LoadSnapshotChunkAsync( + ctx context.Context, + req types.RequestLoadSnapshotChunk, +) (*ReqRes, error) { app.mtx.Lock() defer app.mtx.Unlock() @@ -176,10 +185,13 @@ func (app *localClient) LoadSnapshotChunkAsync(req types.RequestLoadSnapshotChun return app.callback( types.ToRequestLoadSnapshotChunk(req), types.ToResponseLoadSnapshotChunk(res), - ) + ), nil } -func (app *localClient) ApplySnapshotChunkAsync(req types.RequestApplySnapshotChunk) *ReqRes { +func (app *localClient) ApplySnapshotChunkAsync( + ctx context.Context, + req types.RequestApplySnapshotChunk, +) (*ReqRes, error) { app.mtx.Lock() defer app.mtx.Unlock() @@ -187,20 +199,20 @@ func (app *localClient) ApplySnapshotChunkAsync(req types.RequestApplySnapshotCh return app.callback( types.ToRequestApplySnapshotChunk(req), types.ToResponseApplySnapshotChunk(res), - ) + ), nil } //------------------------------------------------------- -func (app *localClient) FlushSync() error { +func (app *localClient) FlushSync(ctx context.Context) error { return nil } -func (app *localClient) EchoSync(msg string) (*types.ResponseEcho, error) { +func (app *localClient) EchoSync(ctx context.Context, msg string) (*types.ResponseEcho, error) { return &types.ResponseEcho{Message: msg}, nil } -func (app *localClient) InfoSync(req types.RequestInfo) (*types.ResponseInfo, error) { +func (app *localClient) InfoSync(ctx context.Context, req types.RequestInfo) (*types.ResponseInfo, error) { app.mtx.Lock() defer app.mtx.Unlock() @@ -208,7 +220,11 @@ func (app *localClient) InfoSync(req types.RequestInfo) (*types.ResponseInfo, er return &res, nil } -func (app *localClient) DeliverTxSync(req types.RequestDeliverTx) (*types.ResponseDeliverTx, error) { +func (app *localClient) DeliverTxSync( + ctx context.Context, + req types.RequestDeliverTx, +) (*types.ResponseDeliverTx, error) { + app.mtx.Lock() defer app.mtx.Unlock() @@ -216,7 +232,10 @@ func (app *localClient) DeliverTxSync(req types.RequestDeliverTx) (*types.Respon return &res, nil } -func (app *localClient) CheckTxSync(req types.RequestCheckTx) (*types.ResponseCheckTx, error) { +func (app *localClient) CheckTxSync( + ctx context.Context, + req types.RequestCheckTx, +) (*types.ResponseCheckTx, error) { app.mtx.Lock() defer app.mtx.Unlock() @@ -224,7 +243,10 @@ func (app *localClient) CheckTxSync(req types.RequestCheckTx) (*types.ResponseCh return &res, nil } -func (app *localClient) QuerySync(req types.RequestQuery) (*types.ResponseQuery, error) { +func (app *localClient) QuerySync( + ctx context.Context, + req types.RequestQuery, +) (*types.ResponseQuery, error) { app.mtx.Lock() defer app.mtx.Unlock() @@ -232,7 +254,7 @@ func (app *localClient) QuerySync(req types.RequestQuery) (*types.ResponseQuery, return &res, nil } -func (app *localClient) CommitSync() (*types.ResponseCommit, error) { +func (app *localClient) CommitSync(ctx context.Context) (*types.ResponseCommit, error) { app.mtx.Lock() defer app.mtx.Unlock() @@ -240,7 +262,11 @@ func (app *localClient) CommitSync() (*types.ResponseCommit, error) { return &res, nil } -func (app *localClient) InitChainSync(req types.RequestInitChain) (*types.ResponseInitChain, error) { +func (app *localClient) InitChainSync( + ctx context.Context, + req types.RequestInitChain, +) (*types.ResponseInitChain, error) { + app.mtx.Lock() defer app.mtx.Unlock() @@ -248,7 +274,11 @@ func (app *localClient) InitChainSync(req types.RequestInitChain) (*types.Respon return &res, nil } -func (app *localClient) BeginBlockSync(req types.RequestBeginBlock) (*types.ResponseBeginBlock, error) { +func (app *localClient) BeginBlockSync( + ctx context.Context, + req types.RequestBeginBlock, +) (*types.ResponseBeginBlock, error) { + app.mtx.Lock() defer app.mtx.Unlock() @@ -256,7 +286,11 @@ func (app *localClient) BeginBlockSync(req types.RequestBeginBlock) (*types.Resp return &res, nil } -func (app *localClient) EndBlockSync(req types.RequestEndBlock) (*types.ResponseEndBlock, error) { +func (app *localClient) EndBlockSync( + ctx context.Context, + req types.RequestEndBlock, +) (*types.ResponseEndBlock, error) { + app.mtx.Lock() defer app.mtx.Unlock() @@ -264,7 +298,11 @@ func (app *localClient) EndBlockSync(req types.RequestEndBlock) (*types.Response return &res, nil } -func (app *localClient) ListSnapshotsSync(req types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { +func (app *localClient) ListSnapshotsSync( + ctx context.Context, + req types.RequestListSnapshots, +) (*types.ResponseListSnapshots, error) { + app.mtx.Lock() defer app.mtx.Unlock() @@ -272,7 +310,11 @@ func (app *localClient) ListSnapshotsSync(req types.RequestListSnapshots) (*type return &res, nil } -func (app *localClient) OfferSnapshotSync(req types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { +func (app *localClient) OfferSnapshotSync( + ctx context.Context, + req types.RequestOfferSnapshot, +) (*types.ResponseOfferSnapshot, error) { + app.mtx.Lock() defer app.mtx.Unlock() @@ -281,7 +323,9 @@ func (app *localClient) OfferSnapshotSync(req types.RequestOfferSnapshot) (*type } func (app *localClient) LoadSnapshotChunkSync( + ctx context.Context, req types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { + app.mtx.Lock() defer app.mtx.Unlock() @@ -290,7 +334,9 @@ func (app *localClient) LoadSnapshotChunkSync( } func (app *localClient) ApplySnapshotChunkSync( + ctx context.Context, req types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { + app.mtx.Lock() defer app.mtx.Unlock() diff --git a/abci/client/mocks/client.go b/abci/client/mocks/client.go index 2ff84183c..207d2d444 100644 --- a/abci/client/mocks/client.go +++ b/abci/client/mocks/client.go @@ -3,7 +3,10 @@ package mocks import ( + context "context" + abcicli "github.com/tendermint/tendermint/abci/client" + log "github.com/tendermint/tendermint/libs/log" mock "github.com/stretchr/testify/mock" @@ -16,29 +19,36 @@ type Client struct { mock.Mock } -// ApplySnapshotChunkAsync provides a mock function with given fields: _a0 -func (_m *Client) ApplySnapshotChunkAsync(_a0 types.RequestApplySnapshotChunk) *abcicli.ReqRes { - ret := _m.Called(_a0) +// ApplySnapshotChunkAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) ApplySnapshotChunkAsync(_a0 context.Context, _a1 types.RequestApplySnapshotChunk) (*abcicli.ReqRes, error) { + ret := _m.Called(_a0, _a1) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestApplySnapshotChunk) *abcicli.ReqRes); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestApplySnapshotChunk) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestApplySnapshotChunk) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// ApplySnapshotChunkSync provides a mock function with given fields: _a0 -func (_m *Client) ApplySnapshotChunkSync(_a0 types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { - ret := _m.Called(_a0) +// ApplySnapshotChunkSync provides a mock function with given fields: _a0, _a1 +func (_m *Client) ApplySnapshotChunkSync(_a0 context.Context, _a1 types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponseApplySnapshotChunk - if rf, ok := ret.Get(0).(func(types.RequestApplySnapshotChunk) *types.ResponseApplySnapshotChunk); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestApplySnapshotChunk) *types.ResponseApplySnapshotChunk); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseApplySnapshotChunk) @@ -46,8 +56,8 @@ func (_m *Client) ApplySnapshotChunkSync(_a0 types.RequestApplySnapshotChunk) (* } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestApplySnapshotChunk) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, types.RequestApplySnapshotChunk) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -55,29 +65,36 @@ func (_m *Client) ApplySnapshotChunkSync(_a0 types.RequestApplySnapshotChunk) (* return r0, r1 } -// BeginBlockAsync provides a mock function with given fields: _a0 -func (_m *Client) BeginBlockAsync(_a0 types.RequestBeginBlock) *abcicli.ReqRes { - ret := _m.Called(_a0) +// BeginBlockAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) BeginBlockAsync(_a0 context.Context, _a1 types.RequestBeginBlock) (*abcicli.ReqRes, error) { + ret := _m.Called(_a0, _a1) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestBeginBlock) *abcicli.ReqRes); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestBeginBlock) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestBeginBlock) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// BeginBlockSync provides a mock function with given fields: _a0 -func (_m *Client) BeginBlockSync(_a0 types.RequestBeginBlock) (*types.ResponseBeginBlock, error) { - ret := _m.Called(_a0) +// BeginBlockSync provides a mock function with given fields: _a0, _a1 +func (_m *Client) BeginBlockSync(_a0 context.Context, _a1 types.RequestBeginBlock) (*types.ResponseBeginBlock, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponseBeginBlock - if rf, ok := ret.Get(0).(func(types.RequestBeginBlock) *types.ResponseBeginBlock); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestBeginBlock) *types.ResponseBeginBlock); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseBeginBlock) @@ -85,8 +102,8 @@ func (_m *Client) BeginBlockSync(_a0 types.RequestBeginBlock) (*types.ResponseBe } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestBeginBlock) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, types.RequestBeginBlock) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -94,29 +111,36 @@ func (_m *Client) BeginBlockSync(_a0 types.RequestBeginBlock) (*types.ResponseBe return r0, r1 } -// CheckTxAsync provides a mock function with given fields: _a0 -func (_m *Client) CheckTxAsync(_a0 types.RequestCheckTx) *abcicli.ReqRes { - ret := _m.Called(_a0) +// CheckTxAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) CheckTxAsync(_a0 context.Context, _a1 types.RequestCheckTx) (*abcicli.ReqRes, error) { + ret := _m.Called(_a0, _a1) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestCheckTx) *abcicli.ReqRes); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestCheckTx) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestCheckTx) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// CheckTxSync provides a mock function with given fields: _a0 -func (_m *Client) CheckTxSync(_a0 types.RequestCheckTx) (*types.ResponseCheckTx, error) { - ret := _m.Called(_a0) +// CheckTxSync provides a mock function with given fields: _a0, _a1 +func (_m *Client) CheckTxSync(_a0 context.Context, _a1 types.RequestCheckTx) (*types.ResponseCheckTx, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponseCheckTx - if rf, ok := ret.Get(0).(func(types.RequestCheckTx) *types.ResponseCheckTx); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestCheckTx) *types.ResponseCheckTx); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseCheckTx) @@ -124,7 +148,30 @@ func (_m *Client) CheckTxSync(_a0 types.RequestCheckTx) (*types.ResponseCheckTx, } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestCheckTx) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, types.RequestCheckTx) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CommitAsync provides a mock function with given fields: _a0 +func (_m *Client) CommitAsync(_a0 context.Context) (*abcicli.ReqRes, error) { + ret := _m.Called(_a0) + + var r0 *abcicli.ReqRes + if rf, ok := ret.Get(0).(func(context.Context) *abcicli.ReqRes); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*abcicli.ReqRes) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context) error); ok { r1 = rf(_a0) } else { r1 = ret.Error(1) @@ -133,29 +180,13 @@ func (_m *Client) CheckTxSync(_a0 types.RequestCheckTx) (*types.ResponseCheckTx, return r0, r1 } -// CommitAsync provides a mock function with given fields: -func (_m *Client) CommitAsync() *abcicli.ReqRes { - ret := _m.Called() - - var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func() *abcicli.ReqRes); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abcicli.ReqRes) - } - } - - return r0 -} - -// CommitSync provides a mock function with given fields: -func (_m *Client) CommitSync() (*types.ResponseCommit, error) { - ret := _m.Called() +// CommitSync provides a mock function with given fields: _a0 +func (_m *Client) CommitSync(_a0 context.Context) (*types.ResponseCommit, error) { + ret := _m.Called(_a0) var r0 *types.ResponseCommit - if rf, ok := ret.Get(0).(func() *types.ResponseCommit); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(context.Context) *types.ResponseCommit); ok { + r0 = rf(_a0) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseCommit) @@ -163,8 +194,8 @@ func (_m *Client) CommitSync() (*types.ResponseCommit, error) { } var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(_a0) } else { r1 = ret.Error(1) } @@ -172,29 +203,36 @@ func (_m *Client) CommitSync() (*types.ResponseCommit, error) { return r0, r1 } -// DeliverTxAsync provides a mock function with given fields: _a0 -func (_m *Client) DeliverTxAsync(_a0 types.RequestDeliverTx) *abcicli.ReqRes { - ret := _m.Called(_a0) +// DeliverTxAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) DeliverTxAsync(_a0 context.Context, _a1 types.RequestDeliverTx) (*abcicli.ReqRes, error) { + ret := _m.Called(_a0, _a1) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestDeliverTx) *abcicli.ReqRes); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestDeliverTx) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestDeliverTx) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// DeliverTxSync provides a mock function with given fields: _a0 -func (_m *Client) DeliverTxSync(_a0 types.RequestDeliverTx) (*types.ResponseDeliverTx, error) { - ret := _m.Called(_a0) +// DeliverTxSync provides a mock function with given fields: _a0, _a1 +func (_m *Client) DeliverTxSync(_a0 context.Context, _a1 types.RequestDeliverTx) (*types.ResponseDeliverTx, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponseDeliverTx - if rf, ok := ret.Get(0).(func(types.RequestDeliverTx) *types.ResponseDeliverTx); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestDeliverTx) *types.ResponseDeliverTx); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseDeliverTx) @@ -202,8 +240,8 @@ func (_m *Client) DeliverTxSync(_a0 types.RequestDeliverTx) (*types.ResponseDeli } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestDeliverTx) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, types.RequestDeliverTx) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -211,29 +249,36 @@ func (_m *Client) DeliverTxSync(_a0 types.RequestDeliverTx) (*types.ResponseDeli return r0, r1 } -// EchoAsync provides a mock function with given fields: msg -func (_m *Client) EchoAsync(msg string) *abcicli.ReqRes { - ret := _m.Called(msg) +// EchoAsync provides a mock function with given fields: ctx, msg +func (_m *Client) EchoAsync(ctx context.Context, msg string) (*abcicli.ReqRes, error) { + ret := _m.Called(ctx, msg) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(string) *abcicli.ReqRes); ok { - r0 = rf(msg) + if rf, ok := ret.Get(0).(func(context.Context, string) *abcicli.ReqRes); ok { + r0 = rf(ctx, msg) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, msg) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// EchoSync provides a mock function with given fields: msg -func (_m *Client) EchoSync(msg string) (*types.ResponseEcho, error) { - ret := _m.Called(msg) +// EchoSync provides a mock function with given fields: ctx, msg +func (_m *Client) EchoSync(ctx context.Context, msg string) (*types.ResponseEcho, error) { + ret := _m.Called(ctx, msg) var r0 *types.ResponseEcho - if rf, ok := ret.Get(0).(func(string) *types.ResponseEcho); ok { - r0 = rf(msg) + if rf, ok := ret.Get(0).(func(context.Context, string) *types.ResponseEcho); ok { + r0 = rf(ctx, msg) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseEcho) @@ -241,8 +286,8 @@ func (_m *Client) EchoSync(msg string) (*types.ResponseEcho, error) { } var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(msg) + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, msg) } else { r1 = ret.Error(1) } @@ -250,29 +295,36 @@ func (_m *Client) EchoSync(msg string) (*types.ResponseEcho, error) { return r0, r1 } -// EndBlockAsync provides a mock function with given fields: _a0 -func (_m *Client) EndBlockAsync(_a0 types.RequestEndBlock) *abcicli.ReqRes { - ret := _m.Called(_a0) +// EndBlockAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) EndBlockAsync(_a0 context.Context, _a1 types.RequestEndBlock) (*abcicli.ReqRes, error) { + ret := _m.Called(_a0, _a1) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestEndBlock) *abcicli.ReqRes); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestEndBlock) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestEndBlock) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// EndBlockSync provides a mock function with given fields: _a0 -func (_m *Client) EndBlockSync(_a0 types.RequestEndBlock) (*types.ResponseEndBlock, error) { - ret := _m.Called(_a0) +// EndBlockSync provides a mock function with given fields: _a0, _a1 +func (_m *Client) EndBlockSync(_a0 context.Context, _a1 types.RequestEndBlock) (*types.ResponseEndBlock, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponseEndBlock - if rf, ok := ret.Get(0).(func(types.RequestEndBlock) *types.ResponseEndBlock); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestEndBlock) *types.ResponseEndBlock); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseEndBlock) @@ -280,8 +332,8 @@ func (_m *Client) EndBlockSync(_a0 types.RequestEndBlock) (*types.ResponseEndBlo } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestEndBlock) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, types.RequestEndBlock) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -303,42 +355,12 @@ func (_m *Client) Error() error { return r0 } -// FlushAsync provides a mock function with given fields: -func (_m *Client) FlushAsync() *abcicli.ReqRes { - ret := _m.Called() - - var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func() *abcicli.ReqRes); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abcicli.ReqRes) - } - } - - return r0 -} - -// FlushSync provides a mock function with given fields: -func (_m *Client) FlushSync() error { - ret := _m.Called() - - var r0 error - if rf, ok := ret.Get(0).(func() error); ok { - r0 = rf() - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// InfoAsync provides a mock function with given fields: _a0 -func (_m *Client) InfoAsync(_a0 types.RequestInfo) *abcicli.ReqRes { +// FlushAsync provides a mock function with given fields: _a0 +func (_m *Client) FlushAsync(_a0 context.Context) (*abcicli.ReqRes, error) { ret := _m.Called(_a0) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestInfo) *abcicli.ReqRes); ok { + if rf, ok := ret.Get(0).(func(context.Context) *abcicli.ReqRes); ok { r0 = rf(_a0) } else { if ret.Get(0) != nil { @@ -346,24 +368,8 @@ func (_m *Client) InfoAsync(_a0 types.RequestInfo) *abcicli.ReqRes { } } - return r0 -} - -// InfoSync provides a mock function with given fields: _a0 -func (_m *Client) InfoSync(_a0 types.RequestInfo) (*types.ResponseInfo, error) { - ret := _m.Called(_a0) - - var r0 *types.ResponseInfo - if rf, ok := ret.Get(0).(func(types.RequestInfo) *types.ResponseInfo); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.ResponseInfo) - } - } - var r1 error - if rf, ok := ret.Get(1).(func(types.RequestInfo) error); ok { + if rf, ok := ret.Get(1).(func(context.Context) error); ok { r1 = rf(_a0) } else { r1 = ret.Error(1) @@ -372,29 +378,96 @@ func (_m *Client) InfoSync(_a0 types.RequestInfo) (*types.ResponseInfo, error) { return r0, r1 } -// InitChainAsync provides a mock function with given fields: _a0 -func (_m *Client) InitChainAsync(_a0 types.RequestInitChain) *abcicli.ReqRes { +// FlushSync provides a mock function with given fields: _a0 +func (_m *Client) FlushSync(_a0 context.Context) error { ret := _m.Called(_a0) - var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestInitChain) *abcicli.ReqRes); ok { + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// InfoAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) InfoAsync(_a0 context.Context, _a1 types.RequestInfo) (*abcicli.ReqRes, error) { + ret := _m.Called(_a0, _a1) + + var r0 *abcicli.ReqRes + if rf, ok := ret.Get(0).(func(context.Context, types.RequestInfo) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestInfo) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// InitChainSync provides a mock function with given fields: _a0 -func (_m *Client) InitChainSync(_a0 types.RequestInitChain) (*types.ResponseInitChain, error) { - ret := _m.Called(_a0) +// InfoSync provides a mock function with given fields: _a0, _a1 +func (_m *Client) InfoSync(_a0 context.Context, _a1 types.RequestInfo) (*types.ResponseInfo, error) { + ret := _m.Called(_a0, _a1) + + var r0 *types.ResponseInfo + if rf, ok := ret.Get(0).(func(context.Context, types.RequestInfo) *types.ResponseInfo); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseInfo) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestInfo) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// InitChainAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) InitChainAsync(_a0 context.Context, _a1 types.RequestInitChain) (*abcicli.ReqRes, error) { + ret := _m.Called(_a0, _a1) + + var r0 *abcicli.ReqRes + if rf, ok := ret.Get(0).(func(context.Context, types.RequestInitChain) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*abcicli.ReqRes) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestInitChain) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// InitChainSync provides a mock function with given fields: _a0, _a1 +func (_m *Client) InitChainSync(_a0 context.Context, _a1 types.RequestInitChain) (*types.ResponseInitChain, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponseInitChain - if rf, ok := ret.Get(0).(func(types.RequestInitChain) *types.ResponseInitChain); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestInitChain) *types.ResponseInitChain); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseInitChain) @@ -402,8 +475,8 @@ func (_m *Client) InitChainSync(_a0 types.RequestInitChain) (*types.ResponseInit } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestInitChain) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, types.RequestInitChain) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -425,29 +498,36 @@ func (_m *Client) IsRunning() bool { return r0 } -// ListSnapshotsAsync provides a mock function with given fields: _a0 -func (_m *Client) ListSnapshotsAsync(_a0 types.RequestListSnapshots) *abcicli.ReqRes { - ret := _m.Called(_a0) +// ListSnapshotsAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) ListSnapshotsAsync(_a0 context.Context, _a1 types.RequestListSnapshots) (*abcicli.ReqRes, error) { + ret := _m.Called(_a0, _a1) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestListSnapshots) *abcicli.ReqRes); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestListSnapshots) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestListSnapshots) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// ListSnapshotsSync provides a mock function with given fields: _a0 -func (_m *Client) ListSnapshotsSync(_a0 types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { - ret := _m.Called(_a0) +// ListSnapshotsSync provides a mock function with given fields: _a0, _a1 +func (_m *Client) ListSnapshotsSync(_a0 context.Context, _a1 types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponseListSnapshots - if rf, ok := ret.Get(0).(func(types.RequestListSnapshots) *types.ResponseListSnapshots); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestListSnapshots) *types.ResponseListSnapshots); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseListSnapshots) @@ -455,8 +535,8 @@ func (_m *Client) ListSnapshotsSync(_a0 types.RequestListSnapshots) (*types.Resp } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestListSnapshots) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, types.RequestListSnapshots) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -464,29 +544,36 @@ func (_m *Client) ListSnapshotsSync(_a0 types.RequestListSnapshots) (*types.Resp return r0, r1 } -// LoadSnapshotChunkAsync provides a mock function with given fields: _a0 -func (_m *Client) LoadSnapshotChunkAsync(_a0 types.RequestLoadSnapshotChunk) *abcicli.ReqRes { - ret := _m.Called(_a0) +// LoadSnapshotChunkAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) LoadSnapshotChunkAsync(_a0 context.Context, _a1 types.RequestLoadSnapshotChunk) (*abcicli.ReqRes, error) { + ret := _m.Called(_a0, _a1) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestLoadSnapshotChunk) *abcicli.ReqRes); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestLoadSnapshotChunk) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestLoadSnapshotChunk) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// LoadSnapshotChunkSync provides a mock function with given fields: _a0 -func (_m *Client) LoadSnapshotChunkSync(_a0 types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { - ret := _m.Called(_a0) +// LoadSnapshotChunkSync provides a mock function with given fields: _a0, _a1 +func (_m *Client) LoadSnapshotChunkSync(_a0 context.Context, _a1 types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponseLoadSnapshotChunk - if rf, ok := ret.Get(0).(func(types.RequestLoadSnapshotChunk) *types.ResponseLoadSnapshotChunk); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestLoadSnapshotChunk) *types.ResponseLoadSnapshotChunk); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseLoadSnapshotChunk) @@ -494,8 +581,8 @@ func (_m *Client) LoadSnapshotChunkSync(_a0 types.RequestLoadSnapshotChunk) (*ty } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestLoadSnapshotChunk) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, types.RequestLoadSnapshotChunk) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -503,29 +590,36 @@ func (_m *Client) LoadSnapshotChunkSync(_a0 types.RequestLoadSnapshotChunk) (*ty return r0, r1 } -// OfferSnapshotAsync provides a mock function with given fields: _a0 -func (_m *Client) OfferSnapshotAsync(_a0 types.RequestOfferSnapshot) *abcicli.ReqRes { - ret := _m.Called(_a0) +// OfferSnapshotAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) OfferSnapshotAsync(_a0 context.Context, _a1 types.RequestOfferSnapshot) (*abcicli.ReqRes, error) { + ret := _m.Called(_a0, _a1) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestOfferSnapshot) *abcicli.ReqRes); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestOfferSnapshot) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestOfferSnapshot) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// OfferSnapshotSync provides a mock function with given fields: _a0 -func (_m *Client) OfferSnapshotSync(_a0 types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { - ret := _m.Called(_a0) +// OfferSnapshotSync provides a mock function with given fields: _a0, _a1 +func (_m *Client) OfferSnapshotSync(_a0 context.Context, _a1 types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponseOfferSnapshot - if rf, ok := ret.Get(0).(func(types.RequestOfferSnapshot) *types.ResponseOfferSnapshot); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestOfferSnapshot) *types.ResponseOfferSnapshot); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseOfferSnapshot) @@ -533,8 +627,8 @@ func (_m *Client) OfferSnapshotSync(_a0 types.RequestOfferSnapshot) (*types.Resp } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestOfferSnapshot) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, types.RequestOfferSnapshot) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -575,29 +669,36 @@ func (_m *Client) OnStop() { _m.Called() } -// QueryAsync provides a mock function with given fields: _a0 -func (_m *Client) QueryAsync(_a0 types.RequestQuery) *abcicli.ReqRes { - ret := _m.Called(_a0) +// QueryAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) QueryAsync(_a0 context.Context, _a1 types.RequestQuery) (*abcicli.ReqRes, error) { + ret := _m.Called(_a0, _a1) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestQuery) *abcicli.ReqRes); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestQuery) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestQuery) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// QuerySync provides a mock function with given fields: _a0 -func (_m *Client) QuerySync(_a0 types.RequestQuery) (*types.ResponseQuery, error) { - ret := _m.Called(_a0) +// QuerySync provides a mock function with given fields: _a0, _a1 +func (_m *Client) QuerySync(_a0 context.Context, _a1 types.RequestQuery) (*types.ResponseQuery, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponseQuery - if rf, ok := ret.Get(0).(func(types.RequestQuery) *types.ResponseQuery); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestQuery) *types.ResponseQuery); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseQuery) @@ -605,8 +706,8 @@ func (_m *Client) QuerySync(_a0 types.RequestQuery) (*types.ResponseQuery, error } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestQuery) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, types.RequestQuery) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } diff --git a/abci/client/socket_client.go b/abci/client/socket_client.go index 040ac2d37..5c3fec937 100644 --- a/abci/client/socket_client.go +++ b/abci/client/socket_client.go @@ -3,6 +3,7 @@ package abcicli import ( "bufio" "container/list" + "context" "errors" "fmt" "io" @@ -18,10 +19,18 @@ import ( ) const ( - reqQueueSize = 256 // TODO make configurable - flushThrottleMS = 20 // Don't wait longer than... + // reqQueueSize is the max number of queued async requests. + // (memory: 256MB max assuming 1MB transactions) + reqQueueSize = 256 + // Don't wait longer than... + flushThrottleMS = 20 ) +type reqResWithContext struct { + R *ReqRes + C context.Context // if context.Err is not nil, reqRes will be thrown away (ignored) +} + // This is goroutine-safe, but users should beware that the application in // general is not meant to be interfaced with concurrent callers. type socketClient struct { @@ -31,7 +40,7 @@ type socketClient struct { mustConnect bool conn net.Conn - reqQueue chan *ReqRes + reqQueue chan *reqResWithContext flushTimer *timer.ThrottleTimer mtx tmsync.Mutex @@ -47,7 +56,7 @@ var _ Client = (*socketClient)(nil) // if it fails to connect. func NewSocketClient(addr string, mustConnect bool) Client { cli := &socketClient{ - reqQueue: make(chan *ReqRes, reqQueueSize), + reqQueue: make(chan *reqResWithContext, reqQueueSize), flushTimer: timer.NewThrottleTimer("socketClient", flushThrottleMS), mustConnect: mustConnect, @@ -123,15 +132,20 @@ func (cli *socketClient) sendRequestsRoutine(conn io.Writer) { case reqres := <-cli.reqQueue: // cli.Logger.Debug("Sent request", "requestType", reflect.TypeOf(reqres.Request), "request", reqres.Request) - cli.willSendReq(reqres) - err := types.WriteMessage(reqres.Request, w) + if reqres.C.Err() != nil { + cli.Logger.Debug("Request's context is done", "req", reqres.R, "err", reqres.C.Err()) + continue + } + + cli.willSendReq(reqres.R) + err := types.WriteMessage(reqres.R.Request, w) if err != nil { cli.stopForError(fmt.Errorf("write to buffer: %w", err)) return } // If it's a flush request, flush the current buffer. - if _, ok := reqres.Request.Value.(*types.Request_Flush); ok { + if _, ok := reqres.R.Request.Value.(*types.Request_Flush); ok { err = w.Flush() if err != nil { cli.stopForError(fmt.Errorf("flush buffer: %w", err)) @@ -140,7 +154,7 @@ func (cli *socketClient) sendRequestsRoutine(conn io.Writer) { } case <-cli.flushTimer.Ch: // flush queue select { - case cli.reqQueue <- NewReqRes(types.ToRequestFlush()): + case cli.reqQueue <- &reqResWithContext{R: NewReqRes(types.ToRequestFlush()), C: context.Background()}: default: // Probably will fill the buffer, or retry later. } @@ -221,198 +235,264 @@ func (cli *socketClient) didRecvResponse(res *types.Response) error { //---------------------------------------- -func (cli *socketClient) EchoAsync(msg string) *ReqRes { - return cli.queueRequest(types.ToRequestEcho(msg)) +func (cli *socketClient) EchoAsync(ctx context.Context, msg string) (*ReqRes, error) { + return cli.queueRequestAsync(ctx, types.ToRequestEcho(msg)) } -func (cli *socketClient) FlushAsync() *ReqRes { - return cli.queueRequest(types.ToRequestFlush()) +func (cli *socketClient) FlushAsync(ctx context.Context) (*ReqRes, error) { + return cli.queueRequestAsync(ctx, types.ToRequestFlush()) } -func (cli *socketClient) InfoAsync(req types.RequestInfo) *ReqRes { - return cli.queueRequest(types.ToRequestInfo(req)) +func (cli *socketClient) InfoAsync(ctx context.Context, req types.RequestInfo) (*ReqRes, error) { + return cli.queueRequestAsync(ctx, types.ToRequestInfo(req)) } -func (cli *socketClient) DeliverTxAsync(req types.RequestDeliverTx) *ReqRes { - return cli.queueRequest(types.ToRequestDeliverTx(req)) +func (cli *socketClient) DeliverTxAsync(ctx context.Context, req types.RequestDeliverTx) (*ReqRes, error) { + return cli.queueRequestAsync(ctx, types.ToRequestDeliverTx(req)) } -func (cli *socketClient) CheckTxAsync(req types.RequestCheckTx) *ReqRes { - return cli.queueRequest(types.ToRequestCheckTx(req)) +func (cli *socketClient) CheckTxAsync(ctx context.Context, req types.RequestCheckTx) (*ReqRes, error) { + return cli.queueRequestAsync(ctx, types.ToRequestCheckTx(req)) } -func (cli *socketClient) QueryAsync(req types.RequestQuery) *ReqRes { - return cli.queueRequest(types.ToRequestQuery(req)) +func (cli *socketClient) QueryAsync(ctx context.Context, req types.RequestQuery) (*ReqRes, error) { + return cli.queueRequestAsync(ctx, types.ToRequestQuery(req)) } -func (cli *socketClient) CommitAsync() *ReqRes { - return cli.queueRequest(types.ToRequestCommit()) +func (cli *socketClient) CommitAsync(ctx context.Context) (*ReqRes, error) { + return cli.queueRequestAsync(ctx, types.ToRequestCommit()) } -func (cli *socketClient) InitChainAsync(req types.RequestInitChain) *ReqRes { - return cli.queueRequest(types.ToRequestInitChain(req)) +func (cli *socketClient) InitChainAsync(ctx context.Context, req types.RequestInitChain) (*ReqRes, error) { + return cli.queueRequestAsync(ctx, types.ToRequestInitChain(req)) } -func (cli *socketClient) BeginBlockAsync(req types.RequestBeginBlock) *ReqRes { - return cli.queueRequest(types.ToRequestBeginBlock(req)) +func (cli *socketClient) BeginBlockAsync(ctx context.Context, req types.RequestBeginBlock) (*ReqRes, error) { + return cli.queueRequestAsync(ctx, types.ToRequestBeginBlock(req)) } -func (cli *socketClient) EndBlockAsync(req types.RequestEndBlock) *ReqRes { - return cli.queueRequest(types.ToRequestEndBlock(req)) +func (cli *socketClient) EndBlockAsync(ctx context.Context, req types.RequestEndBlock) (*ReqRes, error) { + return cli.queueRequestAsync(ctx, types.ToRequestEndBlock(req)) } -func (cli *socketClient) ListSnapshotsAsync(req types.RequestListSnapshots) *ReqRes { - return cli.queueRequest(types.ToRequestListSnapshots(req)) +func (cli *socketClient) ListSnapshotsAsync(ctx context.Context, req types.RequestListSnapshots) (*ReqRes, error) { + return cli.queueRequestAsync(ctx, types.ToRequestListSnapshots(req)) } -func (cli *socketClient) OfferSnapshotAsync(req types.RequestOfferSnapshot) *ReqRes { - return cli.queueRequest(types.ToRequestOfferSnapshot(req)) +func (cli *socketClient) OfferSnapshotAsync(ctx context.Context, req types.RequestOfferSnapshot) (*ReqRes, error) { + return cli.queueRequestAsync(ctx, types.ToRequestOfferSnapshot(req)) } -func (cli *socketClient) LoadSnapshotChunkAsync(req types.RequestLoadSnapshotChunk) *ReqRes { - return cli.queueRequest(types.ToRequestLoadSnapshotChunk(req)) +func (cli *socketClient) LoadSnapshotChunkAsync( + ctx context.Context, + req types.RequestLoadSnapshotChunk, +) (*ReqRes, error) { + return cli.queueRequestAsync(ctx, types.ToRequestLoadSnapshotChunk(req)) } -func (cli *socketClient) ApplySnapshotChunkAsync(req types.RequestApplySnapshotChunk) *ReqRes { - return cli.queueRequest(types.ToRequestApplySnapshotChunk(req)) +func (cli *socketClient) ApplySnapshotChunkAsync( + ctx context.Context, + req types.RequestApplySnapshotChunk, +) (*ReqRes, error) { + return cli.queueRequestAsync(ctx, types.ToRequestApplySnapshotChunk(req)) } //---------------------------------------- -func (cli *socketClient) FlushSync() error { - reqRes := cli.queueRequest(types.ToRequestFlush()) +func (cli *socketClient) FlushSync(ctx context.Context) error { + reqRes, err := cli.queueRequest(ctx, types.ToRequestFlush(), true) + if err != nil { + return queueErr(err) + } + if err := cli.Error(); err != nil { return err } - reqRes.Wait() // NOTE: if we don't flush the queue, its possible to get stuck here - return cli.Error() + + gotResp := make(chan struct{}) + go func() { + // NOTE: if we don't flush the queue, its possible to get stuck here + reqRes.Wait() + close(gotResp) + }() + + select { + case <-gotResp: + return cli.Error() + case <-ctx.Done(): + return ctx.Err() + } } -func (cli *socketClient) EchoSync(msg string) (*types.ResponseEcho, error) { - reqres := cli.queueRequest(types.ToRequestEcho(msg)) - if err := cli.FlushSync(); err != nil { +func (cli *socketClient) EchoSync(ctx context.Context, msg string) (*types.ResponseEcho, error) { + reqres, err := cli.queueRequestAndFlushSync(ctx, types.ToRequestEcho(msg)) + if err != nil { return nil, err } - - return reqres.Response.GetEcho(), cli.Error() + return reqres.Response.GetEcho(), nil } -func (cli *socketClient) InfoSync(req types.RequestInfo) (*types.ResponseInfo, error) { - reqres := cli.queueRequest(types.ToRequestInfo(req)) - if err := cli.FlushSync(); err != nil { +func (cli *socketClient) InfoSync( + ctx context.Context, + req types.RequestInfo, +) (*types.ResponseInfo, error) { + reqres, err := cli.queueRequestAndFlushSync(ctx, types.ToRequestInfo(req)) + if err != nil { return nil, err } - - return reqres.Response.GetInfo(), cli.Error() + return reqres.Response.GetInfo(), nil } -func (cli *socketClient) DeliverTxSync(req types.RequestDeliverTx) (*types.ResponseDeliverTx, error) { - reqres := cli.queueRequest(types.ToRequestDeliverTx(req)) - if err := cli.FlushSync(); err != nil { +func (cli *socketClient) DeliverTxSync( + ctx context.Context, + req types.RequestDeliverTx, +) (*types.ResponseDeliverTx, error) { + + reqres, err := cli.queueRequestAndFlushSync(ctx, types.ToRequestDeliverTx(req)) + if err != nil { return nil, err } - - return reqres.Response.GetDeliverTx(), cli.Error() + return reqres.Response.GetDeliverTx(), nil } -func (cli *socketClient) CheckTxSync(req types.RequestCheckTx) (*types.ResponseCheckTx, error) { - reqres := cli.queueRequest(types.ToRequestCheckTx(req)) - if err := cli.FlushSync(); err != nil { +func (cli *socketClient) CheckTxSync( + ctx context.Context, + req types.RequestCheckTx, +) (*types.ResponseCheckTx, error) { + reqres, err := cli.queueRequestAndFlushSync(ctx, types.ToRequestCheckTx(req)) + if err != nil { return nil, err } - - return reqres.Response.GetCheckTx(), cli.Error() + return reqres.Response.GetCheckTx(), nil } -func (cli *socketClient) QuerySync(req types.RequestQuery) (*types.ResponseQuery, error) { - reqres := cli.queueRequest(types.ToRequestQuery(req)) - if err := cli.FlushSync(); err != nil { +func (cli *socketClient) QuerySync( + ctx context.Context, + req types.RequestQuery, +) (*types.ResponseQuery, error) { + reqres, err := cli.queueRequestAndFlushSync(ctx, types.ToRequestQuery(req)) + if err != nil { return nil, err } - - return reqres.Response.GetQuery(), cli.Error() + return reqres.Response.GetQuery(), nil } -func (cli *socketClient) CommitSync() (*types.ResponseCommit, error) { - reqres := cli.queueRequest(types.ToRequestCommit()) - if err := cli.FlushSync(); err != nil { +func (cli *socketClient) CommitSync(ctx context.Context) (*types.ResponseCommit, error) { + reqres, err := cli.queueRequestAndFlushSync(ctx, types.ToRequestCommit()) + if err != nil { return nil, err } - - return reqres.Response.GetCommit(), cli.Error() + return reqres.Response.GetCommit(), nil } -func (cli *socketClient) InitChainSync(req types.RequestInitChain) (*types.ResponseInitChain, error) { - reqres := cli.queueRequest(types.ToRequestInitChain(req)) - if err := cli.FlushSync(); err != nil { +func (cli *socketClient) InitChainSync( + ctx context.Context, + req types.RequestInitChain, +) (*types.ResponseInitChain, error) { + + reqres, err := cli.queueRequestAndFlushSync(ctx, types.ToRequestInitChain(req)) + if err != nil { return nil, err } - - return reqres.Response.GetInitChain(), cli.Error() + return reqres.Response.GetInitChain(), nil } -func (cli *socketClient) BeginBlockSync(req types.RequestBeginBlock) (*types.ResponseBeginBlock, error) { - reqres := cli.queueRequest(types.ToRequestBeginBlock(req)) - if err := cli.FlushSync(); err != nil { +func (cli *socketClient) BeginBlockSync( + ctx context.Context, + req types.RequestBeginBlock, +) (*types.ResponseBeginBlock, error) { + + reqres, err := cli.queueRequestAndFlushSync(ctx, types.ToRequestBeginBlock(req)) + if err != nil { return nil, err } - - return reqres.Response.GetBeginBlock(), cli.Error() + return reqres.Response.GetBeginBlock(), nil } -func (cli *socketClient) EndBlockSync(req types.RequestEndBlock) (*types.ResponseEndBlock, error) { - reqres := cli.queueRequest(types.ToRequestEndBlock(req)) - if err := cli.FlushSync(); err != nil { +func (cli *socketClient) EndBlockSync( + ctx context.Context, + req types.RequestEndBlock, +) (*types.ResponseEndBlock, error) { + + reqres, err := cli.queueRequestAndFlushSync(ctx, types.ToRequestEndBlock(req)) + if err != nil { return nil, err } - - return reqres.Response.GetEndBlock(), cli.Error() + return reqres.Response.GetEndBlock(), nil } -func (cli *socketClient) ListSnapshotsSync(req types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { - reqres := cli.queueRequest(types.ToRequestListSnapshots(req)) - if err := cli.FlushSync(); err != nil { +func (cli *socketClient) ListSnapshotsSync( + ctx context.Context, + req types.RequestListSnapshots, +) (*types.ResponseListSnapshots, error) { + + reqres, err := cli.queueRequestAndFlushSync(ctx, types.ToRequestListSnapshots(req)) + if err != nil { return nil, err } - - return reqres.Response.GetListSnapshots(), cli.Error() + return reqres.Response.GetListSnapshots(), nil } -func (cli *socketClient) OfferSnapshotSync(req types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { - reqres := cli.queueRequest(types.ToRequestOfferSnapshot(req)) - if err := cli.FlushSync(); err != nil { +func (cli *socketClient) OfferSnapshotSync( + ctx context.Context, + req types.RequestOfferSnapshot, +) (*types.ResponseOfferSnapshot, error) { + + reqres, err := cli.queueRequestAndFlushSync(ctx, types.ToRequestOfferSnapshot(req)) + if err != nil { return nil, err } - - return reqres.Response.GetOfferSnapshot(), cli.Error() + return reqres.Response.GetOfferSnapshot(), nil } func (cli *socketClient) LoadSnapshotChunkSync( + ctx context.Context, req types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { - reqres := cli.queueRequest(types.ToRequestLoadSnapshotChunk(req)) - if err := cli.FlushSync(); err != nil { + + reqres, err := cli.queueRequestAndFlushSync(ctx, types.ToRequestLoadSnapshotChunk(req)) + if err != nil { return nil, err } - - return reqres.Response.GetLoadSnapshotChunk(), cli.Error() + return reqres.Response.GetLoadSnapshotChunk(), nil } func (cli *socketClient) ApplySnapshotChunkSync( + ctx context.Context, req types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { - reqres := cli.queueRequest(types.ToRequestApplySnapshotChunk(req)) - if err := cli.FlushSync(); err != nil { + + reqres, err := cli.queueRequestAndFlushSync(ctx, types.ToRequestApplySnapshotChunk(req)) + if err != nil { return nil, err } - return reqres.Response.GetApplySnapshotChunk(), cli.Error() + return reqres.Response.GetApplySnapshotChunk(), nil } //---------------------------------------- -func (cli *socketClient) queueRequest(req *types.Request) *ReqRes { +// queueRequest enqueues req onto the queue. If the queue is full, it ether +// returns an error (sync=false) or blocks (sync=true). +// +// When sync=true, ctx can be used to break early. When sync=false, ctx will be +// used later to determine if request should be dropped (if ctx.Err is +// non-nil). +// +// The caller is responsible for checking cli.Error. +func (cli *socketClient) queueRequest(ctx context.Context, req *types.Request, sync bool) (*ReqRes, error) { reqres := NewReqRes(req) - // TODO: set cli.err if reqQueue times out - cli.reqQueue <- reqres + if sync { + select { + case cli.reqQueue <- &reqResWithContext{R: reqres, C: context.Background()}: + case <-ctx.Done(): + return nil, ctx.Err() + } + } else { + select { + case cli.reqQueue <- &reqResWithContext{R: reqres, C: ctx}: + default: + return nil, errors.New("buffer is full") + } + } // Maybe auto-flush, or unset auto-flush switch req.Value.(type) { @@ -422,7 +502,41 @@ func (cli *socketClient) queueRequest(req *types.Request) *ReqRes { cli.flushTimer.Set() } - return reqres + return reqres, nil +} + +func (cli *socketClient) queueRequestAsync( + ctx context.Context, + req *types.Request, +) (*ReqRes, error) { + + reqres, err := cli.queueRequest(ctx, req, false) + if err != nil { + return nil, queueErr(err) + } + + return reqres, cli.Error() +} + +func (cli *socketClient) queueRequestAndFlushSync( + ctx context.Context, + req *types.Request, +) (*ReqRes, error) { + + reqres, err := cli.queueRequest(ctx, req, true) + if err != nil { + return nil, queueErr(err) + } + + if err := cli.FlushSync(ctx); err != nil { + return nil, err + } + + return reqres, cli.Error() +} + +func queueErr(e error) error { + return fmt.Errorf("can't queue req: %w", e) } func (cli *socketClient) flushQueue() { @@ -440,7 +554,7 @@ LOOP: for { select { case reqres := <-cli.reqQueue: - reqres.Done() + reqres.R.Done() default: break LOOP } @@ -489,12 +603,10 @@ func (cli *socketClient) stopForError(err error) { } cli.mtx.Lock() - if cli.err == nil { - cli.err = err - } + cli.err = err cli.mtx.Unlock() - cli.Logger.Error(fmt.Sprintf("Stopping abci.socketClient for error: %v", err.Error())) + cli.Logger.Info("Stopping abci.socketClient", "reason", err) if err := cli.Stop(); err != nil { cli.Logger.Error("Error stopping abci.socketClient", "err", err) } diff --git a/abci/client/socket_client_test.go b/abci/client/socket_client_test.go index 90b894b71..82114e002 100644 --- a/abci/client/socket_client_test.go +++ b/abci/client/socket_client_test.go @@ -1,6 +1,7 @@ package abcicli_test import ( + "context" "fmt" "testing" "time" @@ -15,6 +16,8 @@ import ( "github.com/tendermint/tendermint/libs/service" ) +var ctx = context.Background() + func TestProperSyncCalls(t *testing.T) { app := slowApp{} @@ -33,11 +36,12 @@ func TestProperSyncCalls(t *testing.T) { resp := make(chan error, 1) go func() { // This is BeginBlockSync unrolled.... - reqres := c.BeginBlockAsync(types.RequestBeginBlock{}) - err := c.FlushSync() - require.NoError(t, err) + reqres, err := c.BeginBlockAsync(ctx, types.RequestBeginBlock{}) + assert.NoError(t, err) + err = c.FlushSync(context.Background()) + assert.NoError(t, err) res := reqres.Response.GetBeginBlock() - require.NotNil(t, res) + assert.NotNil(t, res) resp <- c.Error() }() @@ -68,14 +72,16 @@ func TestHangingSyncCalls(t *testing.T) { resp := make(chan error, 1) go func() { // Start BeginBlock and flush it - reqres := c.BeginBlockAsync(types.RequestBeginBlock{}) - flush := c.FlushAsync() + reqres, err := c.BeginBlockAsync(ctx, types.RequestBeginBlock{}) + assert.NoError(t, err) + flush, err := c.FlushAsync(ctx) + assert.NoError(t, err) // wait 20 ms for all events to travel socket, but // no response yet from server time.Sleep(20 * time.Millisecond) // kill the server, so the connections break - err := s.Stop() - require.NoError(t, err) + err = s.Stop() + assert.NoError(t, err) // wait for the response from BeginBlock reqres.Wait() diff --git a/abci/cmd/abci-cli/abci-cli.go b/abci/cmd/abci-cli/abci-cli.go index 128403162..e5c9c7fec 100644 --- a/abci/cmd/abci-cli/abci-cli.go +++ b/abci/cmd/abci-cli/abci-cli.go @@ -2,6 +2,7 @@ package main import ( "bufio" + "context" "encoding/hex" "errors" "fmt" @@ -29,6 +30,8 @@ import ( var ( client abcicli.Client logger log.Logger + + ctx = context.Background() ) // flags @@ -463,7 +466,7 @@ func cmdEcho(cmd *cobra.Command, args []string) error { if len(args) > 0 { msg = args[0] } - res, err := client.EchoSync(msg) + res, err := client.EchoSync(ctx, msg) if err != nil { return err } @@ -479,7 +482,7 @@ func cmdInfo(cmd *cobra.Command, args []string) error { if len(args) == 1 { version = args[0] } - res, err := client.InfoSync(types.RequestInfo{Version: version}) + res, err := client.InfoSync(ctx, types.RequestInfo{Version: version}) if err != nil { return err } @@ -504,7 +507,7 @@ func cmdDeliverTx(cmd *cobra.Command, args []string) error { if err != nil { return err } - res, err := client.DeliverTxSync(types.RequestDeliverTx{Tx: txBytes}) + res, err := client.DeliverTxSync(ctx, types.RequestDeliverTx{Tx: txBytes}) if err != nil { return err } @@ -530,7 +533,7 @@ func cmdCheckTx(cmd *cobra.Command, args []string) error { if err != nil { return err } - res, err := client.CheckTxSync(types.RequestCheckTx{Tx: txBytes}) + res, err := client.CheckTxSync(ctx, types.RequestCheckTx{Tx: txBytes}) if err != nil { return err } @@ -545,7 +548,7 @@ func cmdCheckTx(cmd *cobra.Command, args []string) error { // Get application Merkle root hash func cmdCommit(cmd *cobra.Command, args []string) error { - res, err := client.CommitSync() + res, err := client.CommitSync(ctx) if err != nil { return err } @@ -570,7 +573,7 @@ func cmdQuery(cmd *cobra.Command, args []string) error { return err } - resQuery, err := client.QuerySync(types.RequestQuery{ + resQuery, err := client.QuerySync(ctx, types.RequestQuery{ Data: queryBytes, Path: flagPath, Height: int64(flagHeight), diff --git a/abci/example/example_test.go b/abci/example/example_test.go index 24641e11c..fdfc5515e 100644 --- a/abci/example/example_test.go +++ b/abci/example/example_test.go @@ -1,6 +1,7 @@ package example import ( + "context" "fmt" "math/rand" "net" @@ -13,8 +14,6 @@ import ( "google.golang.org/grpc" - "golang.org/x/net/context" - "github.com/tendermint/tendermint/libs/log" tmnet "github.com/tendermint/tendermint/libs/net" @@ -45,7 +44,7 @@ func TestGRPC(t *testing.T) { } func testStream(t *testing.T, app types.Application) { - numDeliverTxs := 20000 + const numDeliverTxs = 20000 socketFile := fmt.Sprintf("test-%08x.sock", rand.Int31n(1<<30)) defer os.Remove(socketFile) socket := fmt.Sprintf("unix://%v", socketFile) @@ -53,9 +52,8 @@ func testStream(t *testing.T, app types.Application) { // Start the listener server := abciserver.NewSocketServer(socket, app) server.SetLogger(log.TestingLogger().With("module", "abci-server")) - if err := server.Start(); err != nil { - require.NoError(t, err, "Error starting socket server") - } + err := server.Start() + require.NoError(t, err) t.Cleanup(func() { if err := server.Stop(); err != nil { t.Error(err) @@ -65,9 +63,8 @@ func testStream(t *testing.T, app types.Application) { // Connect to the socket client := abcicli.NewSocketClient(socket, false) client.SetLogger(log.TestingLogger().With("module", "abci-client")) - if err := client.Start(); err != nil { - t.Fatalf("Error starting socket client: %v", err.Error()) - } + err = client.Start() + require.NoError(t, err) t.Cleanup(func() { if err := client.Stop(); err != nil { t.Error(err) @@ -101,22 +98,24 @@ func testStream(t *testing.T, app types.Application) { } }) + ctx := context.Background() + // Write requests for counter := 0; counter < numDeliverTxs; counter++ { // Send request - reqRes := client.DeliverTxAsync(types.RequestDeliverTx{Tx: []byte("test")}) - _ = reqRes - // check err ? + _, err = client.DeliverTxAsync(ctx, types.RequestDeliverTx{Tx: []byte("test")}) + require.NoError(t, err) // Sometimes send flush messages - if counter%123 == 0 { - client.FlushAsync() - // check err ? + if counter%128 == 0 { + err = client.FlushSync(context.Background()) + require.NoError(t, err) } } // Send final flush message - client.FlushAsync() + _, err = client.FlushAsync(ctx) + require.NoError(t, err) <-done } diff --git a/abci/example/kvstore/kvstore_test.go b/abci/example/kvstore/kvstore_test.go index 2269ec228..a52312a00 100644 --- a/abci/example/kvstore/kvstore_test.go +++ b/abci/example/kvstore/kvstore_test.go @@ -1,6 +1,7 @@ package kvstore import ( + "context" "fmt" "io/ioutil" "sort" @@ -23,6 +24,8 @@ const ( testValue = "def" ) +var ctx = context.Background() + func testKVStore(t *testing.T, app types.Application, tx []byte, key, value string) { req := types.RequestDeliverTx{Tx: tx} ar := app.DeliverTx(req) @@ -323,23 +326,23 @@ func runClientTests(t *testing.T, client abcicli.Client) { } func testClient(t *testing.T, app abcicli.Client, tx []byte, key, value string) { - ar, err := app.DeliverTxSync(types.RequestDeliverTx{Tx: tx}) + ar, err := app.DeliverTxSync(ctx, types.RequestDeliverTx{Tx: tx}) require.NoError(t, err) require.False(t, ar.IsErr(), ar) // repeating tx doesn't raise error - ar, err = app.DeliverTxSync(types.RequestDeliverTx{Tx: tx}) + ar, err = app.DeliverTxSync(ctx, types.RequestDeliverTx{Tx: tx}) require.NoError(t, err) require.False(t, ar.IsErr(), ar) // commit - _, err = app.CommitSync() + _, err = app.CommitSync(ctx) require.NoError(t, err) - info, err := app.InfoSync(types.RequestInfo{}) + info, err := app.InfoSync(ctx, types.RequestInfo{}) require.NoError(t, err) require.NotZero(t, info.LastBlockHeight) // make sure query is fine - resQuery, err := app.QuerySync(types.RequestQuery{ + resQuery, err := app.QuerySync(ctx, types.RequestQuery{ Path: "/store", Data: []byte(key), }) @@ -350,7 +353,7 @@ func testClient(t *testing.T, app abcicli.Client, tx []byte, key, value string) require.EqualValues(t, info.LastBlockHeight, resQuery.Height) // make sure proof is fine - resQuery, err = app.QuerySync(types.RequestQuery{ + resQuery, err = app.QuerySync(ctx, types.RequestQuery{ Path: "/store", Data: []byte(key), Prove: true, diff --git a/abci/tests/server/client.go b/abci/tests/server/client.go index 1a11a9380..7b594da92 100644 --- a/abci/tests/server/client.go +++ b/abci/tests/server/client.go @@ -2,6 +2,7 @@ package testsuite import ( "bytes" + "context" "errors" "fmt" @@ -10,6 +11,8 @@ import ( tmrand "github.com/tendermint/tendermint/libs/rand" ) +var ctx = context.Background() + func InitChain(client abcicli.Client) error { total := 10 vals := make([]types.ValidatorUpdate, total) @@ -18,7 +21,7 @@ func InitChain(client abcicli.Client) error { power := tmrand.Int() vals[i] = types.UpdateValidator(pubkey, int64(power), "") } - _, err := client.InitChainSync(types.RequestInitChain{ + _, err := client.InitChainSync(ctx, types.RequestInitChain{ Validators: vals, }) if err != nil { @@ -30,7 +33,7 @@ func InitChain(client abcicli.Client) error { } func Commit(client abcicli.Client, hashExp []byte) error { - res, err := client.CommitSync() + res, err := client.CommitSync(ctx) data := res.Data if err != nil { fmt.Println("Failed test: Commit") @@ -47,7 +50,7 @@ func Commit(client abcicli.Client, hashExp []byte) error { } func DeliverTx(client abcicli.Client, txBytes []byte, codeExp uint32, dataExp []byte) error { - res, _ := client.DeliverTxSync(types.RequestDeliverTx{Tx: txBytes}) + res, _ := client.DeliverTxSync(ctx, types.RequestDeliverTx{Tx: txBytes}) code, data, log := res.Code, res.Data, res.Log if code != codeExp { fmt.Println("Failed test: DeliverTx") @@ -66,7 +69,7 @@ func DeliverTx(client abcicli.Client, txBytes []byte, codeExp uint32, dataExp [] } func CheckTx(client abcicli.Client, txBytes []byte, codeExp uint32, dataExp []byte) error { - res, _ := client.CheckTxSync(types.RequestCheckTx{Tx: txBytes}) + res, _ := client.CheckTxSync(ctx, types.RequestCheckTx{Tx: txBytes}) code, data, log := res.Code, res.Data, res.Log if code != codeExp { fmt.Println("Failed test: CheckTx") diff --git a/abci/tests/test_app/app.go b/abci/tests/test_app/app.go index 8876ada48..b3878fb0d 100644 --- a/abci/tests/test_app/app.go +++ b/abci/tests/test_app/app.go @@ -2,6 +2,7 @@ package main import ( "bytes" + "context" "fmt" "os" @@ -10,6 +11,8 @@ import ( "github.com/tendermint/tendermint/libs/log" ) +var ctx = context.Background() + func startClient(abciType string) abcicli.Client { // Start client client, err := abcicli.NewClient("tcp://127.0.0.1:26658", abciType, true) @@ -26,7 +29,7 @@ func startClient(abciType string) abcicli.Client { } func commit(client abcicli.Client, hashExp []byte) { - res, err := client.CommitSync() + res, err := client.CommitSync(ctx) if err != nil { panicf("client error: %v", err) } @@ -36,7 +39,7 @@ func commit(client abcicli.Client, hashExp []byte) { } func deliverTx(client abcicli.Client, txBytes []byte, codeExp uint32, dataExp []byte) { - res, err := client.DeliverTxSync(types.RequestDeliverTx{Tx: txBytes}) + res, err := client.DeliverTxSync(ctx, types.RequestDeliverTx{Tx: txBytes}) if err != nil { panicf("client error: %v", err) } diff --git a/abci/types/application.go b/abci/types/application.go index 5b8270ba6..2a3cabd8b 100644 --- a/abci/types/application.go +++ b/abci/types/application.go @@ -1,7 +1,7 @@ package types import ( - context "golang.org/x/net/context" + "context" ) // Application is an interface that enables any finite, deterministic state machine diff --git a/consensus/replay.go b/consensus/replay.go index bfec9e96d..9e393fbda 100644 --- a/consensus/replay.go +++ b/consensus/replay.go @@ -2,6 +2,7 @@ package consensus import ( "bytes" + "context" "fmt" "hash/crc32" "io" @@ -241,7 +242,7 @@ func (h *Handshaker) NBlocks() int { func (h *Handshaker) Handshake(proxyApp proxy.AppConns) error { // Handshake is done via ABCI Info on the query conn. - res, err := proxyApp.Query().InfoSync(proxy.RequestInfo) + res, err := proxyApp.Query().InfoSync(context.Background(), proxy.RequestInfo) if err != nil { return fmt.Errorf("error calling Info: %v", err) } @@ -316,7 +317,7 @@ func (h *Handshaker) ReplayBlocks( Validators: nextVals, AppStateBytes: h.genDoc.AppState, } - res, err := proxyApp.Consensus().InitChainSync(req) + res, err := proxyApp.Consensus().InitChainSync(context.Background(), req) if err != nil { return nil, err } diff --git a/consensus/replay_test.go b/consensus/replay_test.go index b40d408c2..ca3d90f2a 100644 --- a/consensus/replay_test.go +++ b/consensus/replay_test.go @@ -627,7 +627,8 @@ func TestMockProxyApp(t *testing.T) { mock.SetResponseCallback(proxyCb) someTx := []byte("tx") - mock.DeliverTxAsync(abci.RequestDeliverTx{Tx: someTx}) + _, err = mock.DeliverTxAsync(context.Background(), abci.RequestDeliverTx{Tx: someTx}) + assert.NoError(t, err) }) assert.True(t, validTxs == 1) assert.True(t, invalidTxs == 0) @@ -750,7 +751,7 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin } // get the latest app hash from the app - res, err := proxyApp.Query().InfoSync(abci.RequestInfo{Version: ""}) + res, err := proxyApp.Query().InfoSync(context.Background(), abci.RequestInfo{Version: ""}) if err != nil { t.Fatal(err) } @@ -797,7 +798,7 @@ func buildAppStateFromChain(proxyApp proxy.AppConns, stateStore sm.Store, state.Version.Consensus.App = kvstore.ProtocolVersion // simulate handshake, receive app version validators := types.TM2PB.ValidatorUpdates(state.Validators) - if _, err := proxyApp.Consensus().InitChainSync(abci.RequestInitChain{ + if _, err := proxyApp.Consensus().InitChainSync(context.Background(), abci.RequestInitChain{ Validators: validators, }); err != nil { panic(err) @@ -847,7 +848,7 @@ func buildTMStateFromChain( state.Version.Consensus.App = kvstore.ProtocolVersion // simulate handshake, receive app version validators := types.TM2PB.ValidatorUpdates(state.Validators) - if _, err := proxyApp.Consensus().InitChainSync(abci.RequestInitChain{ + if _, err := proxyApp.Consensus().InitChainSync(context.Background(), abci.RequestInitChain{ Validators: validators, }); err != nil { panic(err) diff --git a/mempool/clist_mempool.go b/mempool/clist_mempool.go index 7b0c97522..4ce284798 100644 --- a/mempool/clist_mempool.go +++ b/mempool/clist_mempool.go @@ -3,6 +3,7 @@ package mempool import ( "bytes" "container/list" + "context" "crypto/sha256" "fmt" "sync" @@ -185,7 +186,7 @@ func (mem *CListMempool) TxsBytes() int64 { // Lock() must be help by the caller during execution. func (mem *CListMempool) FlushAppConn() error { - return mem.proxyAppConn.FlushSync() + return mem.proxyAppConn.FlushSync(context.Background()) } // XXX: Unsafe! Calling Flush may leave mempool in inconsistent state. @@ -285,7 +286,16 @@ func (mem *CListMempool) CheckTx(tx types.Tx, cb func(*abci.Response), txInfo Tx return ErrTxInCache } - reqRes := mem.proxyAppConn.CheckTxAsync(abci.RequestCheckTx{Tx: tx}) + ctx := context.Background() + if txInfo.Context != nil { + ctx = txInfo.Context + } + + reqRes, err := mem.proxyAppConn.CheckTxAsync(ctx, abci.RequestCheckTx{Tx: tx}) + if err != nil { + mem.cache.Remove(tx) + return err + } reqRes.SetCallback(mem.reqResCb(tx, txInfo.SenderID, txInfo.SenderP2PID, cb)) return nil @@ -634,17 +644,26 @@ func (mem *CListMempool) recheckTxs() { mem.recheckCursor = mem.txs.Front() mem.recheckEnd = mem.txs.Back() + ctx := context.Background() + // Push txs to proxyAppConn // NOTE: globalCb may be called concurrently. for e := mem.txs.Front(); e != nil; e = e.Next() { memTx := e.Value.(*mempoolTx) - mem.proxyAppConn.CheckTxAsync(abci.RequestCheckTx{ + _, err := mem.proxyAppConn.CheckTxAsync(ctx, abci.RequestCheckTx{ Tx: memTx.tx, Type: abci.CheckTxType_Recheck, }) + if err != nil { + // No need in retrying since memTx will be rechecked after next block. + mem.logger.Error("Can't check tx", "err", err) + } } - mem.proxyAppConn.FlushAsync() + _, err := mem.proxyAppConn.FlushAsync(ctx) + if err != nil { + mem.logger.Error("Can't flush txs", "err", err) + } } //-------------------------------------------------------------------------------- diff --git a/mempool/clist_mempool_test.go b/mempool/clist_mempool_test.go index 45f6f5aa8..1d4068198 100644 --- a/mempool/clist_mempool_test.go +++ b/mempool/clist_mempool_test.go @@ -1,6 +1,7 @@ package mempool import ( + "context" "crypto/rand" "crypto/sha256" "encoding/binary" @@ -313,11 +314,12 @@ func TestSerialReap(t *testing.T) { } commitRange := func(start, end int) { + ctx := context.Background() // Deliver some txs. for i := start; i < end; i++ { txBytes := make([]byte, 8) binary.BigEndian.PutUint64(txBytes, uint64(i)) - res, err := appConnCon.DeliverTxSync(abci.RequestDeliverTx{Tx: txBytes}) + res, err := appConnCon.DeliverTxSync(ctx, abci.RequestDeliverTx{Tx: txBytes}) if err != nil { t.Errorf("client error committing tx: %v", err) } @@ -326,7 +328,7 @@ func TestSerialReap(t *testing.T) { res.Code, res.Data, res.Log) } } - res, err := appConnCon.CommitSync() + res, err := appConnCon.CommitSync(ctx) if err != nil { t.Errorf("client error committing: %v", err) } @@ -520,10 +522,11 @@ func TestMempoolTxsBytes(t *testing.T) { t.Error(err) } }) - res, err := appConnCon.DeliverTxSync(abci.RequestDeliverTx{Tx: txBytes}) + ctx := context.Background() + res, err := appConnCon.DeliverTxSync(ctx, abci.RequestDeliverTx{Tx: txBytes}) require.NoError(t, err) require.EqualValues(t, 0, res.Code) - res2, err := appConnCon.CommitSync() + res2, err := appConnCon.CommitSync(ctx) require.NoError(t, err) require.NotEmpty(t, res2.Data) diff --git a/mempool/mempool.go b/mempool/mempool.go index d01958b53..f6ce722b6 100644 --- a/mempool/mempool.go +++ b/mempool/mempool.go @@ -1,6 +1,7 @@ package mempool import ( + "context" "fmt" abci "github.com/tendermint/tendermint/abci/types" @@ -98,6 +99,8 @@ type TxInfo struct { SenderID uint16 // SenderP2PID is the actual p2p.ID of the sender, used e.g. for logging. SenderP2PID p2p.ID + // Context is the optional context to cancel CheckTx + Context context.Context } //-------------------------------------------------------------------------------- diff --git a/node/node.go b/node/node.go index 7f365ed4c..83064dbae 100644 --- a/node/node.go +++ b/node/node.go @@ -438,7 +438,7 @@ func createTransport( connFilters, // ABCI query for address filtering. func(_ p2p.ConnSet, c net.Conn, _ []net.IP) error { - res, err := proxyApp.Query().QuerySync(abci.RequestQuery{ + res, err := proxyApp.Query().QuerySync(context.Background(), abci.RequestQuery{ Path: fmt.Sprintf("/p2p/filter/addr/%s", c.RemoteAddr().String()), }) if err != nil { @@ -456,7 +456,7 @@ func createTransport( peerFilters, // ABCI query for ID filtering. func(_ p2p.IPeerSet, p p2p.Peer) error { - res, err := proxyApp.Query().QuerySync(abci.RequestQuery{ + res, err := proxyApp.Query().QuerySync(context.Background(), abci.RequestQuery{ Path: fmt.Sprintf("/p2p/filter/id/%s", p.ID()), }) if err != nil { diff --git a/proxy/app_conn.go b/proxy/app_conn.go index 61652b30b..9165bdad4 100644 --- a/proxy/app_conn.go +++ b/proxy/app_conn.go @@ -1,6 +1,8 @@ package proxy import ( + "context" + abcicli "github.com/tendermint/tendermint/abci/client" "github.com/tendermint/tendermint/abci/types" ) @@ -14,40 +16,40 @@ type AppConnConsensus interface { SetResponseCallback(abcicli.Callback) Error() error - InitChainSync(types.RequestInitChain) (*types.ResponseInitChain, error) + InitChainSync(context.Context, types.RequestInitChain) (*types.ResponseInitChain, error) - BeginBlockSync(types.RequestBeginBlock) (*types.ResponseBeginBlock, error) - DeliverTxAsync(types.RequestDeliverTx) *abcicli.ReqRes - EndBlockSync(types.RequestEndBlock) (*types.ResponseEndBlock, error) - CommitSync() (*types.ResponseCommit, error) + BeginBlockSync(context.Context, types.RequestBeginBlock) (*types.ResponseBeginBlock, error) + DeliverTxAsync(context.Context, types.RequestDeliverTx) (*abcicli.ReqRes, error) + EndBlockSync(context.Context, types.RequestEndBlock) (*types.ResponseEndBlock, error) + CommitSync(context.Context) (*types.ResponseCommit, error) } type AppConnMempool interface { SetResponseCallback(abcicli.Callback) Error() error - CheckTxAsync(types.RequestCheckTx) *abcicli.ReqRes - CheckTxSync(types.RequestCheckTx) (*types.ResponseCheckTx, error) + CheckTxAsync(context.Context, types.RequestCheckTx) (*abcicli.ReqRes, error) + CheckTxSync(context.Context, types.RequestCheckTx) (*types.ResponseCheckTx, error) - FlushAsync() *abcicli.ReqRes - FlushSync() error + FlushAsync(context.Context) (*abcicli.ReqRes, error) + FlushSync(context.Context) error } type AppConnQuery interface { Error() error - EchoSync(string) (*types.ResponseEcho, error) - InfoSync(types.RequestInfo) (*types.ResponseInfo, error) - QuerySync(types.RequestQuery) (*types.ResponseQuery, error) + EchoSync(context.Context, string) (*types.ResponseEcho, error) + InfoSync(context.Context, types.RequestInfo) (*types.ResponseInfo, error) + QuerySync(context.Context, types.RequestQuery) (*types.ResponseQuery, error) } type AppConnSnapshot interface { Error() error - ListSnapshotsSync(types.RequestListSnapshots) (*types.ResponseListSnapshots, error) - OfferSnapshotSync(types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) - LoadSnapshotChunkSync(types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) - ApplySnapshotChunkSync(types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) + ListSnapshotsSync(context.Context, types.RequestListSnapshots) (*types.ResponseListSnapshots, error) + OfferSnapshotSync(context.Context, types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) + LoadSnapshotChunkSync(context.Context, types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) + ApplySnapshotChunkSync(context.Context, types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) } //----------------------------------------------------------------------------------------- @@ -71,24 +73,33 @@ func (app *appConnConsensus) Error() error { return app.appConn.Error() } -func (app *appConnConsensus) InitChainSync(req types.RequestInitChain) (*types.ResponseInitChain, error) { - return app.appConn.InitChainSync(req) +func (app *appConnConsensus) InitChainSync( + ctx context.Context, + req types.RequestInitChain, +) (*types.ResponseInitChain, error) { + return app.appConn.InitChainSync(ctx, req) } -func (app *appConnConsensus) BeginBlockSync(req types.RequestBeginBlock) (*types.ResponseBeginBlock, error) { - return app.appConn.BeginBlockSync(req) +func (app *appConnConsensus) BeginBlockSync( + ctx context.Context, + req types.RequestBeginBlock, +) (*types.ResponseBeginBlock, error) { + return app.appConn.BeginBlockSync(ctx, req) } -func (app *appConnConsensus) DeliverTxAsync(req types.RequestDeliverTx) *abcicli.ReqRes { - return app.appConn.DeliverTxAsync(req) +func (app *appConnConsensus) DeliverTxAsync(ctx context.Context, req types.RequestDeliverTx) (*abcicli.ReqRes, error) { + return app.appConn.DeliverTxAsync(ctx, req) } -func (app *appConnConsensus) EndBlockSync(req types.RequestEndBlock) (*types.ResponseEndBlock, error) { - return app.appConn.EndBlockSync(req) +func (app *appConnConsensus) EndBlockSync( + ctx context.Context, + req types.RequestEndBlock, +) (*types.ResponseEndBlock, error) { + return app.appConn.EndBlockSync(ctx, req) } -func (app *appConnConsensus) CommitSync() (*types.ResponseCommit, error) { - return app.appConn.CommitSync() +func (app *appConnConsensus) CommitSync(ctx context.Context) (*types.ResponseCommit, error) { + return app.appConn.CommitSync(ctx) } //------------------------------------------------ @@ -112,20 +123,20 @@ func (app *appConnMempool) Error() error { return app.appConn.Error() } -func (app *appConnMempool) FlushAsync() *abcicli.ReqRes { - return app.appConn.FlushAsync() +func (app *appConnMempool) FlushAsync(ctx context.Context) (*abcicli.ReqRes, error) { + return app.appConn.FlushAsync(ctx) } -func (app *appConnMempool) FlushSync() error { - return app.appConn.FlushSync() +func (app *appConnMempool) FlushSync(ctx context.Context) error { + return app.appConn.FlushSync(ctx) } -func (app *appConnMempool) CheckTxAsync(req types.RequestCheckTx) *abcicli.ReqRes { - return app.appConn.CheckTxAsync(req) +func (app *appConnMempool) CheckTxAsync(ctx context.Context, req types.RequestCheckTx) (*abcicli.ReqRes, error) { + return app.appConn.CheckTxAsync(ctx, req) } -func (app *appConnMempool) CheckTxSync(req types.RequestCheckTx) (*types.ResponseCheckTx, error) { - return app.appConn.CheckTxSync(req) +func (app *appConnMempool) CheckTxSync(ctx context.Context, req types.RequestCheckTx) (*types.ResponseCheckTx, error) { + return app.appConn.CheckTxSync(ctx, req) } //------------------------------------------------ @@ -145,16 +156,16 @@ func (app *appConnQuery) Error() error { return app.appConn.Error() } -func (app *appConnQuery) EchoSync(msg string) (*types.ResponseEcho, error) { - return app.appConn.EchoSync(msg) +func (app *appConnQuery) EchoSync(ctx context.Context, msg string) (*types.ResponseEcho, error) { + return app.appConn.EchoSync(ctx, msg) } -func (app *appConnQuery) InfoSync(req types.RequestInfo) (*types.ResponseInfo, error) { - return app.appConn.InfoSync(req) +func (app *appConnQuery) InfoSync(ctx context.Context, req types.RequestInfo) (*types.ResponseInfo, error) { + return app.appConn.InfoSync(ctx, req) } -func (app *appConnQuery) QuerySync(reqQuery types.RequestQuery) (*types.ResponseQuery, error) { - return app.appConn.QuerySync(reqQuery) +func (app *appConnQuery) QuerySync(ctx context.Context, reqQuery types.RequestQuery) (*types.ResponseQuery, error) { + return app.appConn.QuerySync(ctx, reqQuery) } //------------------------------------------------ @@ -174,20 +185,28 @@ func (app *appConnSnapshot) Error() error { return app.appConn.Error() } -func (app *appConnSnapshot) ListSnapshotsSync(req types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { - return app.appConn.ListSnapshotsSync(req) +func (app *appConnSnapshot) ListSnapshotsSync( + ctx context.Context, + req types.RequestListSnapshots, +) (*types.ResponseListSnapshots, error) { + return app.appConn.ListSnapshotsSync(ctx, req) } -func (app *appConnSnapshot) OfferSnapshotSync(req types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { - return app.appConn.OfferSnapshotSync(req) +func (app *appConnSnapshot) OfferSnapshotSync( + ctx context.Context, + req types.RequestOfferSnapshot, +) (*types.ResponseOfferSnapshot, error) { + return app.appConn.OfferSnapshotSync(ctx, req) } func (app *appConnSnapshot) LoadSnapshotChunkSync( + ctx context.Context, req types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { - return app.appConn.LoadSnapshotChunkSync(req) + return app.appConn.LoadSnapshotChunkSync(ctx, req) } func (app *appConnSnapshot) ApplySnapshotChunkSync( + ctx context.Context, req types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { - return app.appConn.ApplySnapshotChunkSync(req) + return app.appConn.ApplySnapshotChunkSync(ctx, req) } diff --git a/proxy/app_conn_test.go b/proxy/app_conn_test.go index 683fe47e0..458088635 100644 --- a/proxy/app_conn_test.go +++ b/proxy/app_conn_test.go @@ -1,6 +1,7 @@ package proxy import ( + "context" "fmt" "strings" "testing" @@ -15,30 +16,30 @@ import ( //---------------------------------------- -type AppConnTest interface { - EchoAsync(string) *abcicli.ReqRes - FlushSync() error - InfoSync(types.RequestInfo) (*types.ResponseInfo, error) +type appConnTestI interface { + EchoAsync(ctx context.Context, msg string) (*abcicli.ReqRes, error) + FlushSync(context.Context) error + InfoSync(context.Context, types.RequestInfo) (*types.ResponseInfo, error) } type appConnTest struct { appConn abcicli.Client } -func NewAppConnTest(appConn abcicli.Client) AppConnTest { +func newAppConnTest(appConn abcicli.Client) appConnTestI { return &appConnTest{appConn} } -func (app *appConnTest) EchoAsync(msg string) *abcicli.ReqRes { - return app.appConn.EchoAsync(msg) +func (app *appConnTest) EchoAsync(ctx context.Context, msg string) (*abcicli.ReqRes, error) { + return app.appConn.EchoAsync(ctx, msg) } -func (app *appConnTest) FlushSync() error { - return app.appConn.FlushSync() +func (app *appConnTest) FlushSync(ctx context.Context) error { + return app.appConn.FlushSync(ctx) } -func (app *appConnTest) InfoSync(req types.RequestInfo) (*types.ResponseInfo, error) { - return app.appConn.InfoSync(req) +func (app *appConnTest) InfoSync(ctx context.Context, req types.RequestInfo) (*types.ResponseInfo, error) { + return app.appConn.InfoSync(ctx, req) } //---------------------------------------- @@ -71,13 +72,23 @@ func TestEcho(t *testing.T) { t.Fatalf("Error starting ABCI client: %v", err.Error()) } - proxy := NewAppConnTest(cli) + proxy := newAppConnTest(cli) t.Log("Connected") + ctx := context.Background() for i := 0; i < 1000; i++ { - proxy.EchoAsync(fmt.Sprintf("echo-%v", i)) + _, err = proxy.EchoAsync(ctx, fmt.Sprintf("echo-%v", i)) + if err != nil { + t.Error(err) + } + // flush sometimes + if i%128 == 0 { + if err := proxy.FlushSync(ctx); err != nil { + t.Error(err) + } + } } - if err := proxy.FlushSync(); err != nil { + if err := proxy.FlushSync(ctx); err != nil { t.Error(err) } } @@ -109,15 +120,25 @@ func BenchmarkEcho(b *testing.B) { b.Fatalf("Error starting ABCI client: %v", err.Error()) } - proxy := NewAppConnTest(cli) + proxy := newAppConnTest(cli) b.Log("Connected") echoString := strings.Repeat(" ", 200) b.StartTimer() // Start benchmarking tests + ctx := context.Background() for i := 0; i < b.N; i++ { - proxy.EchoAsync(echoString) + _, err = proxy.EchoAsync(ctx, echoString) + if err != nil { + b.Error(err) + } + // flush sometimes + if i%128 == 0 { + if err := proxy.FlushSync(ctx); err != nil { + b.Error(err) + } + } } - if err := proxy.FlushSync(); err != nil { + if err := proxy.FlushSync(ctx); err != nil { b.Error(err) } @@ -152,10 +173,10 @@ func TestInfo(t *testing.T) { t.Fatalf("Error starting ABCI client: %v", err.Error()) } - proxy := NewAppConnTest(cli) + proxy := newAppConnTest(cli) t.Log("Connected") - resInfo, err := proxy.InfoSync(RequestInfo) + resInfo, err := proxy.InfoSync(context.Background(), RequestInfo) if err != nil { t.Errorf("unexpected error: %v", err) } diff --git a/proxy/mocks/app_conn_consensus.go b/proxy/mocks/app_conn_consensus.go index 7e5f81489..e51d9c8f4 100644 --- a/proxy/mocks/app_conn_consensus.go +++ b/proxy/mocks/app_conn_consensus.go @@ -3,9 +3,12 @@ package mocks import ( - mock "github.com/stretchr/testify/mock" + context "context" + abcicli "github.com/tendermint/tendermint/abci/client" + mock "github.com/stretchr/testify/mock" + types "github.com/tendermint/tendermint/abci/types" ) @@ -14,13 +17,13 @@ type AppConnConsensus struct { mock.Mock } -// BeginBlockSync provides a mock function with given fields: _a0 -func (_m *AppConnConsensus) BeginBlockSync(_a0 types.RequestBeginBlock) (*types.ResponseBeginBlock, error) { - ret := _m.Called(_a0) +// BeginBlockSync provides a mock function with given fields: _a0, _a1 +func (_m *AppConnConsensus) BeginBlockSync(_a0 context.Context, _a1 types.RequestBeginBlock) (*types.ResponseBeginBlock, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponseBeginBlock - if rf, ok := ret.Get(0).(func(types.RequestBeginBlock) *types.ResponseBeginBlock); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestBeginBlock) *types.ResponseBeginBlock); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseBeginBlock) @@ -28,8 +31,8 @@ func (_m *AppConnConsensus) BeginBlockSync(_a0 types.RequestBeginBlock) (*types. } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestBeginBlock) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, types.RequestBeginBlock) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -37,13 +40,13 @@ func (_m *AppConnConsensus) BeginBlockSync(_a0 types.RequestBeginBlock) (*types. return r0, r1 } -// CommitSync provides a mock function with given fields: -func (_m *AppConnConsensus) CommitSync() (*types.ResponseCommit, error) { - ret := _m.Called() +// CommitSync provides a mock function with given fields: _a0 +func (_m *AppConnConsensus) CommitSync(_a0 context.Context) (*types.ResponseCommit, error) { + ret := _m.Called(_a0) var r0 *types.ResponseCommit - if rf, ok := ret.Get(0).(func() *types.ResponseCommit); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(context.Context) *types.ResponseCommit); ok { + r0 = rf(_a0) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseCommit) @@ -51,8 +54,8 @@ func (_m *AppConnConsensus) CommitSync() (*types.ResponseCommit, error) { } var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(_a0) } else { r1 = ret.Error(1) } @@ -60,29 +63,36 @@ func (_m *AppConnConsensus) CommitSync() (*types.ResponseCommit, error) { return r0, r1 } -// DeliverTxAsync provides a mock function with given fields: _a0 -func (_m *AppConnConsensus) DeliverTxAsync(_a0 types.RequestDeliverTx) *abcicli.ReqRes { - ret := _m.Called(_a0) +// DeliverTxAsync provides a mock function with given fields: _a0, _a1 +func (_m *AppConnConsensus) DeliverTxAsync(_a0 context.Context, _a1 types.RequestDeliverTx) (*abcicli.ReqRes, error) { + ret := _m.Called(_a0, _a1) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestDeliverTx) *abcicli.ReqRes); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestDeliverTx) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestDeliverTx) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// EndBlockSync provides a mock function with given fields: _a0 -func (_m *AppConnConsensus) EndBlockSync(_a0 types.RequestEndBlock) (*types.ResponseEndBlock, error) { - ret := _m.Called(_a0) +// EndBlockSync provides a mock function with given fields: _a0, _a1 +func (_m *AppConnConsensus) EndBlockSync(_a0 context.Context, _a1 types.RequestEndBlock) (*types.ResponseEndBlock, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponseEndBlock - if rf, ok := ret.Get(0).(func(types.RequestEndBlock) *types.ResponseEndBlock); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestEndBlock) *types.ResponseEndBlock); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseEndBlock) @@ -90,8 +100,8 @@ func (_m *AppConnConsensus) EndBlockSync(_a0 types.RequestEndBlock) (*types.Resp } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestEndBlock) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, types.RequestEndBlock) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -113,13 +123,13 @@ func (_m *AppConnConsensus) Error() error { return r0 } -// InitChainSync provides a mock function with given fields: _a0 -func (_m *AppConnConsensus) InitChainSync(_a0 types.RequestInitChain) (*types.ResponseInitChain, error) { - ret := _m.Called(_a0) +// InitChainSync provides a mock function with given fields: _a0, _a1 +func (_m *AppConnConsensus) InitChainSync(_a0 context.Context, _a1 types.RequestInitChain) (*types.ResponseInitChain, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponseInitChain - if rf, ok := ret.Get(0).(func(types.RequestInitChain) *types.ResponseInitChain); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestInitChain) *types.ResponseInitChain); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseInitChain) @@ -127,8 +137,8 @@ func (_m *AppConnConsensus) InitChainSync(_a0 types.RequestInitChain) (*types.Re } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestInitChain) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, types.RequestInitChain) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } diff --git a/proxy/mocks/app_conn_mempool.go b/proxy/mocks/app_conn_mempool.go index b068c01eb..f8e605ee5 100644 --- a/proxy/mocks/app_conn_mempool.go +++ b/proxy/mocks/app_conn_mempool.go @@ -3,9 +3,12 @@ package mocks import ( - mock "github.com/stretchr/testify/mock" + context "context" + abcicli "github.com/tendermint/tendermint/abci/client" + mock "github.com/stretchr/testify/mock" + types "github.com/tendermint/tendermint/abci/types" ) @@ -14,29 +17,36 @@ type AppConnMempool struct { mock.Mock } -// CheckTxAsync provides a mock function with given fields: _a0 -func (_m *AppConnMempool) CheckTxAsync(_a0 types.RequestCheckTx) *abcicli.ReqRes { - ret := _m.Called(_a0) +// CheckTxAsync provides a mock function with given fields: _a0, _a1 +func (_m *AppConnMempool) CheckTxAsync(_a0 context.Context, _a1 types.RequestCheckTx) (*abcicli.ReqRes, error) { + ret := _m.Called(_a0, _a1) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestCheckTx) *abcicli.ReqRes); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestCheckTx) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, types.RequestCheckTx) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// CheckTxSync provides a mock function with given fields: _a0 -func (_m *AppConnMempool) CheckTxSync(_a0 types.RequestCheckTx) (*types.ResponseCheckTx, error) { - ret := _m.Called(_a0) +// CheckTxSync provides a mock function with given fields: _a0, _a1 +func (_m *AppConnMempool) CheckTxSync(_a0 context.Context, _a1 types.RequestCheckTx) (*types.ResponseCheckTx, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponseCheckTx - if rf, ok := ret.Get(0).(func(types.RequestCheckTx) *types.ResponseCheckTx); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestCheckTx) *types.ResponseCheckTx); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseCheckTx) @@ -44,8 +54,8 @@ func (_m *AppConnMempool) CheckTxSync(_a0 types.RequestCheckTx) (*types.Response } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestCheckTx) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, types.RequestCheckTx) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -67,29 +77,36 @@ func (_m *AppConnMempool) Error() error { return r0 } -// FlushAsync provides a mock function with given fields: -func (_m *AppConnMempool) FlushAsync() *abcicli.ReqRes { - ret := _m.Called() +// FlushAsync provides a mock function with given fields: _a0 +func (_m *AppConnMempool) FlushAsync(_a0 context.Context) (*abcicli.ReqRes, error) { + ret := _m.Called(_a0) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func() *abcicli.ReqRes); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(context.Context) *abcicli.ReqRes); ok { + r0 = rf(_a0) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// FlushSync provides a mock function with given fields: -func (_m *AppConnMempool) FlushSync() error { - ret := _m.Called() +// FlushSync provides a mock function with given fields: _a0 +func (_m *AppConnMempool) FlushSync(_a0 context.Context) error { + ret := _m.Called(_a0) var r0 error - if rf, ok := ret.Get(0).(func() error); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(_a0) } else { r0 = ret.Error(0) } diff --git a/proxy/mocks/app_conn_query.go b/proxy/mocks/app_conn_query.go index 970dfab3a..3b9792d06 100644 --- a/proxy/mocks/app_conn_query.go +++ b/proxy/mocks/app_conn_query.go @@ -3,6 +3,8 @@ package mocks import ( + context "context" + mock "github.com/stretchr/testify/mock" types "github.com/tendermint/tendermint/abci/types" @@ -13,13 +15,13 @@ type AppConnQuery struct { mock.Mock } -// EchoSync provides a mock function with given fields: _a0 -func (_m *AppConnQuery) EchoSync(_a0 string) (*types.ResponseEcho, error) { - ret := _m.Called(_a0) +// EchoSync provides a mock function with given fields: _a0, _a1 +func (_m *AppConnQuery) EchoSync(_a0 context.Context, _a1 string) (*types.ResponseEcho, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponseEcho - if rf, ok := ret.Get(0).(func(string) *types.ResponseEcho); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, string) *types.ResponseEcho); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseEcho) @@ -27,8 +29,8 @@ func (_m *AppConnQuery) EchoSync(_a0 string) (*types.ResponseEcho, error) { } var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -50,13 +52,13 @@ func (_m *AppConnQuery) Error() error { return r0 } -// InfoSync provides a mock function with given fields: _a0 -func (_m *AppConnQuery) InfoSync(_a0 types.RequestInfo) (*types.ResponseInfo, error) { - ret := _m.Called(_a0) +// InfoSync provides a mock function with given fields: _a0, _a1 +func (_m *AppConnQuery) InfoSync(_a0 context.Context, _a1 types.RequestInfo) (*types.ResponseInfo, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponseInfo - if rf, ok := ret.Get(0).(func(types.RequestInfo) *types.ResponseInfo); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestInfo) *types.ResponseInfo); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseInfo) @@ -64,8 +66,8 @@ func (_m *AppConnQuery) InfoSync(_a0 types.RequestInfo) (*types.ResponseInfo, er } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestInfo) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, types.RequestInfo) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -73,13 +75,13 @@ func (_m *AppConnQuery) InfoSync(_a0 types.RequestInfo) (*types.ResponseInfo, er return r0, r1 } -// QuerySync provides a mock function with given fields: _a0 -func (_m *AppConnQuery) QuerySync(_a0 types.RequestQuery) (*types.ResponseQuery, error) { - ret := _m.Called(_a0) +// QuerySync provides a mock function with given fields: _a0, _a1 +func (_m *AppConnQuery) QuerySync(_a0 context.Context, _a1 types.RequestQuery) (*types.ResponseQuery, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponseQuery - if rf, ok := ret.Get(0).(func(types.RequestQuery) *types.ResponseQuery); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestQuery) *types.ResponseQuery); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseQuery) @@ -87,8 +89,8 @@ func (_m *AppConnQuery) QuerySync(_a0 types.RequestQuery) (*types.ResponseQuery, } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestQuery) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, types.RequestQuery) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } diff --git a/proxy/mocks/app_conn_snapshot.go b/proxy/mocks/app_conn_snapshot.go index 8cd39c923..baa5fdd8e 100644 --- a/proxy/mocks/app_conn_snapshot.go +++ b/proxy/mocks/app_conn_snapshot.go @@ -3,6 +3,8 @@ package mocks import ( + context "context" + mock "github.com/stretchr/testify/mock" types "github.com/tendermint/tendermint/abci/types" @@ -13,13 +15,13 @@ type AppConnSnapshot struct { mock.Mock } -// ApplySnapshotChunkSync provides a mock function with given fields: _a0 -func (_m *AppConnSnapshot) ApplySnapshotChunkSync(_a0 types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { - ret := _m.Called(_a0) +// ApplySnapshotChunkSync provides a mock function with given fields: _a0, _a1 +func (_m *AppConnSnapshot) ApplySnapshotChunkSync(_a0 context.Context, _a1 types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponseApplySnapshotChunk - if rf, ok := ret.Get(0).(func(types.RequestApplySnapshotChunk) *types.ResponseApplySnapshotChunk); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestApplySnapshotChunk) *types.ResponseApplySnapshotChunk); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseApplySnapshotChunk) @@ -27,8 +29,8 @@ func (_m *AppConnSnapshot) ApplySnapshotChunkSync(_a0 types.RequestApplySnapshot } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestApplySnapshotChunk) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, types.RequestApplySnapshotChunk) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -50,13 +52,13 @@ func (_m *AppConnSnapshot) Error() error { return r0 } -// ListSnapshotsSync provides a mock function with given fields: _a0 -func (_m *AppConnSnapshot) ListSnapshotsSync(_a0 types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { - ret := _m.Called(_a0) +// ListSnapshotsSync provides a mock function with given fields: _a0, _a1 +func (_m *AppConnSnapshot) ListSnapshotsSync(_a0 context.Context, _a1 types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponseListSnapshots - if rf, ok := ret.Get(0).(func(types.RequestListSnapshots) *types.ResponseListSnapshots); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestListSnapshots) *types.ResponseListSnapshots); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseListSnapshots) @@ -64,8 +66,8 @@ func (_m *AppConnSnapshot) ListSnapshotsSync(_a0 types.RequestListSnapshots) (*t } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestListSnapshots) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, types.RequestListSnapshots) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -73,13 +75,13 @@ func (_m *AppConnSnapshot) ListSnapshotsSync(_a0 types.RequestListSnapshots) (*t return r0, r1 } -// LoadSnapshotChunkSync provides a mock function with given fields: _a0 -func (_m *AppConnSnapshot) LoadSnapshotChunkSync(_a0 types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { - ret := _m.Called(_a0) +// LoadSnapshotChunkSync provides a mock function with given fields: _a0, _a1 +func (_m *AppConnSnapshot) LoadSnapshotChunkSync(_a0 context.Context, _a1 types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponseLoadSnapshotChunk - if rf, ok := ret.Get(0).(func(types.RequestLoadSnapshotChunk) *types.ResponseLoadSnapshotChunk); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestLoadSnapshotChunk) *types.ResponseLoadSnapshotChunk); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseLoadSnapshotChunk) @@ -87,8 +89,8 @@ func (_m *AppConnSnapshot) LoadSnapshotChunkSync(_a0 types.RequestLoadSnapshotCh } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestLoadSnapshotChunk) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, types.RequestLoadSnapshotChunk) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -96,13 +98,13 @@ func (_m *AppConnSnapshot) LoadSnapshotChunkSync(_a0 types.RequestLoadSnapshotCh return r0, r1 } -// OfferSnapshotSync provides a mock function with given fields: _a0 -func (_m *AppConnSnapshot) OfferSnapshotSync(_a0 types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { - ret := _m.Called(_a0) +// OfferSnapshotSync provides a mock function with given fields: _a0, _a1 +func (_m *AppConnSnapshot) OfferSnapshotSync(_a0 context.Context, _a1 types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponseOfferSnapshot - if rf, ok := ret.Get(0).(func(types.RequestOfferSnapshot) *types.ResponseOfferSnapshot); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, types.RequestOfferSnapshot) *types.ResponseOfferSnapshot); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseOfferSnapshot) @@ -110,8 +112,8 @@ func (_m *AppConnSnapshot) OfferSnapshotSync(_a0 types.RequestOfferSnapshot) (*t } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestOfferSnapshot) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, types.RequestOfferSnapshot) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } diff --git a/rpc/core/abci.go b/rpc/core/abci.go index d1edfdfd7..65dcf13e2 100644 --- a/rpc/core/abci.go +++ b/rpc/core/abci.go @@ -17,7 +17,7 @@ func ABCIQuery( height int64, prove bool, ) (*ctypes.ResultABCIQuery, error) { - resQuery, err := env.ProxyAppQuery.QuerySync(abci.RequestQuery{ + resQuery, err := env.ProxyAppQuery.QuerySync(ctx.Context(), abci.RequestQuery{ Path: path, Data: data, Height: height, @@ -33,7 +33,7 @@ func ABCIQuery( // ABCIInfo gets some info about the application. // More: https://docs.tendermint.com/master/rpc/#/ABCI/abci_info func ABCIInfo(ctx *rpctypes.Context) (*ctypes.ResultABCIInfo, error) { - resInfo, err := env.ProxyAppQuery.InfoSync(proxy.RequestInfo) + resInfo, err := env.ProxyAppQuery.InfoSync(ctx.Context(), proxy.RequestInfo) if err != nil { return nil, err } diff --git a/rpc/core/mempool.go b/rpc/core/mempool.go index 79aa03bc5..48faceee2 100644 --- a/rpc/core/mempool.go +++ b/rpc/core/mempool.go @@ -20,7 +20,7 @@ import ( // CheckTx nor DeliverTx results. // More: https://docs.tendermint.com/master/rpc/#/Tx/broadcast_tx_async func BroadcastTxAsync(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) { - err := env.Mempool.CheckTx(tx, nil, mempl.TxInfo{}) + err := env.Mempool.CheckTx(tx, nil, mempl.TxInfo{Context: ctx.Context()}) if err != nil { return nil, err @@ -35,7 +35,7 @@ func BroadcastTxSync(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcas resCh := make(chan *abci.Response, 1) err := env.Mempool.CheckTx(tx, func(res *abci.Response) { resCh <- res - }, mempl.TxInfo{}) + }, mempl.TxInfo{Context: ctx.Context()}) if err != nil { return nil, err } @@ -81,7 +81,7 @@ func BroadcastTxCommit(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadc checkTxResCh := make(chan *abci.Response, 1) err = env.Mempool.CheckTx(tx, func(res *abci.Response) { checkTxResCh <- res - }, mempl.TxInfo{}) + }, mempl.TxInfo{Context: ctx.Context()}) if err != nil { env.Logger.Error("Error on broadcastTxCommit", "err", err) return nil, fmt.Errorf("error on broadcastTxCommit: %v", err) @@ -159,7 +159,7 @@ func NumUnconfirmedTxs(ctx *rpctypes.Context) (*ctypes.ResultUnconfirmedTxs, err // be added to the mempool either. // More: https://docs.tendermint.com/master/rpc/#/Tx/check_tx func CheckTx(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultCheckTx, error) { - res, err := env.ProxyAppMempool.CheckTxSync(abci.RequestCheckTx{Tx: tx}) + res, err := env.ProxyAppMempool.CheckTxSync(ctx.Context(), abci.RequestCheckTx{Tx: tx}) if err != nil { return nil, err } diff --git a/rpc/grpc/client_server.go b/rpc/grpc/client_server.go index 133eb53ff..8bed20605 100644 --- a/rpc/grpc/client_server.go +++ b/rpc/grpc/client_server.go @@ -1,9 +1,9 @@ package coregrpc import ( + "context" "net" - "golang.org/x/net/context" "google.golang.org/grpc" tmnet "github.com/tendermint/tendermint/libs/net" diff --git a/state/execution.go b/state/execution.go index 241c15e93..b8054fde2 100644 --- a/state/execution.go +++ b/state/execution.go @@ -1,6 +1,7 @@ package state import ( + "context" "errors" "fmt" "time" @@ -223,7 +224,7 @@ func (blockExec *BlockExecutor) Commit( } // Commit block, get hash back - res, err := blockExec.proxyApp.CommitSync() + res, err := blockExec.proxyApp.CommitSync(context.Background()) if err != nil { blockExec.logger.Error( "Client error during proxyAppConn.CommitSync", @@ -297,18 +298,22 @@ func execBlockOnProxyApp( byzVals = append(byzVals, evidence.ABCI()...) } + ctx := context.Background() + // Begin block var err error pbh := block.Header.ToProto() if pbh == nil { return nil, errors.New("nil header") } - abciResponses.BeginBlock, err = proxyAppConn.BeginBlockSync(abci.RequestBeginBlock{ - Hash: block.Hash(), - Header: *pbh, - LastCommitInfo: commitInfo, - ByzantineValidators: byzVals, - }) + abciResponses.BeginBlock, err = proxyAppConn.BeginBlockSync( + ctx, + abci.RequestBeginBlock{ + Hash: block.Hash(), + Header: *pbh, + LastCommitInfo: commitInfo, + ByzantineValidators: byzVals, + }) if err != nil { logger.Error("Error in proxyAppConn.BeginBlock", "err", err) return nil, err @@ -316,14 +321,14 @@ func execBlockOnProxyApp( // Run txs of block. for _, tx := range block.Txs { - proxyAppConn.DeliverTxAsync(abci.RequestDeliverTx{Tx: tx}) - if err := proxyAppConn.Error(); err != nil { + _, err = proxyAppConn.DeliverTxAsync(ctx, abci.RequestDeliverTx{Tx: tx}) + if err != nil { return nil, err } } // End block. - abciResponses.EndBlock, err = proxyAppConn.EndBlockSync(abci.RequestEndBlock{Height: block.Height}) + abciResponses.EndBlock, err = proxyAppConn.EndBlockSync(ctx, abci.RequestEndBlock{Height: block.Height}) if err != nil { logger.Error("Error in proxyAppConn.EndBlock", "err", err) return nil, err @@ -537,7 +542,7 @@ func ExecCommitBlock( return nil, err } // Commit block, get hash back - res, err := appConnConsensus.CommitSync() + res, err := appConnConsensus.CommitSync(context.Background()) if err != nil { logger.Error("Client error during proxyAppConn.CommitSync", "err", res) return nil, err diff --git a/statesync/reactor.go b/statesync/reactor.go index 0abd91cf1..2764698fd 100644 --- a/statesync/reactor.go +++ b/statesync/reactor.go @@ -1,6 +1,7 @@ package statesync import ( + "context" "errors" "sort" "time" @@ -161,7 +162,7 @@ func (r *Reactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) { case *ssproto.ChunkRequest: r.Logger.Debug("Received chunk request", "height", msg.Height, "format", msg.Format, "chunk", msg.Index, "peer", src.ID()) - resp, err := r.conn.LoadSnapshotChunkSync(abci.RequestLoadSnapshotChunk{ + resp, err := r.conn.LoadSnapshotChunkSync(context.Background(), abci.RequestLoadSnapshotChunk{ Height: msg.Height, Format: msg.Format, Chunk: msg.Index, @@ -214,7 +215,7 @@ func (r *Reactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) { // recentSnapshots fetches the n most recent snapshots from the app func (r *Reactor) recentSnapshots(n uint32) ([]*snapshot, error) { - resp, err := r.conn.ListSnapshotsSync(abci.RequestListSnapshots{}) + resp, err := r.conn.ListSnapshotsSync(context.Background(), abci.RequestListSnapshots{}) if err != nil { return nil, err } diff --git a/statesync/reactor_test.go b/statesync/reactor_test.go index 49d8376b8..72062ca9d 100644 --- a/statesync/reactor_test.go +++ b/statesync/reactor_test.go @@ -1,6 +1,7 @@ package statesync import ( + "context" "testing" "time" @@ -41,7 +42,7 @@ func TestReactor_Receive_ChunkRequest(t *testing.T) { t.Run(name, func(t *testing.T) { // Mock ABCI connection to return local snapshots conn := &proxymocks.AppConnSnapshot{} - conn.On("LoadSnapshotChunkSync", abci.RequestLoadSnapshotChunk{ + conn.On("LoadSnapshotChunkSync", context.Background(), abci.RequestLoadSnapshotChunk{ Height: tc.request.Height, Format: tc.request.Format, Chunk: tc.request.Index, @@ -120,7 +121,7 @@ func TestReactor_Receive_SnapshotsRequest(t *testing.T) { t.Run(name, func(t *testing.T) { // Mock ABCI connection to return local snapshots conn := &proxymocks.AppConnSnapshot{} - conn.On("ListSnapshotsSync", abci.RequestListSnapshots{}).Return(&abci.ResponseListSnapshots{ + conn.On("ListSnapshotsSync", context.Background(), abci.RequestListSnapshots{}).Return(&abci.ResponseListSnapshots{ Snapshots: tc.snapshots, }, nil) diff --git a/statesync/syncer.go b/statesync/syncer.go index 8bf0f7f7b..b4c3aa51f 100644 --- a/statesync/syncer.go +++ b/statesync/syncer.go @@ -277,7 +277,7 @@ func (s *syncer) Sync(snapshot *snapshot, chunks *chunkQueue) (sm.State, *types. func (s *syncer) offerSnapshot(snapshot *snapshot) error { s.logger.Info("Offering snapshot to ABCI app", "height", snapshot.Height, "format", snapshot.Format, "hash", fmt.Sprintf("%X", snapshot.Hash)) - resp, err := s.conn.OfferSnapshotSync(abci.RequestOfferSnapshot{ + resp, err := s.conn.OfferSnapshotSync(context.Background(), abci.RequestOfferSnapshot{ Snapshot: &abci.Snapshot{ Height: snapshot.Height, Format: snapshot.Format, @@ -319,7 +319,7 @@ func (s *syncer) applyChunks(chunks *chunkQueue) error { return fmt.Errorf("failed to fetch chunk: %w", err) } - resp, err := s.conn.ApplySnapshotChunkSync(abci.RequestApplySnapshotChunk{ + resp, err := s.conn.ApplySnapshotChunkSync(context.Background(), abci.RequestApplySnapshotChunk{ Index: chunk.Index, Chunk: chunk.Chunk, Sender: string(chunk.Sender), @@ -422,7 +422,7 @@ func (s *syncer) requestChunk(snapshot *snapshot, chunk uint32) { // verifyApp verifies the sync, checking the app hash and last block height. It returns the // app version, which should be returned as part of the initial state. func (s *syncer) verifyApp(snapshot *snapshot) (uint64, error) { - resp, err := s.connQuery.InfoSync(proxy.RequestInfo) + resp, err := s.connQuery.InfoSync(context.Background(), proxy.RequestInfo) if err != nil { return 0, fmt.Errorf("failed to query ABCI app for appHash: %w", err) } diff --git a/statesync/syncer_test.go b/statesync/syncer_test.go index c78509bfe..96459c26e 100644 --- a/statesync/syncer_test.go +++ b/statesync/syncer_test.go @@ -1,6 +1,7 @@ package statesync import ( + "context" "errors" "testing" "time" @@ -25,6 +26,8 @@ import ( "github.com/tendermint/tendermint/version" ) +var ctx = context.Background() + // Sets up a basic syncer that can be used to test OfferSnapshot requests func setupOfferSyncer(t *testing.T) (*syncer, *proxymocks.AppConnSnapshot) { connQuery := &proxymocks.AppConnQuery{} @@ -119,7 +122,7 @@ func TestSyncer_SyncAny(t *testing.T) { // We start a sync, with peers sending back chunks when requested. We first reject the snapshot // with height 2 format 2, and accept the snapshot at height 1. - connSnapshot.On("OfferSnapshotSync", abci.RequestOfferSnapshot{ + connSnapshot.On("OfferSnapshotSync", ctx, abci.RequestOfferSnapshot{ Snapshot: &abci.Snapshot{ Height: 2, Format: 2, @@ -128,7 +131,7 @@ func TestSyncer_SyncAny(t *testing.T) { }, AppHash: []byte("app_hash_2"), }).Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT_FORMAT}, nil) - connSnapshot.On("OfferSnapshotSync", abci.RequestOfferSnapshot{ + connSnapshot.On("OfferSnapshotSync", ctx, abci.RequestOfferSnapshot{ Snapshot: &abci.Snapshot{ Height: s.Height, Format: s.Format, @@ -143,14 +146,14 @@ func TestSyncer_SyncAny(t *testing.T) { chunkRequestsMtx := tmsync.Mutex{} onChunkRequest := func(args mock.Arguments) { pb, err := decodeMsg(args[1].([]byte)) - require.NoError(t, err) + assert.NoError(t, err) msg := pb.(*ssproto.ChunkRequest) - require.EqualValues(t, 1, msg.Height) - require.EqualValues(t, 1, msg.Format) - require.LessOrEqual(t, msg.Index, uint32(len(chunks))) + assert.EqualValues(t, 1, msg.Height) + assert.EqualValues(t, 1, msg.Format) + assert.LessOrEqual(t, msg.Index, uint32(len(chunks))) added, err := syncer.AddChunk(chunks[msg.Index]) - require.NoError(t, err) + assert.NoError(t, err) assert.True(t, added) chunkRequestsMtx.Lock() @@ -163,7 +166,7 @@ func TestSyncer_SyncAny(t *testing.T) { // The first time we're applying chunk 2 we tell it to retry the snapshot and discard chunk 1, // which should cause it to keep the existing chunk 0 and 2, and restart restoration from // beginning. We also wait for a little while, to exercise the retry logic in fetchChunks(). - connSnapshot.On("ApplySnapshotChunkSync", abci.RequestApplySnapshotChunk{ + connSnapshot.On("ApplySnapshotChunkSync", ctx, abci.RequestApplySnapshotChunk{ Index: 2, Chunk: []byte{1, 1, 2}, }).Once().Run(func(args mock.Arguments) { time.Sleep(2 * time.Second) }).Return( &abci.ResponseApplySnapshotChunk{ @@ -171,16 +174,16 @@ func TestSyncer_SyncAny(t *testing.T) { RefetchChunks: []uint32{1}, }, nil) - connSnapshot.On("ApplySnapshotChunkSync", abci.RequestApplySnapshotChunk{ + connSnapshot.On("ApplySnapshotChunkSync", ctx, abci.RequestApplySnapshotChunk{ Index: 0, Chunk: []byte{1, 1, 0}, }).Times(2).Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) - connSnapshot.On("ApplySnapshotChunkSync", abci.RequestApplySnapshotChunk{ + connSnapshot.On("ApplySnapshotChunkSync", ctx, abci.RequestApplySnapshotChunk{ Index: 1, Chunk: []byte{1, 1, 1}, }).Times(2).Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) - connSnapshot.On("ApplySnapshotChunkSync", abci.RequestApplySnapshotChunk{ + connSnapshot.On("ApplySnapshotChunkSync", ctx, abci.RequestApplySnapshotChunk{ Index: 2, Chunk: []byte{1, 1, 2}, }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) - connQuery.On("InfoSync", proxy.RequestInfo).Return(&abci.ResponseInfo{ + connQuery.On("InfoSync", ctx, proxy.RequestInfo).Return(&abci.ResponseInfo{ AppVersion: 9, LastBlockHeight: 1, LastBlockAppHash: []byte("app_hash"), @@ -220,7 +223,7 @@ func TestSyncer_SyncAny_abort(t *testing.T) { s := &snapshot{Height: 1, Format: 1, Chunks: 3, Hash: []byte{1, 2, 3}} _, err := syncer.AddSnapshot(simplePeer("id"), s) require.NoError(t, err) - connSnapshot.On("OfferSnapshotSync", abci.RequestOfferSnapshot{ + connSnapshot.On("OfferSnapshotSync", ctx, abci.RequestOfferSnapshot{ Snapshot: toABCI(s), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ABORT}, nil) @@ -243,15 +246,15 @@ func TestSyncer_SyncAny_reject(t *testing.T) { _, err = syncer.AddSnapshot(simplePeer("id"), s11) require.NoError(t, err) - connSnapshot.On("OfferSnapshotSync", abci.RequestOfferSnapshot{ + connSnapshot.On("OfferSnapshotSync", ctx, abci.RequestOfferSnapshot{ Snapshot: toABCI(s22), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT}, nil) - connSnapshot.On("OfferSnapshotSync", abci.RequestOfferSnapshot{ + connSnapshot.On("OfferSnapshotSync", ctx, abci.RequestOfferSnapshot{ Snapshot: toABCI(s12), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT}, nil) - connSnapshot.On("OfferSnapshotSync", abci.RequestOfferSnapshot{ + connSnapshot.On("OfferSnapshotSync", ctx, abci.RequestOfferSnapshot{ Snapshot: toABCI(s11), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT}, nil) @@ -274,11 +277,11 @@ func TestSyncer_SyncAny_reject_format(t *testing.T) { _, err = syncer.AddSnapshot(simplePeer("id"), s11) require.NoError(t, err) - connSnapshot.On("OfferSnapshotSync", abci.RequestOfferSnapshot{ + connSnapshot.On("OfferSnapshotSync", ctx, abci.RequestOfferSnapshot{ Snapshot: toABCI(s22), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT_FORMAT}, nil) - connSnapshot.On("OfferSnapshotSync", abci.RequestOfferSnapshot{ + connSnapshot.On("OfferSnapshotSync", ctx, abci.RequestOfferSnapshot{ Snapshot: toABCI(s11), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ABORT}, nil) @@ -312,11 +315,11 @@ func TestSyncer_SyncAny_reject_sender(t *testing.T) { _, err = syncer.AddSnapshot(peerC, sbc) require.NoError(t, err) - connSnapshot.On("OfferSnapshotSync", abci.RequestOfferSnapshot{ + connSnapshot.On("OfferSnapshotSync", ctx, abci.RequestOfferSnapshot{ Snapshot: toABCI(sbc), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT_SENDER}, nil) - connSnapshot.On("OfferSnapshotSync", abci.RequestOfferSnapshot{ + connSnapshot.On("OfferSnapshotSync", ctx, abci.RequestOfferSnapshot{ Snapshot: toABCI(sa), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT}, nil) @@ -332,7 +335,7 @@ func TestSyncer_SyncAny_abciError(t *testing.T) { s := &snapshot{Height: 1, Format: 1, Chunks: 3, Hash: []byte{1, 2, 3}} _, err := syncer.AddSnapshot(simplePeer("id"), s) require.NoError(t, err) - connSnapshot.On("OfferSnapshotSync", abci.RequestOfferSnapshot{ + connSnapshot.On("OfferSnapshotSync", ctx, abci.RequestOfferSnapshot{ Snapshot: toABCI(s), AppHash: []byte("app_hash"), }).Once().Return(nil, errBoom) @@ -364,7 +367,7 @@ func TestSyncer_offerSnapshot(t *testing.T) { t.Run(name, func(t *testing.T) { syncer, connSnapshot := setupOfferSyncer(t) s := &snapshot{Height: 1, Format: 1, Chunks: 3, Hash: []byte{1, 2, 3}, trustedAppHash: []byte("app_hash")} - connSnapshot.On("OfferSnapshotSync", abci.RequestOfferSnapshot{ + connSnapshot.On("OfferSnapshotSync", ctx, abci.RequestOfferSnapshot{ Snapshot: toABCI(s), AppHash: []byte("app_hash"), }).Return(&abci.ResponseOfferSnapshot{Result: tc.result}, tc.err) @@ -415,11 +418,11 @@ func TestSyncer_applyChunks_Results(t *testing.T) { _, err = chunks.Add(&chunk{Height: 1, Format: 1, Index: 0, Chunk: body}) require.NoError(t, err) - connSnapshot.On("ApplySnapshotChunkSync", abci.RequestApplySnapshotChunk{ + connSnapshot.On("ApplySnapshotChunkSync", ctx, abci.RequestApplySnapshotChunk{ Index: 0, Chunk: body, }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: tc.result}, tc.err) if tc.result == abci.ResponseApplySnapshotChunk_RETRY { - connSnapshot.On("ApplySnapshotChunkSync", abci.RequestApplySnapshotChunk{ + connSnapshot.On("ApplySnapshotChunkSync", ctx, abci.RequestApplySnapshotChunk{ Index: 0, Chunk: body, }).Once().Return(&abci.ResponseApplySnapshotChunk{ Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) @@ -473,13 +476,13 @@ func TestSyncer_applyChunks_RefetchChunks(t *testing.T) { require.NoError(t, err) // The first two chunks are accepted, before the last one asks for 1 to be refetched - connSnapshot.On("ApplySnapshotChunkSync", abci.RequestApplySnapshotChunk{ + connSnapshot.On("ApplySnapshotChunkSync", ctx, abci.RequestApplySnapshotChunk{ Index: 0, Chunk: []byte{0}, }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) - connSnapshot.On("ApplySnapshotChunkSync", abci.RequestApplySnapshotChunk{ + connSnapshot.On("ApplySnapshotChunkSync", ctx, abci.RequestApplySnapshotChunk{ Index: 1, Chunk: []byte{1}, }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) - connSnapshot.On("ApplySnapshotChunkSync", abci.RequestApplySnapshotChunk{ + connSnapshot.On("ApplySnapshotChunkSync", ctx, abci.RequestApplySnapshotChunk{ Index: 2, Chunk: []byte{2}, }).Once().Return(&abci.ResponseApplySnapshotChunk{ Result: tc.result, @@ -557,13 +560,13 @@ func TestSyncer_applyChunks_RejectSenders(t *testing.T) { require.NoError(t, err) // The first two chunks are accepted, before the last one asks for b sender to be rejected - connSnapshot.On("ApplySnapshotChunkSync", abci.RequestApplySnapshotChunk{ + connSnapshot.On("ApplySnapshotChunkSync", ctx, abci.RequestApplySnapshotChunk{ Index: 0, Chunk: []byte{0}, Sender: "a", }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) - connSnapshot.On("ApplySnapshotChunkSync", abci.RequestApplySnapshotChunk{ + connSnapshot.On("ApplySnapshotChunkSync", ctx, abci.RequestApplySnapshotChunk{ Index: 1, Chunk: []byte{1}, Sender: "b", }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) - connSnapshot.On("ApplySnapshotChunkSync", abci.RequestApplySnapshotChunk{ + connSnapshot.On("ApplySnapshotChunkSync", ctx, abci.RequestApplySnapshotChunk{ Index: 2, Chunk: []byte{2}, Sender: "c", }).Once().Return(&abci.ResponseApplySnapshotChunk{ Result: tc.result, @@ -572,7 +575,7 @@ func TestSyncer_applyChunks_RejectSenders(t *testing.T) { // On retry, the last chunk will be tried again, so we just accept it then. if tc.result == abci.ResponseApplySnapshotChunk_RETRY { - connSnapshot.On("ApplySnapshotChunkSync", abci.RequestApplySnapshotChunk{ + connSnapshot.On("ApplySnapshotChunkSync", ctx, abci.RequestApplySnapshotChunk{ Index: 2, Chunk: []byte{2}, Sender: "c", }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) } @@ -636,7 +639,7 @@ func TestSyncer_verifyApp(t *testing.T) { stateProvider := &mocks.StateProvider{} syncer := newSyncer(log.NewNopLogger(), connSnapshot, connQuery, stateProvider, "") - connQuery.On("InfoSync", proxy.RequestInfo).Return(tc.response, tc.err) + connQuery.On("InfoSync", ctx, proxy.RequestInfo).Return(tc.response, tc.err) version, err := syncer.verifyApp(s) unwrapped := errors.Unwrap(err) if unwrapped != nil { diff --git a/test/maverick/consensus/replay.go b/test/maverick/consensus/replay.go index bfec9e96d..9e393fbda 100644 --- a/test/maverick/consensus/replay.go +++ b/test/maverick/consensus/replay.go @@ -2,6 +2,7 @@ package consensus import ( "bytes" + "context" "fmt" "hash/crc32" "io" @@ -241,7 +242,7 @@ func (h *Handshaker) NBlocks() int { func (h *Handshaker) Handshake(proxyApp proxy.AppConns) error { // Handshake is done via ABCI Info on the query conn. - res, err := proxyApp.Query().InfoSync(proxy.RequestInfo) + res, err := proxyApp.Query().InfoSync(context.Background(), proxy.RequestInfo) if err != nil { return fmt.Errorf("error calling Info: %v", err) } @@ -316,7 +317,7 @@ func (h *Handshaker) ReplayBlocks( Validators: nextVals, AppStateBytes: h.genDoc.AppState, } - res, err := proxyApp.Consensus().InitChainSync(req) + res, err := proxyApp.Consensus().InitChainSync(context.Background(), req) if err != nil { return nil, err } diff --git a/test/maverick/node/node.go b/test/maverick/node/node.go index e1f41b6fb..f697fd7a1 100644 --- a/test/maverick/node/node.go +++ b/test/maverick/node/node.go @@ -482,7 +482,7 @@ func createTransport( connFilters, // ABCI query for address filtering. func(_ p2p.ConnSet, c net.Conn, _ []net.IP) error { - res, err := proxyApp.Query().QuerySync(abci.RequestQuery{ + res, err := proxyApp.Query().QuerySync(context.Background(), abci.RequestQuery{ Path: fmt.Sprintf("/p2p/filter/addr/%s", c.RemoteAddr().String()), }) if err != nil { @@ -500,7 +500,7 @@ func createTransport( peerFilters, // ABCI query for ID filtering. func(_ p2p.IPeerSet, p p2p.Peer) error { - res, err := proxyApp.Query().QuerySync(abci.RequestQuery{ + res, err := proxyApp.Query().QuerySync(context.Background(), abci.RequestQuery{ Path: fmt.Sprintf("/p2p/filter/id/%s", p.ID()), }) if err != nil {