diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4f0c7cf1d..f3f5cba1d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,7 +14,7 @@ jobs: strategy: fail-fast: false matrix: - part: ["00", "01", "02", "03"] + part: ["00", "01", "02", "03", "04", "05"] steps: - uses: actions/setup-go@v2 with: @@ -30,7 +30,7 @@ jobs: Makefile - name: Run Go Tests run: | - make test-group-${{ matrix.part }} NUM_SPLIT=4 + make test-group-${{ matrix.part }} NUM_SPLIT=6 if: env.GIT_DIFF - uses: actions/upload-artifact@v2 with: diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 4dbfc70b0..947bea24f 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -25,6 +25,7 @@ Special thanks to external contributors on this release: - [p2p] \#7035 Remove legacy P2P routing implementation and associated configuration options. (@tychoish) - [p2p] \#7265 Peer manager reduces peer score for each failed dial attempts for peers that have not successfully dialed. (@tychoish) + - [p2p] [\#7594](https://github.com/tendermint/tendermint/pull/7594) always advertise self, to enable mutual address discovery. (@altergui) - Go API @@ -59,6 +60,7 @@ Special thanks to external contributors on this release: - [pubsub] \#7319 Performance improvements for the event query API (@creachadair) - [node] \#7521 Define concrete type for seed node implementation (@spacech1mp) - [rpc] \#7612 paginate mempool /unconfirmed_txs rpc endpoint (@spacech1mp) +- [light] [\#7536](https://github.com/tendermint/tendermint/pull/7536) rpc /status call returns info about the light client (@jmalicevic) ### BUG FIXES diff --git a/DOCKER/Dockerfile b/DOCKER/Dockerfile index 0465bec09..2785d7e24 100644 --- a/DOCKER/Dockerfile +++ b/DOCKER/Dockerfile @@ -1,5 +1,5 @@ # stage 1 Generate Tendermint Binary -FROM golang:1.16-alpine as builder +FROM golang:1.17-alpine as builder RUN apk update && \ apk upgrade && \ apk --no-cache add make @@ -8,7 +8,7 @@ WORKDIR /tendermint RUN make build-linux # stage 2 -FROM golang:1.15-alpine +FROM golang:1.17-alpine LABEL maintainer="hello@tendermint.com" # Tendermint will be looking for the genesis file in /tendermint/config/genesis.json diff --git a/Makefile b/Makefile index 8956a7ebd..85c53e1e0 100644 --- a/Makefile +++ b/Makefile @@ -299,9 +299,11 @@ NUM_SPLIT ?= 4 $(BUILDDIR): mkdir -p $@ -# the format statement filters out all packages that don't have tests. +# The format statement filters out all packages that don't have tests. +# Note we need to check for both in-package tests (.TestGoFiles) and +# out-of-package tests (.XTestGoFiles). $(BUILDDIR)/packages.txt:$(GO_TEST_FILES) $(BUILDDIR) - go list -f "{{ if .TestGoFiles }}{{ .ImportPath }}{{ end }}" ./... | sort > $@ + go list -f "{{ if (or .TestGoFiles .XTestGoFiles) }}{{ .ImportPath }}{{ end }}" ./... | sort > $@ split-test-packages:$(BUILDDIR)/packages.txt split -d -n l/$(NUM_SPLIT) $< $<. diff --git a/abci/client/client.go b/abci/client/client.go index d588922f6..bb6ee8361 100644 --- a/abci/client/client.go +++ b/abci/client/client.go @@ -33,35 +33,24 @@ type Client interface { // 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) // 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) + Flush(context.Context) error + Echo(ctx context.Context, msg string) (*types.ResponseEcho, error) + Info(context.Context, types.RequestInfo) (*types.ResponseInfo, error) + DeliverTx(context.Context, types.RequestDeliverTx) (*types.ResponseDeliverTx, error) + CheckTx(context.Context, types.RequestCheckTx) (*types.ResponseCheckTx, error) + Query(context.Context, types.RequestQuery) (*types.ResponseQuery, error) + Commit(context.Context) (*types.ResponseCommit, error) + InitChain(context.Context, types.RequestInitChain) (*types.ResponseInitChain, error) + BeginBlock(context.Context, types.RequestBeginBlock) (*types.ResponseBeginBlock, error) + EndBlock(context.Context, types.RequestEndBlock) (*types.ResponseEndBlock, error) + ListSnapshots(context.Context, types.RequestListSnapshots) (*types.ResponseListSnapshots, error) + OfferSnapshot(context.Context, types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) + LoadSnapshotChunk(context.Context, types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) + ApplySnapshotChunk(context.Context, types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) } //---------------------------------------- diff --git a/abci/client/grpc_client.go b/abci/client/grpc_client.go index 10a794741..b10300cc7 100644 --- a/abci/client/grpc_client.go +++ b/abci/client/grpc_client.go @@ -183,16 +183,6 @@ func (cli *grpcClient) SetResponseCallback(resCb Callback) { //---------------------------------------- -// 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(ctx, req.GetEcho(), grpc.WaitForReady(true)) - if err != nil { - return nil, err - } - return cli.finishAsyncCall(ctx, req, &types.Response{Value: &types.Response_Echo{Echo: res}}) -} - // NOTE: call is synchronous, use ctx to break early if needed func (cli *grpcClient) FlushAsync(ctx context.Context) (*ReqRes, error) { req := types.ToRequestFlush() @@ -203,16 +193,6 @@ func (cli *grpcClient) FlushAsync(ctx context.Context) (*ReqRes, error) { return cli.finishAsyncCall(ctx, req, &types.Response{Value: &types.Response_Flush{Flush: res}}) } -// 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(ctx, req.GetInfo(), grpc.WaitForReady(true)) - if err != nil { - return nil, err - } - return cli.finishAsyncCall(ctx, req, &types.Response{Value: &types.Response_Info{Info: res}}) -} - // 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) @@ -233,106 +213,6 @@ func (cli *grpcClient) CheckTxAsync(ctx context.Context, params types.RequestChe return cli.finishAsyncCall(ctx, req, &types.Response{Value: &types.Response_CheckTx{CheckTx: res}}) } -// 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(ctx, req.GetQuery(), grpc.WaitForReady(true)) - if err != nil { - return nil, err - } - return cli.finishAsyncCall(ctx, req, &types.Response{Value: &types.Response_Query{Query: res}}) -} - -// 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(ctx, req.GetCommit(), grpc.WaitForReady(true)) - if err != nil { - return nil, err - } - return cli.finishAsyncCall(ctx, req, &types.Response{Value: &types.Response_Commit{Commit: res}}) -} - -// 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(ctx, req.GetInitChain(), grpc.WaitForReady(true)) - if err != nil { - return nil, err - } - return cli.finishAsyncCall(ctx, req, &types.Response{Value: &types.Response_InitChain{InitChain: res}}) -} - -// 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(ctx, req.GetBeginBlock(), grpc.WaitForReady(true)) - if err != nil { - return nil, err - } - return cli.finishAsyncCall(ctx, req, &types.Response{Value: &types.Response_BeginBlock{BeginBlock: res}}) -} - -// 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(ctx, req.GetEndBlock(), grpc.WaitForReady(true)) - if err != nil { - return nil, err - } - return cli.finishAsyncCall(ctx, req, &types.Response{Value: &types.Response_EndBlock{EndBlock: res}}) -} - -// 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(ctx, req.GetListSnapshots(), grpc.WaitForReady(true)) - if err != nil { - return nil, err - } - return cli.finishAsyncCall(ctx, req, &types.Response{Value: &types.Response_ListSnapshots{ListSnapshots: res}}) -} - -// 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(ctx, req.GetOfferSnapshot(), grpc.WaitForReady(true)) - if err != nil { - return nil, err - } - return cli.finishAsyncCall(ctx, req, &types.Response{Value: &types.Response_OfferSnapshot{OfferSnapshot: res}}) -} - -// 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(ctx, req.GetLoadSnapshotChunk(), grpc.WaitForReady(true)) - if err != nil { - return nil, err - } - return cli.finishAsyncCall(ctx, req, &types.Response{Value: &types.Response_LoadSnapshotChunk{LoadSnapshotChunk: res}}) -} - -// 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(ctx, req.GetApplySnapshotChunk(), grpc.WaitForReady(true)) - if err != nil { - return nil, err - } - 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(ctx context.Context, req *types.Request, res *types.Response) (*ReqRes, error) { @@ -376,30 +256,22 @@ func (cli *grpcClient) finishSyncCall(reqres *ReqRes) *types.Response { //---------------------------------------- -func (cli *grpcClient) FlushSync(ctx context.Context) error { - return nil +func (cli *grpcClient) Flush(ctx context.Context) error { return nil } + +func (cli *grpcClient) Echo(ctx context.Context, msg string) (*types.ResponseEcho, error) { + req := types.ToRequestEcho(msg) + return cli.client.Echo(ctx, req.GetEcho(), grpc.WaitForReady(true)) } -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( +func (cli *grpcClient) Info( ctx context.Context, - req types.RequestInfo, + params types.RequestInfo, ) (*types.ResponseInfo, error) { - reqres, err := cli.InfoAsync(ctx, req) - if err != nil { - return nil, err - } - return cli.finishSyncCall(reqres).GetInfo(), cli.Error() + req := types.ToRequestInfo(params) + return cli.client.Info(ctx, req.GetInfo(), grpc.WaitForReady(true)) } -func (cli *grpcClient) DeliverTxSync( +func (cli *grpcClient) DeliverTx( ctx context.Context, params types.RequestDeliverTx, ) (*types.ResponseDeliverTx, error) { @@ -411,7 +283,7 @@ func (cli *grpcClient) DeliverTxSync( return cli.finishSyncCall(reqres).GetDeliverTx(), cli.Error() } -func (cli *grpcClient) CheckTxSync( +func (cli *grpcClient) CheckTx( ctx context.Context, params types.RequestCheckTx, ) (*types.ResponseCheckTx, error) { @@ -423,103 +295,76 @@ func (cli *grpcClient) CheckTxSync( return cli.finishSyncCall(reqres).GetCheckTx(), cli.Error() } -func (cli *grpcClient) QuerySync( +func (cli *grpcClient) Query( ctx context.Context, - req types.RequestQuery, + params types.RequestQuery, ) (*types.ResponseQuery, error) { - reqres, err := cli.QueryAsync(ctx, req) - if err != nil { - return nil, err - } - return cli.finishSyncCall(reqres).GetQuery(), cli.Error() + req := types.ToRequestQuery(params) + return cli.client.Query(ctx, req.GetQuery(), grpc.WaitForReady(true)) } -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) Commit(ctx context.Context) (*types.ResponseCommit, error) { + req := types.ToRequestCommit() + return cli.client.Commit(ctx, req.GetCommit(), grpc.WaitForReady(true)) } -func (cli *grpcClient) InitChainSync( +func (cli *grpcClient) InitChain( 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() + req := types.ToRequestInitChain(params) + return cli.client.InitChain(ctx, req.GetInitChain(), grpc.WaitForReady(true)) } -func (cli *grpcClient) BeginBlockSync( +func (cli *grpcClient) BeginBlock( 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() + req := types.ToRequestBeginBlock(params) + return cli.client.BeginBlock(ctx, req.GetBeginBlock(), grpc.WaitForReady(true)) } -func (cli *grpcClient) EndBlockSync( +func (cli *grpcClient) EndBlock( 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() + req := types.ToRequestEndBlock(params) + return cli.client.EndBlock(ctx, req.GetEndBlock(), grpc.WaitForReady(true)) } -func (cli *grpcClient) ListSnapshotsSync( +func (cli *grpcClient) ListSnapshots( 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() + req := types.ToRequestListSnapshots(params) + return cli.client.ListSnapshots(ctx, req.GetListSnapshots(), grpc.WaitForReady(true)) } -func (cli *grpcClient) OfferSnapshotSync( +func (cli *grpcClient) OfferSnapshot( 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() + req := types.ToRequestOfferSnapshot(params) + return cli.client.OfferSnapshot(ctx, req.GetOfferSnapshot(), grpc.WaitForReady(true)) } -func (cli *grpcClient) LoadSnapshotChunkSync( +func (cli *grpcClient) LoadSnapshotChunk( ctx context.Context, params types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { - reqres, err := cli.LoadSnapshotChunkAsync(ctx, params) - if err != nil { - return nil, err - } - return cli.finishSyncCall(reqres).GetLoadSnapshotChunk(), cli.Error() + req := types.ToRequestLoadSnapshotChunk(params) + return cli.client.LoadSnapshotChunk(ctx, req.GetLoadSnapshotChunk(), grpc.WaitForReady(true)) } -func (cli *grpcClient) ApplySnapshotChunkSync( +func (cli *grpcClient) ApplySnapshotChunk( ctx context.Context, params types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { - reqres, err := cli.ApplySnapshotChunkAsync(ctx, params) - if err != nil { - return nil, err - } - return cli.finishSyncCall(reqres).GetApplySnapshotChunk(), cli.Error() + req := types.ToRequestApplySnapshotChunk(params) + return cli.client.ApplySnapshotChunk(ctx, req.GetApplySnapshotChunk(), grpc.WaitForReady(true)) } diff --git a/abci/client/local_client.go b/abci/client/local_client.go index 86e0e1d4c..1e9aeca3c 100644 --- a/abci/client/local_client.go +++ b/abci/client/local_client.go @@ -58,27 +58,6 @@ func (app *localClient) FlushAsync(ctx context.Context) (*ReqRes, error) { return newLocalReqRes(types.ToRequestFlush(), nil), nil } -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(ctx context.Context, req types.RequestInfo) (*ReqRes, error) { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.Info(req) - return app.callback( - types.ToRequestInfo(req), - types.ToResponseInfo(res), - ), nil -} - func (app *localClient) DeliverTxAsync(ctx context.Context, params types.RequestDeliverTx) (*ReqRes, error) { app.mtx.Lock() defer app.mtx.Unlock() @@ -101,122 +80,17 @@ func (app *localClient) CheckTxAsync(ctx context.Context, req types.RequestCheck ), nil } -func (app *localClient) QueryAsync(ctx context.Context, req types.RequestQuery) (*ReqRes, error) { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.Query(req) - return app.callback( - types.ToRequestQuery(req), - types.ToResponseQuery(res), - ), nil -} - -func (app *localClient) CommitAsync(ctx context.Context) (*ReqRes, error) { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.Commit() - return app.callback( - types.ToRequestCommit(), - types.ToResponseCommit(res), - ), nil -} - -func (app *localClient) InitChainAsync(ctx context.Context, req types.RequestInitChain) (*ReqRes, error) { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.InitChain(req) - return app.callback( - types.ToRequestInitChain(req), - types.ToResponseInitChain(res), - ), nil -} - -func (app *localClient) BeginBlockAsync(ctx context.Context, req types.RequestBeginBlock) (*ReqRes, error) { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.BeginBlock(req) - return app.callback( - types.ToRequestBeginBlock(req), - types.ToResponseBeginBlock(res), - ), nil -} - -func (app *localClient) EndBlockAsync(ctx context.Context, req types.RequestEndBlock) (*ReqRes, error) { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.EndBlock(req) - return app.callback( - types.ToRequestEndBlock(req), - types.ToResponseEndBlock(res), - ), nil -} - -func (app *localClient) ListSnapshotsAsync(ctx context.Context, req types.RequestListSnapshots) (*ReqRes, error) { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.ListSnapshots(req) - return app.callback( - types.ToRequestListSnapshots(req), - types.ToResponseListSnapshots(res), - ), nil -} - -func (app *localClient) OfferSnapshotAsync(ctx context.Context, req types.RequestOfferSnapshot) (*ReqRes, error) { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.OfferSnapshot(req) - return app.callback( - types.ToRequestOfferSnapshot(req), - types.ToResponseOfferSnapshot(res), - ), nil -} - -func (app *localClient) LoadSnapshotChunkAsync( - ctx context.Context, - req types.RequestLoadSnapshotChunk, -) (*ReqRes, error) { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.LoadSnapshotChunk(req) - return app.callback( - types.ToRequestLoadSnapshotChunk(req), - types.ToResponseLoadSnapshotChunk(res), - ), nil -} - -func (app *localClient) ApplySnapshotChunkAsync( - ctx context.Context, - req types.RequestApplySnapshotChunk, -) (*ReqRes, error) { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.ApplySnapshotChunk(req) - return app.callback( - types.ToRequestApplySnapshotChunk(req), - types.ToResponseApplySnapshotChunk(res), - ), nil -} - //------------------------------------------------------- -func (app *localClient) FlushSync(ctx context.Context) error { +func (app *localClient) Flush(ctx context.Context) error { return nil } -func (app *localClient) EchoSync(ctx context.Context, msg string) (*types.ResponseEcho, error) { +func (app *localClient) Echo(ctx context.Context, msg string) (*types.ResponseEcho, error) { return &types.ResponseEcho{Message: msg}, nil } -func (app *localClient) InfoSync(ctx context.Context, req types.RequestInfo) (*types.ResponseInfo, error) { +func (app *localClient) Info(ctx context.Context, req types.RequestInfo) (*types.ResponseInfo, error) { app.mtx.Lock() defer app.mtx.Unlock() @@ -224,7 +98,7 @@ func (app *localClient) InfoSync(ctx context.Context, req types.RequestInfo) (*t return &res, nil } -func (app *localClient) DeliverTxSync( +func (app *localClient) DeliverTx( ctx context.Context, req types.RequestDeliverTx, ) (*types.ResponseDeliverTx, error) { @@ -236,7 +110,7 @@ func (app *localClient) DeliverTxSync( return &res, nil } -func (app *localClient) CheckTxSync( +func (app *localClient) CheckTx( ctx context.Context, req types.RequestCheckTx, ) (*types.ResponseCheckTx, error) { @@ -247,7 +121,7 @@ func (app *localClient) CheckTxSync( return &res, nil } -func (app *localClient) QuerySync( +func (app *localClient) Query( ctx context.Context, req types.RequestQuery, ) (*types.ResponseQuery, error) { @@ -258,7 +132,7 @@ func (app *localClient) QuerySync( return &res, nil } -func (app *localClient) CommitSync(ctx context.Context) (*types.ResponseCommit, error) { +func (app *localClient) Commit(ctx context.Context) (*types.ResponseCommit, error) { app.mtx.Lock() defer app.mtx.Unlock() @@ -266,7 +140,7 @@ func (app *localClient) CommitSync(ctx context.Context) (*types.ResponseCommit, return &res, nil } -func (app *localClient) InitChainSync( +func (app *localClient) InitChain( ctx context.Context, req types.RequestInitChain, ) (*types.ResponseInitChain, error) { @@ -278,7 +152,7 @@ func (app *localClient) InitChainSync( return &res, nil } -func (app *localClient) BeginBlockSync( +func (app *localClient) BeginBlock( ctx context.Context, req types.RequestBeginBlock, ) (*types.ResponseBeginBlock, error) { @@ -290,7 +164,7 @@ func (app *localClient) BeginBlockSync( return &res, nil } -func (app *localClient) EndBlockSync( +func (app *localClient) EndBlock( ctx context.Context, req types.RequestEndBlock, ) (*types.ResponseEndBlock, error) { @@ -302,7 +176,7 @@ func (app *localClient) EndBlockSync( return &res, nil } -func (app *localClient) ListSnapshotsSync( +func (app *localClient) ListSnapshots( ctx context.Context, req types.RequestListSnapshots, ) (*types.ResponseListSnapshots, error) { @@ -314,7 +188,7 @@ func (app *localClient) ListSnapshotsSync( return &res, nil } -func (app *localClient) OfferSnapshotSync( +func (app *localClient) OfferSnapshot( ctx context.Context, req types.RequestOfferSnapshot, ) (*types.ResponseOfferSnapshot, error) { @@ -326,7 +200,7 @@ func (app *localClient) OfferSnapshotSync( return &res, nil } -func (app *localClient) LoadSnapshotChunkSync( +func (app *localClient) LoadSnapshotChunk( ctx context.Context, req types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { @@ -337,7 +211,7 @@ func (app *localClient) LoadSnapshotChunkSync( return &res, nil } -func (app *localClient) ApplySnapshotChunkSync( +func (app *localClient) ApplySnapshotChunk( ctx context.Context, req types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { diff --git a/abci/client/mocks/client.go b/abci/client/mocks/client.go index e727fd544..f741066c0 100644 --- a/abci/client/mocks/client.go +++ b/abci/client/mocks/client.go @@ -17,31 +17,8 @@ type Client struct { mock.Mock } -// ApplySnapshotChunkAsync provides a mock function with given fields: _a0, _a1 -func (_m *Client) ApplySnapshotChunkAsync(_a0 context.Context, _a1 types.RequestApplySnapshotChunk) (*abciclient.ReqRes, error) { - ret := _m.Called(_a0, _a1) - - var r0 *abciclient.ReqRes - if rf, ok := ret.Get(0).(func(context.Context, types.RequestApplySnapshotChunk) *abciclient.ReqRes); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abciclient.ReqRes) - } - } - - 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, _a1 -func (_m *Client) ApplySnapshotChunkSync(_a0 context.Context, _a1 types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { +// ApplySnapshotChunk provides a mock function with given fields: _a0, _a1 +func (_m *Client) ApplySnapshotChunk(_a0 context.Context, _a1 types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseApplySnapshotChunk @@ -63,31 +40,8 @@ func (_m *Client) ApplySnapshotChunkSync(_a0 context.Context, _a1 types.RequestA return r0, r1 } -// BeginBlockAsync provides a mock function with given fields: _a0, _a1 -func (_m *Client) BeginBlockAsync(_a0 context.Context, _a1 types.RequestBeginBlock) (*abciclient.ReqRes, error) { - ret := _m.Called(_a0, _a1) - - var r0 *abciclient.ReqRes - if rf, ok := ret.Get(0).(func(context.Context, types.RequestBeginBlock) *abciclient.ReqRes); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abciclient.ReqRes) - } - } - - 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, _a1 -func (_m *Client) BeginBlockSync(_a0 context.Context, _a1 types.RequestBeginBlock) (*types.ResponseBeginBlock, error) { +// BeginBlock provides a mock function with given fields: _a0, _a1 +func (_m *Client) BeginBlock(_a0 context.Context, _a1 types.RequestBeginBlock) (*types.ResponseBeginBlock, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseBeginBlock @@ -109,6 +63,29 @@ func (_m *Client) BeginBlockSync(_a0 context.Context, _a1 types.RequestBeginBloc return r0, r1 } +// CheckTx provides a mock function with given fields: _a0, _a1 +func (_m *Client) CheckTx(_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(context.Context, types.RequestCheckTx) *types.ResponseCheckTx); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseCheckTx) + } + } + + 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 +} + // CheckTxAsync provides a mock function with given fields: _a0, _a1 func (_m *Client) CheckTxAsync(_a0 context.Context, _a1 types.RequestCheckTx) (*abciclient.ReqRes, error) { ret := _m.Called(_a0, _a1) @@ -132,54 +109,8 @@ func (_m *Client) CheckTxAsync(_a0 context.Context, _a1 types.RequestCheckTx) (* return r0, r1 } -// 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(context.Context, types.RequestCheckTx) *types.ResponseCheckTx); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.ResponseCheckTx) - } - } - - 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 -} - -// CommitAsync provides a mock function with given fields: _a0 -func (_m *Client) CommitAsync(_a0 context.Context) (*abciclient.ReqRes, error) { - ret := _m.Called(_a0) - - var r0 *abciclient.ReqRes - if rf, ok := ret.Get(0).(func(context.Context) *abciclient.ReqRes); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abciclient.ReqRes) - } - } - - 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 -} - -// CommitSync provides a mock function with given fields: _a0 -func (_m *Client) CommitSync(_a0 context.Context) (*types.ResponseCommit, error) { +// Commit provides a mock function with given fields: _a0 +func (_m *Client) Commit(_a0 context.Context) (*types.ResponseCommit, error) { ret := _m.Called(_a0) var r0 *types.ResponseCommit @@ -201,6 +132,29 @@ func (_m *Client) CommitSync(_a0 context.Context) (*types.ResponseCommit, error) return r0, r1 } +// DeliverTx provides a mock function with given fields: _a0, _a1 +func (_m *Client) DeliverTx(_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(context.Context, types.RequestDeliverTx) *types.ResponseDeliverTx); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseDeliverTx) + } + } + + 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 +} + // DeliverTxAsync provides a mock function with given fields: _a0, _a1 func (_m *Client) DeliverTxAsync(_a0 context.Context, _a1 types.RequestDeliverTx) (*abciclient.ReqRes, error) { ret := _m.Called(_a0, _a1) @@ -224,54 +178,8 @@ func (_m *Client) DeliverTxAsync(_a0 context.Context, _a1 types.RequestDeliverTx return r0, r1 } -// 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(context.Context, types.RequestDeliverTx) *types.ResponseDeliverTx); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.ResponseDeliverTx) - } - } - - 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 -} - -// EchoAsync provides a mock function with given fields: ctx, msg -func (_m *Client) EchoAsync(ctx context.Context, msg string) (*abciclient.ReqRes, error) { - ret := _m.Called(ctx, msg) - - var r0 *abciclient.ReqRes - if rf, ok := ret.Get(0).(func(context.Context, string) *abciclient.ReqRes); ok { - r0 = rf(ctx, msg) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abciclient.ReqRes) - } - } - - 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: ctx, msg -func (_m *Client) EchoSync(ctx context.Context, msg string) (*types.ResponseEcho, error) { +// Echo provides a mock function with given fields: ctx, msg +func (_m *Client) Echo(ctx context.Context, msg string) (*types.ResponseEcho, error) { ret := _m.Called(ctx, msg) var r0 *types.ResponseEcho @@ -293,31 +201,8 @@ func (_m *Client) EchoSync(ctx context.Context, msg string) (*types.ResponseEcho return r0, r1 } -// EndBlockAsync provides a mock function with given fields: _a0, _a1 -func (_m *Client) EndBlockAsync(_a0 context.Context, _a1 types.RequestEndBlock) (*abciclient.ReqRes, error) { - ret := _m.Called(_a0, _a1) - - var r0 *abciclient.ReqRes - if rf, ok := ret.Get(0).(func(context.Context, types.RequestEndBlock) *abciclient.ReqRes); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abciclient.ReqRes) - } - } - - 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, _a1 -func (_m *Client) EndBlockSync(_a0 context.Context, _a1 types.RequestEndBlock) (*types.ResponseEndBlock, error) { +// EndBlock provides a mock function with given fields: _a0, _a1 +func (_m *Client) EndBlock(_a0 context.Context, _a1 types.RequestEndBlock) (*types.ResponseEndBlock, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseEndBlock @@ -353,6 +238,20 @@ func (_m *Client) Error() error { return r0 } +// Flush provides a mock function with given fields: _a0 +func (_m *Client) Flush(_a0 context.Context) error { + ret := _m.Called(_a0) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // FlushAsync provides a mock function with given fields: _a0 func (_m *Client) FlushAsync(_a0 context.Context) (*abciclient.ReqRes, error) { ret := _m.Called(_a0) @@ -376,45 +275,8 @@ func (_m *Client) FlushAsync(_a0 context.Context) (*abciclient.ReqRes, error) { return r0, r1 } -// FlushSync provides a mock function with given fields: _a0 -func (_m *Client) FlushSync(_a0 context.Context) error { - ret := _m.Called(_a0) - - 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) (*abciclient.ReqRes, error) { - ret := _m.Called(_a0, _a1) - - var r0 *abciclient.ReqRes - if rf, ok := ret.Get(0).(func(context.Context, types.RequestInfo) *abciclient.ReqRes); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abciclient.ReqRes) - } - } - - 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 -} - -// InfoSync provides a mock function with given fields: _a0, _a1 -func (_m *Client) InfoSync(_a0 context.Context, _a1 types.RequestInfo) (*types.ResponseInfo, error) { +// Info provides a mock function with given fields: _a0, _a1 +func (_m *Client) Info(_a0 context.Context, _a1 types.RequestInfo) (*types.ResponseInfo, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseInfo @@ -436,31 +298,8 @@ func (_m *Client) InfoSync(_a0 context.Context, _a1 types.RequestInfo) (*types.R return r0, r1 } -// InitChainAsync provides a mock function with given fields: _a0, _a1 -func (_m *Client) InitChainAsync(_a0 context.Context, _a1 types.RequestInitChain) (*abciclient.ReqRes, error) { - ret := _m.Called(_a0, _a1) - - var r0 *abciclient.ReqRes - if rf, ok := ret.Get(0).(func(context.Context, types.RequestInitChain) *abciclient.ReqRes); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abciclient.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) { +// InitChain provides a mock function with given fields: _a0, _a1 +func (_m *Client) InitChain(_a0 context.Context, _a1 types.RequestInitChain) (*types.ResponseInitChain, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseInitChain @@ -496,31 +335,8 @@ func (_m *Client) IsRunning() bool { return r0 } -// ListSnapshotsAsync provides a mock function with given fields: _a0, _a1 -func (_m *Client) ListSnapshotsAsync(_a0 context.Context, _a1 types.RequestListSnapshots) (*abciclient.ReqRes, error) { - ret := _m.Called(_a0, _a1) - - var r0 *abciclient.ReqRes - if rf, ok := ret.Get(0).(func(context.Context, types.RequestListSnapshots) *abciclient.ReqRes); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abciclient.ReqRes) - } - } - - 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, _a1 -func (_m *Client) ListSnapshotsSync(_a0 context.Context, _a1 types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { +// ListSnapshots provides a mock function with given fields: _a0, _a1 +func (_m *Client) ListSnapshots(_a0 context.Context, _a1 types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseListSnapshots @@ -542,31 +358,8 @@ func (_m *Client) ListSnapshotsSync(_a0 context.Context, _a1 types.RequestListSn return r0, r1 } -// LoadSnapshotChunkAsync provides a mock function with given fields: _a0, _a1 -func (_m *Client) LoadSnapshotChunkAsync(_a0 context.Context, _a1 types.RequestLoadSnapshotChunk) (*abciclient.ReqRes, error) { - ret := _m.Called(_a0, _a1) - - var r0 *abciclient.ReqRes - if rf, ok := ret.Get(0).(func(context.Context, types.RequestLoadSnapshotChunk) *abciclient.ReqRes); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abciclient.ReqRes) - } - } - - 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, _a1 -func (_m *Client) LoadSnapshotChunkSync(_a0 context.Context, _a1 types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { +// LoadSnapshotChunk provides a mock function with given fields: _a0, _a1 +func (_m *Client) LoadSnapshotChunk(_a0 context.Context, _a1 types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseLoadSnapshotChunk @@ -588,31 +381,8 @@ func (_m *Client) LoadSnapshotChunkSync(_a0 context.Context, _a1 types.RequestLo return r0, r1 } -// OfferSnapshotAsync provides a mock function with given fields: _a0, _a1 -func (_m *Client) OfferSnapshotAsync(_a0 context.Context, _a1 types.RequestOfferSnapshot) (*abciclient.ReqRes, error) { - ret := _m.Called(_a0, _a1) - - var r0 *abciclient.ReqRes - if rf, ok := ret.Get(0).(func(context.Context, types.RequestOfferSnapshot) *abciclient.ReqRes); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abciclient.ReqRes) - } - } - - 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, _a1 -func (_m *Client) OfferSnapshotSync(_a0 context.Context, _a1 types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { +// OfferSnapshot provides a mock function with given fields: _a0, _a1 +func (_m *Client) OfferSnapshot(_a0 context.Context, _a1 types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseOfferSnapshot @@ -634,31 +404,8 @@ func (_m *Client) OfferSnapshotSync(_a0 context.Context, _a1 types.RequestOfferS return r0, r1 } -// QueryAsync provides a mock function with given fields: _a0, _a1 -func (_m *Client) QueryAsync(_a0 context.Context, _a1 types.RequestQuery) (*abciclient.ReqRes, error) { - ret := _m.Called(_a0, _a1) - - var r0 *abciclient.ReqRes - if rf, ok := ret.Get(0).(func(context.Context, types.RequestQuery) *abciclient.ReqRes); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abciclient.ReqRes) - } - } - - 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, _a1 -func (_m *Client) QuerySync(_a0 context.Context, _a1 types.RequestQuery) (*types.ResponseQuery, error) { +// Query provides a mock function with given fields: _a0, _a1 +func (_m *Client) Query(_a0 context.Context, _a1 types.RequestQuery) (*types.ResponseQuery, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseQuery diff --git a/abci/client/socket_client.go b/abci/client/socket_client.go index b619edde2..2381c478a 100644 --- a/abci/client/socket_client.go +++ b/abci/client/socket_client.go @@ -222,18 +222,10 @@ func (cli *socketClient) didRecvResponse(res *types.Response) error { //---------------------------------------- -func (cli *socketClient) EchoAsync(ctx context.Context, msg string) (*ReqRes, error) { - return cli.queueRequestAsync(ctx, types.ToRequestEcho(msg)) -} - func (cli *socketClient) FlushAsync(ctx context.Context) (*ReqRes, error) { return cli.queueRequestAsync(ctx, types.ToRequestFlush()) } -func (cli *socketClient) InfoAsync(ctx context.Context, req types.RequestInfo) (*ReqRes, error) { - return cli.queueRequestAsync(ctx, types.ToRequestInfo(req)) -} - func (cli *socketClient) DeliverTxAsync(ctx context.Context, req types.RequestDeliverTx) (*ReqRes, error) { return cli.queueRequestAsync(ctx, types.ToRequestDeliverTx(req)) } @@ -242,51 +234,9 @@ func (cli *socketClient) CheckTxAsync(ctx context.Context, req types.RequestChec return cli.queueRequestAsync(ctx, types.ToRequestCheckTx(req)) } -func (cli *socketClient) QueryAsync(ctx context.Context, req types.RequestQuery) (*ReqRes, error) { - return cli.queueRequestAsync(ctx, types.ToRequestQuery(req)) -} - -func (cli *socketClient) CommitAsync(ctx context.Context) (*ReqRes, error) { - return cli.queueRequestAsync(ctx, types.ToRequestCommit()) -} - -func (cli *socketClient) InitChainAsync(ctx context.Context, req types.RequestInitChain) (*ReqRes, error) { - return cli.queueRequestAsync(ctx, types.ToRequestInitChain(req)) -} - -func (cli *socketClient) BeginBlockAsync(ctx context.Context, req types.RequestBeginBlock) (*ReqRes, error) { - return cli.queueRequestAsync(ctx, types.ToRequestBeginBlock(req)) -} - -func (cli *socketClient) EndBlockAsync(ctx context.Context, req types.RequestEndBlock) (*ReqRes, error) { - return cli.queueRequestAsync(ctx, types.ToRequestEndBlock(req)) -} - -func (cli *socketClient) ListSnapshotsAsync(ctx context.Context, req types.RequestListSnapshots) (*ReqRes, error) { - return cli.queueRequestAsync(ctx, types.ToRequestListSnapshots(req)) -} - -func (cli *socketClient) OfferSnapshotAsync(ctx context.Context, req types.RequestOfferSnapshot) (*ReqRes, error) { - return cli.queueRequestAsync(ctx, types.ToRequestOfferSnapshot(req)) -} - -func (cli *socketClient) LoadSnapshotChunkAsync( - ctx context.Context, - req types.RequestLoadSnapshotChunk, -) (*ReqRes, error) { - return cli.queueRequestAsync(ctx, types.ToRequestLoadSnapshotChunk(req)) -} - -func (cli *socketClient) ApplySnapshotChunkAsync( - ctx context.Context, - req types.RequestApplySnapshotChunk, -) (*ReqRes, error) { - return cli.queueRequestAsync(ctx, types.ToRequestApplySnapshotChunk(req)) -} - //---------------------------------------- -func (cli *socketClient) FlushSync(ctx context.Context) error { +func (cli *socketClient) Flush(ctx context.Context) error { reqRes, err := cli.queueRequest(ctx, types.ToRequestFlush(), true) if err != nil { return queueErr(err) @@ -311,143 +261,143 @@ func (cli *socketClient) FlushSync(ctx context.Context) error { } } -func (cli *socketClient) EchoSync(ctx context.Context, msg string) (*types.ResponseEcho, error) { - reqres, err := cli.queueRequestAndFlushSync(ctx, types.ToRequestEcho(msg)) +func (cli *socketClient) Echo(ctx context.Context, msg string) (*types.ResponseEcho, error) { + reqres, err := cli.queueRequestAndFlush(ctx, types.ToRequestEcho(msg)) if err != nil { return nil, err } return reqres.Response.GetEcho(), nil } -func (cli *socketClient) InfoSync( +func (cli *socketClient) Info( ctx context.Context, req types.RequestInfo, ) (*types.ResponseInfo, error) { - reqres, err := cli.queueRequestAndFlushSync(ctx, types.ToRequestInfo(req)) + reqres, err := cli.queueRequestAndFlush(ctx, types.ToRequestInfo(req)) if err != nil { return nil, err } return reqres.Response.GetInfo(), nil } -func (cli *socketClient) DeliverTxSync( +func (cli *socketClient) DeliverTx( ctx context.Context, req types.RequestDeliverTx, ) (*types.ResponseDeliverTx, error) { - reqres, err := cli.queueRequestAndFlushSync(ctx, types.ToRequestDeliverTx(req)) + reqres, err := cli.queueRequestAndFlush(ctx, types.ToRequestDeliverTx(req)) if err != nil { return nil, err } return reqres.Response.GetDeliverTx(), nil } -func (cli *socketClient) CheckTxSync( +func (cli *socketClient) CheckTx( ctx context.Context, req types.RequestCheckTx, ) (*types.ResponseCheckTx, error) { - reqres, err := cli.queueRequestAndFlushSync(ctx, types.ToRequestCheckTx(req)) + reqres, err := cli.queueRequestAndFlush(ctx, types.ToRequestCheckTx(req)) if err != nil { return nil, err } return reqres.Response.GetCheckTx(), nil } -func (cli *socketClient) QuerySync( +func (cli *socketClient) Query( ctx context.Context, req types.RequestQuery, ) (*types.ResponseQuery, error) { - reqres, err := cli.queueRequestAndFlushSync(ctx, types.ToRequestQuery(req)) + reqres, err := cli.queueRequestAndFlush(ctx, types.ToRequestQuery(req)) if err != nil { return nil, err } return reqres.Response.GetQuery(), nil } -func (cli *socketClient) CommitSync(ctx context.Context) (*types.ResponseCommit, error) { - reqres, err := cli.queueRequestAndFlushSync(ctx, types.ToRequestCommit()) +func (cli *socketClient) Commit(ctx context.Context) (*types.ResponseCommit, error) { + reqres, err := cli.queueRequestAndFlush(ctx, types.ToRequestCommit()) if err != nil { return nil, err } return reqres.Response.GetCommit(), nil } -func (cli *socketClient) InitChainSync( +func (cli *socketClient) InitChain( ctx context.Context, req types.RequestInitChain, ) (*types.ResponseInitChain, error) { - reqres, err := cli.queueRequestAndFlushSync(ctx, types.ToRequestInitChain(req)) + reqres, err := cli.queueRequestAndFlush(ctx, types.ToRequestInitChain(req)) if err != nil { return nil, err } return reqres.Response.GetInitChain(), nil } -func (cli *socketClient) BeginBlockSync( +func (cli *socketClient) BeginBlock( ctx context.Context, req types.RequestBeginBlock, ) (*types.ResponseBeginBlock, error) { - reqres, err := cli.queueRequestAndFlushSync(ctx, types.ToRequestBeginBlock(req)) + reqres, err := cli.queueRequestAndFlush(ctx, types.ToRequestBeginBlock(req)) if err != nil { return nil, err } return reqres.Response.GetBeginBlock(), nil } -func (cli *socketClient) EndBlockSync( +func (cli *socketClient) EndBlock( ctx context.Context, req types.RequestEndBlock, ) (*types.ResponseEndBlock, error) { - reqres, err := cli.queueRequestAndFlushSync(ctx, types.ToRequestEndBlock(req)) + reqres, err := cli.queueRequestAndFlush(ctx, types.ToRequestEndBlock(req)) if err != nil { return nil, err } return reqres.Response.GetEndBlock(), nil } -func (cli *socketClient) ListSnapshotsSync( +func (cli *socketClient) ListSnapshots( ctx context.Context, req types.RequestListSnapshots, ) (*types.ResponseListSnapshots, error) { - reqres, err := cli.queueRequestAndFlushSync(ctx, types.ToRequestListSnapshots(req)) + reqres, err := cli.queueRequestAndFlush(ctx, types.ToRequestListSnapshots(req)) if err != nil { return nil, err } return reqres.Response.GetListSnapshots(), nil } -func (cli *socketClient) OfferSnapshotSync( +func (cli *socketClient) OfferSnapshot( ctx context.Context, req types.RequestOfferSnapshot, ) (*types.ResponseOfferSnapshot, error) { - reqres, err := cli.queueRequestAndFlushSync(ctx, types.ToRequestOfferSnapshot(req)) + reqres, err := cli.queueRequestAndFlush(ctx, types.ToRequestOfferSnapshot(req)) if err != nil { return nil, err } return reqres.Response.GetOfferSnapshot(), nil } -func (cli *socketClient) LoadSnapshotChunkSync( +func (cli *socketClient) LoadSnapshotChunk( ctx context.Context, req types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { - reqres, err := cli.queueRequestAndFlushSync(ctx, types.ToRequestLoadSnapshotChunk(req)) + reqres, err := cli.queueRequestAndFlush(ctx, types.ToRequestLoadSnapshotChunk(req)) if err != nil { return nil, err } return reqres.Response.GetLoadSnapshotChunk(), nil } -func (cli *socketClient) ApplySnapshotChunkSync( +func (cli *socketClient) ApplySnapshotChunk( ctx context.Context, req types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { - reqres, err := cli.queueRequestAndFlushSync(ctx, types.ToRequestApplySnapshotChunk(req)) + reqres, err := cli.queueRequestAndFlush(ctx, types.ToRequestApplySnapshotChunk(req)) if err != nil { return nil, err } @@ -497,7 +447,7 @@ func (cli *socketClient) queueRequestAsync( return reqres, cli.Error() } -func (cli *socketClient) queueRequestAndFlushSync( +func (cli *socketClient) queueRequestAndFlush( ctx context.Context, req *types.Request, ) (*ReqRes, error) { @@ -507,7 +457,7 @@ func (cli *socketClient) queueRequestAndFlushSync( return nil, queueErr(err) } - if err := cli.FlushSync(ctx); err != nil { + if err := cli.Flush(ctx); err != nil { return nil, err } diff --git a/abci/client/socket_client_test.go b/abci/client/socket_client_test.go index ae060cead..556f98566 100644 --- a/abci/client/socket_client_test.go +++ b/abci/client/socket_client_test.go @@ -23,20 +23,20 @@ func TestProperSyncCalls(t *testing.T) { defer cancel() app := slowApp{} - logger := log.NewTestingLogger(t) + logger := log.NewNopLogger() _, c := setupClientServer(ctx, t, logger, app) resp := make(chan error, 1) go func() { - // This is BeginBlockSync unrolled.... - reqres, err := c.BeginBlockAsync(ctx, types.RequestBeginBlock{}) + rsp, err := c.BeginBlock(ctx, types.RequestBeginBlock{}) assert.NoError(t, err) - err = c.FlushSync(ctx) - assert.NoError(t, err) - res := reqres.Response.GetBeginBlock() - assert.NotNil(t, res) - resp <- c.Error() + assert.NoError(t, c.Flush(ctx)) + assert.NotNil(t, rsp) + select { + case <-ctx.Done(): + case resp <- c.Error(): + } }() select { diff --git a/abci/cmd/abci-cli/abci-cli.go b/abci/cmd/abci-cli/abci-cli.go index acf7e6096..eef194d4a 100644 --- a/abci/cmd/abci-cli/abci-cli.go +++ b/abci/cmd/abci-cli/abci-cli.go @@ -442,7 +442,7 @@ func cmdEcho(cmd *cobra.Command, args []string) error { if len(args) > 0 { msg = args[0] } - res, err := client.EchoSync(cmd.Context(), msg) + res, err := client.Echo(cmd.Context(), msg) if err != nil { return err } @@ -460,7 +460,7 @@ func cmdInfo(cmd *cobra.Command, args []string) error { if len(args) == 1 { version = args[0] } - res, err := client.InfoSync(cmd.Context(), types.RequestInfo{Version: version}) + res, err := client.Info(cmd.Context(), types.RequestInfo{Version: version}) if err != nil { return err } @@ -485,7 +485,7 @@ func cmdDeliverTx(cmd *cobra.Command, args []string) error { if err != nil { return err } - res, err := client.DeliverTxSync(cmd.Context(), types.RequestDeliverTx{Tx: txBytes}) + res, err := client.DeliverTx(cmd.Context(), types.RequestDeliverTx{Tx: txBytes}) if err != nil { return err } @@ -511,7 +511,7 @@ func cmdCheckTx(cmd *cobra.Command, args []string) error { if err != nil { return err } - res, err := client.CheckTxSync(cmd.Context(), types.RequestCheckTx{Tx: txBytes}) + res, err := client.CheckTx(cmd.Context(), types.RequestCheckTx{Tx: txBytes}) if err != nil { return err } @@ -526,7 +526,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(cmd.Context()) + res, err := client.Commit(cmd.Context()) if err != nil { return err } @@ -551,7 +551,7 @@ func cmdQuery(cmd *cobra.Command, args []string) error { return err } - resQuery, err := client.QuerySync(cmd.Context(), types.RequestQuery{ + resQuery, err := client.Query(cmd.Context(), types.RequestQuery{ Data: queryBytes, Path: flagPath, Height: int64(flagHeight), diff --git a/abci/example/example_test.go b/abci/example/example_test.go index 9a6bbe45e..99c7cc35c 100644 --- a/abci/example/example_test.go +++ b/abci/example/example_test.go @@ -112,7 +112,7 @@ func testStream(ctx context.Context, t *testing.T, logger log.Logger, app types. // Sometimes send flush messages if counter%128 == 0 { - err = client.FlushSync(ctx) + err = client.Flush(ctx) require.NoError(t, err) } } diff --git a/abci/example/kvstore/kvstore_test.go b/abci/example/kvstore/kvstore_test.go index b210fecc4..0c104f6d7 100644 --- a/abci/example/kvstore/kvstore_test.go +++ b/abci/example/kvstore/kvstore_test.go @@ -330,23 +330,23 @@ func runClientTests(ctx context.Context, t *testing.T, client abciclient.Client) } func testClient(ctx context.Context, t *testing.T, app abciclient.Client, tx []byte, key, value string) { - ar, err := app.DeliverTxSync(ctx, types.RequestDeliverTx{Tx: tx}) + ar, err := app.DeliverTx(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(ctx, types.RequestDeliverTx{Tx: tx}) + ar, err = app.DeliverTx(ctx, types.RequestDeliverTx{Tx: tx}) require.NoError(t, err) require.False(t, ar.IsErr(), ar) // commit - _, err = app.CommitSync(ctx) + _, err = app.Commit(ctx) require.NoError(t, err) - info, err := app.InfoSync(ctx, types.RequestInfo{}) + info, err := app.Info(ctx, types.RequestInfo{}) require.NoError(t, err) require.NotZero(t, info.LastBlockHeight) // make sure query is fine - resQuery, err := app.QuerySync(ctx, types.RequestQuery{ + resQuery, err := app.Query(ctx, types.RequestQuery{ Path: "/store", Data: []byte(key), }) @@ -357,7 +357,7 @@ func testClient(ctx context.Context, t *testing.T, app abciclient.Client, tx []b require.EqualValues(t, info.LastBlockHeight, resQuery.Height) // make sure proof is fine - resQuery, err = app.QuerySync(ctx, types.RequestQuery{ + resQuery, err = app.Query(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 5062083f0..2b2d57961 100644 --- a/abci/tests/server/client.go +++ b/abci/tests/server/client.go @@ -21,7 +21,7 @@ func InitChain(ctx context.Context, client abciclient.Client) error { power := mrand.Int() vals[i] = types.UpdateValidator(pubkey, int64(power), "") } - _, err := client.InitChainSync(ctx, types.RequestInitChain{ + _, err := client.InitChain(ctx, types.RequestInitChain{ Validators: vals, }) if err != nil { @@ -33,7 +33,7 @@ func InitChain(ctx context.Context, client abciclient.Client) error { } func Commit(ctx context.Context, client abciclient.Client, hashExp []byte) error { - res, err := client.CommitSync(ctx) + res, err := client.Commit(ctx) data := res.Data if err != nil { fmt.Println("Failed test: Commit") @@ -50,7 +50,7 @@ func Commit(ctx context.Context, client abciclient.Client, hashExp []byte) error } func DeliverTx(ctx context.Context, client abciclient.Client, txBytes []byte, codeExp uint32, dataExp []byte) error { - res, _ := client.DeliverTxSync(ctx, types.RequestDeliverTx{Tx: txBytes}) + res, _ := client.DeliverTx(ctx, types.RequestDeliverTx{Tx: txBytes}) code, data, log := res.Code, res.Data, res.Log if code != codeExp { fmt.Println("Failed test: DeliverTx") @@ -69,7 +69,7 @@ func DeliverTx(ctx context.Context, client abciclient.Client, txBytes []byte, co } func CheckTx(ctx context.Context, client abciclient.Client, txBytes []byte, codeExp uint32, dataExp []byte) error { - res, _ := client.CheckTxSync(ctx, types.RequestCheckTx{Tx: txBytes}) + res, _ := client.CheckTx(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/go.mod b/go.mod index 556b6fa69..cd8a66edc 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/mroth/weightedrand v0.4.1 github.com/oasisprotocol/curve25519-voi v0.0.0-20210609091139-0a56a4bca00b github.com/ory/dockertest v3.3.5+incompatible - github.com/prometheus/client_golang v1.11.0 + github.com/prometheus/client_golang v1.12.0 github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 github.com/rs/cors v1.8.2 github.com/rs/zerolog v1.26.1 @@ -155,7 +155,7 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polyfloyd/go-errorlint v0.0.0-20210722154253-910bb7978349 // indirect github.com/prometheus/client_model v0.2.0 // indirect - github.com/prometheus/common v0.30.0 // indirect + github.com/prometheus/common v0.32.1 // indirect github.com/prometheus/procfs v0.7.3 // indirect github.com/quasilyte/go-ruleguard v0.3.13 // indirect github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 // indirect @@ -189,7 +189,7 @@ require ( github.com/yeya24/promlinter v0.1.0 // indirect go.etcd.io/bbolt v1.3.6 // indirect golang.org/x/mod v0.5.0 // indirect - golang.org/x/sys v0.0.0-20211210111614-af8b64212486 // indirect + golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/tools v0.1.7 // indirect diff --git a/go.sum b/go.sum index d02e70443..7dfbed118 100644 --- a/go.sum +++ b/go.sum @@ -831,8 +831,9 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.0 h1:C+UIj/QWtmqY13Arb8kwMt5j34/0Z2iKamrJ+ryC0Gg= +github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -844,8 +845,9 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.30.0 h1:JEkYlQnpzrzQFxi6gnukFPdQ+ac82oRhzMcIduJu/Ug= github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -1330,8 +1332,9 @@ golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211210111614-af8b64212486 h1:5hpz5aRr+W1erYCL5JRhSUBJRph7l9XkNveoExlrKYk= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= diff --git a/internal/consensus/common_test.go b/internal/consensus/common_test.go index 4c1d0c4da..3400754d8 100644 --- a/internal/consensus/common_test.go +++ b/internal/consensus/common_test.go @@ -282,6 +282,9 @@ func validatePrevote( ) { t.Helper() + cs.mtx.RLock() + defer cs.mtx.RUnlock() + prevotes := cs.Votes.Prevotes(round) pubKey, err := privVal.GetPubKey(ctx) require.NoError(t, err) @@ -355,25 +358,6 @@ func validatePrecommit( } } -func validatePrevoteAndPrecommit( - ctx context.Context, - t *testing.T, - cs *State, - thisRound, - lockRound int32, - privVal *validatorStub, - votedBlockHash, - lockedBlockHash []byte, -) { - t.Helper() - // verify the prevote - validatePrevote(ctx, t, cs, thisRound, privVal, votedBlockHash) - // verify precommit - cs.mtx.Lock() - defer cs.mtx.Unlock() - validatePrecommit(ctx, t, cs, thisRound, lockRound, privVal, votedBlockHash, lockedBlockHash) -} - func subscribeToVoter(ctx context.Context, t *testing.T, cs *State, addr []byte) <-chan tmpubsub.Message { t.Helper() @@ -683,6 +667,38 @@ func ensurePrevote(t *testing.T, voteCh <-chan tmpubsub.Message, height int64, r ensureVote(t, voteCh, height, round, tmproto.PrevoteType) } +func ensurePrevoteMatch(t *testing.T, voteCh <-chan tmpubsub.Message, height int64, round int32, hash []byte) { + t.Helper() + ensureVoteMatch(t, voteCh, height, round, hash, tmproto.PrevoteType) +} + +func ensurePrecommitMatch(t *testing.T, voteCh <-chan tmpubsub.Message, height int64, round int32, hash []byte) { + t.Helper() + ensureVoteMatch(t, voteCh, height, round, hash, tmproto.PrecommitType) +} + +func ensureVoteMatch(t *testing.T, voteCh <-chan tmpubsub.Message, height int64, round int32, hash []byte, voteType tmproto.SignedMsgType) { + t.Helper() + select { + case <-time.After(ensureTimeout): + t.Fatal("Timeout expired while waiting for NewVote event") + case msg := <-voteCh: + voteEvent, ok := msg.Data().(types.EventDataVote) + require.True(t, ok, "expected a EventDataVote, got %T. Wrong subscription channel?", + msg.Data()) + + vote := voteEvent.Vote + require.Equal(t, height, vote.Height) + require.Equal(t, round, vote.Round) + + require.Equal(t, voteType, vote.Type) + if hash == nil { + require.Nil(t, vote.BlockID.Hash, "Expected prevote to be for nil, got %X", vote.BlockID.Hash) + } else { + require.True(t, bytes.Equal(vote.BlockID.Hash, hash), "Expected prevote to be for %X, got %X", hash, vote.BlockID.Hash) + } + } +} func ensureVote(t *testing.T, voteCh <-chan tmpubsub.Message, height int64, round int32, voteType tmproto.SignedMsgType) { t.Helper() msg := ensureMessageBeforeTimeout(t, voteCh, ensureTimeout) diff --git a/internal/consensus/reactor_test.go b/internal/consensus/reactor_test.go index 00e8d73f3..c0a6445aa 100644 --- a/internal/consensus/reactor_test.go +++ b/internal/consensus/reactor_test.go @@ -81,7 +81,7 @@ func setup( rts.voteSetBitsChannels = rts.network.MakeChannelsNoCleanup(ctx, t, chDesc(VoteSetBitsChannel, size)) ctx, cancel := context.WithCancel(ctx) - // Canceled during cleanup (see below). + t.Cleanup(cancel) chCreator := func(nodeID types.NodeID) p2p.ChannelCreator { return func(ctx context.Context, desc *p2p.ChannelDescriptor) (*p2p.Channel, error) { @@ -142,6 +142,7 @@ func setup( require.NoError(t, reactor.Start(ctx)) require.True(t, reactor.IsRunning()) + t.Cleanup(reactor.Wait) i++ } @@ -151,10 +152,7 @@ func setup( // start the in-memory network and connect all peers with each other rts.network.Start(ctx, t) - t.Cleanup(func() { - cancel() - leaktest.Check(t) - }) + t.Cleanup(leaktest.Check(t)) return rts } diff --git a/internal/consensus/replay.go b/internal/consensus/replay.go index 73b113e65..6250ffc06 100644 --- a/internal/consensus/replay.go +++ b/internal/consensus/replay.go @@ -240,7 +240,7 @@ func (h *Handshaker) NBlocks() int { func (h *Handshaker) Handshake(ctx context.Context, proxyApp proxy.AppConns) error { // Handshake is done via ABCI Info on the query conn. - res, err := proxyApp.Query().InfoSync(ctx, proxy.RequestInfo) + res, err := proxyApp.Query().Info(ctx, proxy.RequestInfo) if err != nil { return fmt.Errorf("error calling Info: %w", err) } @@ -316,7 +316,7 @@ func (h *Handshaker) ReplayBlocks( Validators: nextVals, AppStateBytes: h.genDoc.AppState, } - res, err := proxyApp.Consensus().InitChainSync(ctx, req) + res, err := proxyApp.Consensus().InitChain(ctx, req) if err != nil { return nil, err } diff --git a/internal/consensus/replay_test.go b/internal/consensus/replay_test.go index b0af9dda0..566aa8bff 100644 --- a/internal/consensus/replay_test.go +++ b/internal/consensus/replay_test.go @@ -686,26 +686,20 @@ func TestMockProxyApp(t *testing.T) { abciRes := new(tmstate.ABCIResponses) abciRes.DeliverTxs = make([]*abci.ResponseDeliverTx, len(loadedAbciRes.DeliverTxs)) - // Execute transactions and get hash. - proxyCb := func(req *abci.Request, res *abci.Response) { - if r, ok := res.Value.(*abci.Response_DeliverTx); ok { - // TODO: make use of res.Log - // TODO: make use of this info - // Blocks may include invalid txs. - txRes := r.DeliverTx - if txRes.Code == abci.CodeTypeOK { - validTxs++ - } else { - invalidTxs++ - } - abciRes.DeliverTxs[txIndex] = txRes - txIndex++ - } - } - mock.SetResponseCallback(proxyCb) someTx := []byte("tx") - _, err = mock.DeliverTxAsync(ctx, abci.RequestDeliverTx{Tx: someTx}) + resp, err := mock.DeliverTx(ctx, abci.RequestDeliverTx{Tx: someTx}) + // TODO: make use of res.Log + // TODO: make use of this info + // Blocks may include invalid txs. + if resp.Code == abci.CodeTypeOK { + validTxs++ + } else { + invalidTxs++ + } + abciRes.DeliverTxs[txIndex] = resp + txIndex++ + assert.NoError(t, err) }) assert.True(t, validTxs == 1) @@ -847,7 +841,7 @@ func testHandshakeReplay( require.NoError(t, err, "Error on abci handshake") // get the latest app hash from the app - res, err := proxyApp.Query().InfoSync(ctx, abci.RequestInfo{Version: ""}) + res, err := proxyApp.Query().Info(ctx, abci.RequestInfo{Version: ""}) if err != nil { t.Fatal(err) } @@ -913,7 +907,7 @@ func buildAppStateFromChain( state.Version.Consensus.App = kvstore.ProtocolVersion // simulate handshake, receive app version validators := types.TM2PB.ValidatorUpdates(state.Validators) - _, err := proxyApp.Consensus().InitChainSync(ctx, abci.RequestInitChain{ + _, err := proxyApp.Consensus().InitChain(ctx, abci.RequestInitChain{ Validators: validators, }) require.NoError(t, err) @@ -970,7 +964,7 @@ func buildTMStateFromChain( state.Version.Consensus.App = kvstore.ProtocolVersion // simulate handshake, receive app version validators := types.TM2PB.ValidatorUpdates(state.Validators) - _, err := proxyApp.Consensus().InitChainSync(ctx, abci.RequestInitChain{ + _, err := proxyApp.Consensus().InitChain(ctx, abci.RequestInitChain{ Validators: validators, }) require.NoError(t, err) diff --git a/internal/consensus/state.go b/internal/consensus/state.go index 16a04b7ca..512b1b789 100644 --- a/internal/consensus/state.go +++ b/internal/consensus/state.go @@ -2451,11 +2451,16 @@ func (cs *State) checkDoubleSigningRisk(height int64) error { } func (cs *State) calculatePrevoteMessageDelayMetrics() { + if cs.Proposal == nil { + return + } ps := cs.Votes.Prevotes(cs.Round) pl := ps.List() + sort.Slice(pl, func(i, j int) bool { return pl[i].Timestamp.Before(pl[j].Timestamp) }) + var votingPowerSeen int64 for _, v := range pl { _, val := cs.Validators.GetByAddress(v.ValidatorAddress) diff --git a/internal/consensus/state_test.go b/internal/consensus/state_test.go index b622d94eb..dc308def0 100644 --- a/internal/consensus/state_test.go +++ b/internal/consensus/state_test.go @@ -254,8 +254,7 @@ func TestStateBadProposal(t *testing.T) { ensureProposal(t, proposalCh, height, round, blockID) // wait for prevote - ensurePrevote(t, voteCh, height, round) - validatePrevote(ctx, t, cs1, round, vss[0], nil) + ensurePrevoteMatch(t, voteCh, height, round, nil) // add bad prevote from vs2 and wait for it signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), blockID, vs2) @@ -321,8 +320,7 @@ func TestStateOversizedBlock(t *testing.T) { // and then should send nil prevote and precommit regardless of whether other validators prevote and // precommit on it - ensurePrevote(t, voteCh, height, round) - validatePrevote(ctx, t, cs1, round, vss[0], nil) + ensurePrevoteMatch(t, voteCh, height, round, nil) signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), blockID, vs2) ensurePrevote(t, voteCh, height, round) ensurePrecommit(t, voteCh, height, round) @@ -343,19 +341,9 @@ func TestStateFullRound1(t *testing.T) { cs, vss := makeState(ctx, t, config, logger, 1) height, round := cs.Height, cs.Round - // NOTE: buffer capacity of 0 ensures we can validate prevote and last commit - // before consensus can move to the next height (and cause a race condition) - if err := cs.eventBus.Stop(); err != nil { - t.Error(err) - } - eventBus := eventbus.NewDefault(logger.With("module", "events")) - - cs.SetEventBus(eventBus) - if err := eventBus.Start(ctx); err != nil { - t.Error(err) - } - - voteCh := subscribe(ctx, t, cs.eventBus, types.EventQueryVote) + pv, err := cs.privValidator.GetPubKey(ctx) + require.NoError(t, err) + voteCh := subscribeToVoter(ctx, t, cs, pv.Address()) propCh := subscribe(ctx, t, cs.eventBus, types.EventQueryCompleteProposal) newRoundCh := subscribe(ctx, t, cs.eventBus, types.EventQueryNewRound) @@ -367,8 +355,7 @@ func TestStateFullRound1(t *testing.T) { ensureNewProposal(t, propCh, height, round) propBlockHash := cs.GetRoundState().ProposalBlock.Hash() - ensurePrevote(t, voteCh, height, round) // wait for prevote - validatePrevote(ctx, t, cs, round, vss[0], propBlockHash) + ensurePrevoteMatch(t, voteCh, height, round, propBlockHash) // wait for prevote ensurePrecommit(t, voteCh, height, round) // wait for precommit @@ -385,7 +372,7 @@ func TestStateFullRoundNil(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - cs, vss := makeState(ctx, t, config, logger, 1) + cs, _ := makeState(ctx, t, config, logger, 1) height, round := cs.Height, cs.Round voteCh := subscribe(ctx, t, cs.eventBus, types.EventQueryVote) @@ -393,11 +380,8 @@ func TestStateFullRoundNil(t *testing.T) { cs.enterPrevote(ctx, height, round) cs.startRoutines(ctx, 4) - ensurePrevote(t, voteCh, height, round) // prevote - ensurePrecommit(t, voteCh, height, round) // precommit - - // should prevote and precommit nil - validatePrevoteAndPrecommit(ctx, t, cs, round, -1, vss[0], nil, nil) + ensurePrevoteMatch(t, voteCh, height, round, nil) // prevote + ensurePrecommitMatch(t, voteCh, height, round, nil) // precommit } // run through propose, prevote, precommit commit with two validators @@ -746,8 +730,7 @@ func TestStateLock_POLUpdateLock(t *testing.T) { ensureNewProposal(t, proposalCh, height, round) // Prevote our nil since the proposal does not match our locked block. - ensurePrevote(t, voteCh, height, round) - validatePrevote(ctx, t, cs1, round, vss[0], nil) + ensurePrevoteMatch(t, voteCh, height, round, nil) // Add prevotes from the remainder of the validators for the new locked block. signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), r1BlockID, vs2, vs3, vs4) @@ -1096,8 +1079,7 @@ func TestStateLock_POLDoesNotUnlock(t *testing.T) { PartSetHeader: rs.ProposalBlockParts.Header(), } - ensurePrevote(t, voteCh, height, round) - validatePrevote(ctx, t, cs1, round, vss[0], blockID.Hash) + ensurePrevoteMatch(t, voteCh, height, round, blockID.Hash) signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), blockID, vs2, vs3, vs4) @@ -1142,8 +1124,7 @@ func TestStateLock_POLDoesNotUnlock(t *testing.T) { ensureNewProposal(t, proposalCh, height, round) // Prevote for nil since the proposed block does not match our locked block. - ensurePrevote(t, voteCh, height, round) - validatePrevote(ctx, t, cs1, round, vss[0], nil) + ensurePrevoteMatch(t, voteCh, height, round, nil) // add >2/3 prevotes for nil from all other validators signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), types.BlockID{}, vs2, vs3, vs4) @@ -1270,8 +1251,7 @@ func TestStateLock_MissingProposalWhenPOLSeenDoesNotUpdateLock(t *testing.T) { ensureNewRound(t, newRoundCh, height, round) // prevote for nil since the proposal was not seen. - ensurePrevote(t, voteCh, height, round) - validatePrevote(ctx, t, cs1, round, vss[0], nil) + ensurePrevoteMatch(t, voteCh, height, round, nil) // now lets add prevotes from everyone else for the new block signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), secondBlockID, vs2, vs3, vs4) @@ -1391,8 +1371,7 @@ func TestStateLock_POLSafety1(t *testing.T) { rs := cs1.GetRoundState() propBlock := rs.ProposalBlock - ensurePrevote(t, voteCh, height, round) - validatePrevote(ctx, t, cs1, round, vss[0], propBlock.Hash()) + ensurePrevoteMatch(t, voteCh, height, round, propBlock.Hash()) partSet, err := propBlock.MakePartSet(partSize) require.NoError(t, err) blockID := types.BlockID{Hash: propBlock.Hash(), PartSetHeader: partSet.Header()} @@ -1439,8 +1418,7 @@ func TestStateLock_POLSafety1(t *testing.T) { t.Logf("new prop hash %v", fmt.Sprintf("%X", propBlock.Hash())) // go to prevote, prevote for proposal block - ensurePrevote(t, voteCh, height, round) - validatePrevote(ctx, t, cs1, round, vss[0], r2BlockID.Hash) + ensurePrevoteMatch(t, voteCh, height, round, r2BlockID.Hash) // now we see the others prevote for it, so we should lock on it signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), r2BlockID, vs2, vs3, vs4) @@ -1467,9 +1445,7 @@ func TestStateLock_POLSafety1(t *testing.T) { ensureNewTimeout(t, timeoutProposeCh, height, round, cs1.config.Propose(round).Nanoseconds()) // finish prevote - ensurePrevote(t, voteCh, height, round) - // we should prevote for nil - validatePrevote(ctx, t, cs1, round, vss[0], nil) + ensurePrevoteMatch(t, voteCh, height, round, nil) newStepCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryNewRoundStep) @@ -1536,8 +1512,7 @@ func TestStateLock_POLSafety2(t *testing.T) { require.NoError(t, err) ensureNewProposal(t, proposalCh, height, round) - ensurePrevote(t, voteCh, height, round) - validatePrevote(ctx, t, cs1, round, vss[0], propBlockID1.Hash) + ensurePrevoteMatch(t, voteCh, height, round, propBlockID1.Hash) signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), propBlockID1, vs2, vs3, vs4) @@ -1762,8 +1737,7 @@ func TestProposeValidBlock(t *testing.T) { PartSetHeader: partSet.Header(), } - ensurePrevote(t, voteCh, height, round) - validatePrevote(ctx, t, cs1, round, vss[0], blockID.Hash) + ensurePrevoteMatch(t, voteCh, height, round, blockID.Hash) // the others sign a polka signAddVotes(ctx, t, cs1, tmproto.PrevoteType, cfg.ChainID(), blockID, vs2, vs3, vs4) @@ -1787,8 +1761,7 @@ func TestProposeValidBlock(t *testing.T) { ensureNewTimeout(t, timeoutProposeCh, height, round, cs1.config.Propose(round).Nanoseconds()) // We did not see a valid proposal within this round, so prevote nil. - ensurePrevote(t, voteCh, height, round) - validatePrevote(ctx, t, cs1, round, vss[0], nil) + ensurePrevoteMatch(t, voteCh, height, round, nil) signAddVotes(ctx, t, cs1, tmproto.PrecommitType, cfg.ChainID(), types.BlockID{}, vs2, vs3, vs4) @@ -1859,8 +1832,7 @@ func TestSetValidBlockOnDelayedPrevote(t *testing.T) { PartSetHeader: partSet.Header(), } - ensurePrevote(t, voteCh, height, round) - validatePrevote(ctx, t, cs1, round, vss[0], blockID.Hash) + ensurePrevoteMatch(t, voteCh, height, round, blockID.Hash) // vs2 send prevote for propBlock signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), blockID, vs2) @@ -1925,8 +1897,7 @@ func TestSetValidBlockOnDelayedProposal(t *testing.T) { ensureNewTimeout(t, timeoutProposeCh, height, round, cs1.config.Propose(round).Nanoseconds()) - ensurePrevote(t, voteCh, height, round) - validatePrevote(ctx, t, cs1, round, vss[0], nil) + ensurePrevoteMatch(t, voteCh, height, round, nil) prop, propBlock := decideProposal(ctx, t, cs1, vs2, vs2.Height, vs2.Round+1) partSet, err := propBlock.MakePartSet(partSize) @@ -2021,8 +1992,7 @@ func TestWaitingTimeoutProposeOnNewRound(t *testing.T) { ensureNewTimeout(t, timeoutWaitCh, height, round, cs1.config.Propose(round).Nanoseconds()) - ensurePrevote(t, voteCh, height, round) - validatePrevote(ctx, t, cs1, round, vss[0], nil) + ensurePrevoteMatch(t, voteCh, height, round, nil) } // 4 vals, 3 Precommits for nil from the higher round. @@ -2095,8 +2065,7 @@ func TestWaitTimeoutProposeOnNilPolkaForTheCurrentRound(t *testing.T) { ensureNewTimeout(t, timeoutProposeCh, height, round, cs1.config.Propose(round).Nanoseconds()) - ensurePrevote(t, voteCh, height, round) - validatePrevote(ctx, t, cs1, round, vss[0], nil) + ensurePrevoteMatch(t, voteCh, height, round, nil) } // What we want: @@ -2241,8 +2210,7 @@ func TestStartNextHeightCorrectlyAfterTimeout(t *testing.T) { PartSetHeader: rs.ProposalBlockParts.Header(), } - ensurePrevote(t, voteCh, height, round) - validatePrevote(ctx, t, cs1, round, vss[0], blockID.Hash) + ensurePrevoteMatch(t, voteCh, height, round, blockID.Hash) signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), blockID, vs2, vs3, vs4) @@ -2308,8 +2276,7 @@ func TestResetTimeoutPrecommitUponNewHeight(t *testing.T) { PartSetHeader: rs.ProposalBlockParts.Header(), } - ensurePrevote(t, voteCh, height, round) - validatePrevote(ctx, t, cs1, round, vss[0], blockID.Hash) + ensurePrevoteMatch(t, voteCh, height, round, blockID.Hash) signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), blockID, vs2, vs3, vs4) @@ -2410,8 +2377,7 @@ func TestStateHalt1(t *testing.T) { */ // prevote for nil since we did not receive a proposal in this round. - ensurePrevote(t, voteCh, height, round) - validatePrevote(ctx, t, cs1, round, vss[0], nil) + ensurePrevoteMatch(t, voteCh, height, round, rs.LockedBlock.Hash()) // now we receive the precommit from the previous round addVotes(cs1, precommit4) diff --git a/internal/consensus/wal_test.go b/internal/consensus/wal_test.go index 24b1d3dfc..8a39b31b5 100644 --- a/internal/consensus/wal_test.go +++ b/internal/consensus/wal_test.go @@ -9,6 +9,7 @@ import ( "testing" "time" + "github.com/fortytw2/leaktest" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -50,6 +51,10 @@ func TestWALTruncate(t *testing.T) { err = WALGenerateNBlocks(ctx, t, logger, wal.Group(), 60) require.NoError(t, err) + // put the leakcheck here so it runs after other cleanup + // functions. + t.Cleanup(leaktest.CheckTimeout(t, 500*time.Millisecond)) + time.Sleep(1 * time.Millisecond) // wait groupCheckDuration, make sure RotateFile run if err := wal.FlushAndSync(); err != nil { diff --git a/internal/libs/autofile/group.go b/internal/libs/autofile/group.go index 4aa6f2cb5..1b4418d59 100644 --- a/internal/libs/autofile/group.go +++ b/internal/libs/autofile/group.go @@ -56,7 +56,6 @@ assuming that marker lines are written occasionally. type Group struct { service.BaseService logger log.Logger - ctx context.Context ID string Head *AutoFile // The head AutoFile to write to @@ -93,7 +92,6 @@ func OpenGroup(ctx context.Context, logger log.Logger, headPath string, groupOpt g := &Group{ logger: logger, - ctx: ctx, ID: "group:" + head.ID, Head: head, headBuf: bufio.NewWriterSize(head, 4096*10), @@ -250,14 +248,14 @@ func (g *Group) processTicks(ctx context.Context) { case <-ctx.Done(): return case <-g.ticker.C: - g.checkHeadSizeLimit() - g.checkTotalSizeLimit() + g.checkHeadSizeLimit(ctx) + g.checkTotalSizeLimit(ctx) } } } // NOTE: this function is called manually in tests. -func (g *Group) checkHeadSizeLimit() { +func (g *Group) checkHeadSizeLimit(ctx context.Context) { limit := g.HeadSizeLimit() if limit == 0 { return @@ -268,13 +266,15 @@ func (g *Group) checkHeadSizeLimit() { return } if size >= limit { - g.RotateFile() + g.rotateFile(ctx) } } -func (g *Group) checkTotalSizeLimit() { - limit := g.TotalSizeLimit() - if limit == 0 { +func (g *Group) checkTotalSizeLimit(ctx context.Context) { + g.mtx.Lock() + defer g.mtx.Unlock() + + if g.totalSizeLimit == 0 { return } @@ -282,7 +282,7 @@ func (g *Group) checkTotalSizeLimit() { totalSize := gInfo.TotalSize for i := 0; i < maxFilesToRemove; i++ { index := gInfo.MinIndex + i - if totalSize < limit { + if totalSize < g.totalSizeLimit { return } if index == gInfo.MaxIndex { @@ -296,8 +296,12 @@ func (g *Group) checkTotalSizeLimit() { g.logger.Error("Failed to fetch info for file", "file", pathToRemove) continue } - err = os.Remove(pathToRemove) - if err != nil { + + if ctx.Err() != nil { + return + } + + if err = os.Remove(pathToRemove); err != nil { g.logger.Error("Failed to remove path", "path", pathToRemove) return } @@ -305,8 +309,8 @@ func (g *Group) checkTotalSizeLimit() { } } -// RotateFile causes group to close the current head and assign it some index. -func (g *Group) RotateFile() { +// rotateFile causes group to close the current head and assign it some index. +func (g *Group) rotateFile(ctx context.Context) { g.mtx.Lock() defer g.mtx.Unlock() @@ -319,6 +323,10 @@ func (g *Group) RotateFile() { panic(err) } err := g.Head.withLock(func() error { + if err := ctx.Err(); err != nil { + return err + } + if err := g.Head.unsyncCloseFile(); err != nil { return err } @@ -326,9 +334,13 @@ func (g *Group) RotateFile() { indexPath := filePathForIndex(headPath, g.maxIndex, g.maxIndex+1) return os.Rename(headPath, indexPath) }) + if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { + return + } if err != nil { panic(err) } + g.maxIndex++ } diff --git a/internal/libs/autofile/group_test.go b/internal/libs/autofile/group_test.go index 328201780..f6b3eaab6 100644 --- a/internal/libs/autofile/group_test.go +++ b/internal/libs/autofile/group_test.go @@ -64,7 +64,7 @@ func TestCheckHeadSizeLimit(t *testing.T) { assertGroupInfo(t, g.ReadGroupInfo(), 0, 0, 999000, 999000) // Even calling checkHeadSizeLimit manually won't rotate it. - g.checkHeadSizeLimit() + g.checkHeadSizeLimit(ctx) assertGroupInfo(t, g.ReadGroupInfo(), 0, 0, 999000, 999000) // Write 1000 more bytes. @@ -74,7 +74,7 @@ func TestCheckHeadSizeLimit(t *testing.T) { require.NoError(t, err) // Calling checkHeadSizeLimit this time rolls it. - g.checkHeadSizeLimit() + g.checkHeadSizeLimit(ctx) assertGroupInfo(t, g.ReadGroupInfo(), 0, 1, 1000000, 0) // Write 1000 more bytes. @@ -84,7 +84,7 @@ func TestCheckHeadSizeLimit(t *testing.T) { require.NoError(t, err) // Calling checkHeadSizeLimit does nothing. - g.checkHeadSizeLimit() + g.checkHeadSizeLimit(ctx) assertGroupInfo(t, g.ReadGroupInfo(), 0, 1, 1001000, 1000) // Write 1000 bytes 999 times. @@ -97,7 +97,7 @@ func TestCheckHeadSizeLimit(t *testing.T) { assertGroupInfo(t, g.ReadGroupInfo(), 0, 1, 2000000, 1000000) // Calling checkHeadSizeLimit rolls it again. - g.checkHeadSizeLimit() + g.checkHeadSizeLimit(ctx) assertGroupInfo(t, g.ReadGroupInfo(), 0, 2, 2000000, 0) // Write 1000 more bytes. @@ -108,7 +108,7 @@ func TestCheckHeadSizeLimit(t *testing.T) { assertGroupInfo(t, g.ReadGroupInfo(), 0, 2, 2001000, 1000) // Calling checkHeadSizeLimit does nothing. - g.checkHeadSizeLimit() + g.checkHeadSizeLimit(ctx) assertGroupInfo(t, g.ReadGroupInfo(), 0, 2, 2001000, 1000) // Cleanup @@ -150,7 +150,7 @@ func TestRotateFile(t *testing.T) { require.NoError(t, err) err = g.FlushAndSync() require.NoError(t, err) - g.RotateFile() + g.rotateFile(ctx) err = g.WriteLine("Line 4") require.NoError(t, err) err = g.WriteLine("Line 5") @@ -224,7 +224,7 @@ func TestGroupReaderRead(t *testing.T) { require.NoError(t, err) err = g.FlushAndSync() require.NoError(t, err) - g.RotateFile() + g.rotateFile(ctx) frankenstein := []byte("Frankenstein's Monster") _, err = g.Write(frankenstein) require.NoError(t, err) @@ -262,7 +262,7 @@ func TestGroupReaderRead2(t *testing.T) { require.NoError(t, err) err = g.FlushAndSync() require.NoError(t, err) - g.RotateFile() + g.rotateFile(ctx) frankenstein := []byte("Frankenstein's Monster") frankensteinPart := []byte("Frankenstein") _, err = g.Write(frankensteinPart) // note writing only a part @@ -315,7 +315,7 @@ func TestMaxIndex(t *testing.T) { require.NoError(t, err) err = g.FlushAndSync() require.NoError(t, err) - g.RotateFile() + g.rotateFile(ctx) assert.Equal(t, 1, g.MaxIndex(), "MaxIndex should point to the last file") diff --git a/internal/mempool/mempool.go b/internal/mempool/mempool.go index e0cb72d0b..1850b80d0 100644 --- a/internal/mempool/mempool.go +++ b/internal/mempool/mempool.go @@ -176,7 +176,7 @@ func (txmp *TxMempool) SizeBytes() int64 { // // NOTE: The caller must obtain a write-lock prior to execution. func (txmp *TxMempool) FlushAppConn(ctx context.Context) error { - return txmp.proxyAppConn.FlushSync(ctx) + return txmp.proxyAppConn.Flush(ctx) } // WaitForNextTx returns a blocking channel that will be closed when the next diff --git a/internal/mempool/reactor_test.go b/internal/mempool/reactor_test.go index d8a536084..eeba1e0d9 100644 --- a/internal/mempool/reactor_test.go +++ b/internal/mempool/reactor_test.go @@ -45,7 +45,7 @@ func setupReactors(ctx context.Context, t *testing.T, numNodes int, chBuf uint) t.Cleanup(func() { os.RemoveAll(cfg.RootDir) }) rts := &reactorTestSuite{ - logger: log.TestingLogger().With("testCase", t.Name()), + logger: log.NewNopLogger().With("testCase", t.Name()), network: p2ptest.MakeNetwork(ctx, t, p2ptest.NetworkOptions{NumNodes: numNodes}), reactors: make(map[types.NodeID]*Reactor, numNodes), mempoolChannels: make(map[types.NodeID]*p2p.Channel, numNodes), @@ -95,8 +95,10 @@ func setupReactors(ctx context.Context, t *testing.T, numNodes int, chBuf uint) for nodeID := range rts.reactors { if rts.reactors[nodeID].IsRunning() { require.NoError(t, rts.reactors[nodeID].Stop()) + rts.reactors[nodeID].Wait() require.False(t, rts.reactors[nodeID].IsRunning()) } + } }) diff --git a/internal/p2p/peermanager.go b/internal/p2p/peermanager.go index f7e4fb730..2edc5b3b6 100644 --- a/internal/p2p/peermanager.go +++ b/internal/p2p/peermanager.go @@ -136,6 +136,10 @@ type PeerManagerOptions struct { // consider private and never gossip. PrivatePeers map[types.NodeID]struct{} + // SelfAddress is the address that will be advertised to peers for them to dial back to us. + // If Hostname and Port are unset, Advertise() will include no self-announcement + SelfAddress NodeAddress + // persistentPeers provides fast PersistentPeers lookups. It is built // by optimize(). persistentPeers map[types.NodeID]bool @@ -791,6 +795,13 @@ func (m *PeerManager) Advertise(peerID types.NodeID, limit uint16) []NodeAddress defer m.mtx.Unlock() addresses := make([]NodeAddress, 0, limit) + + // advertise ourselves, to let everyone know how to dial us back + // and enable mutual address discovery + if m.options.SelfAddress.Hostname != "" && m.options.SelfAddress.Port != 0 { + addresses = append(addresses, m.options.SelfAddress) + } + for _, peer := range m.store.Ranked() { if peer.ID == peerID { continue diff --git a/internal/p2p/peermanager_test.go b/internal/p2p/peermanager_test.go index 2999e8d6d..17d04bac2 100644 --- a/internal/p2p/peermanager_test.go +++ b/internal/p2p/peermanager_test.go @@ -1828,6 +1828,23 @@ func TestPeerManager_Advertise(t *testing.T) { }, peerManager.Advertise(dID, 2)) } +func TestPeerManager_Advertise_Self(t *testing.T) { + dID := types.NodeID(strings.Repeat("d", 40)) + + self := p2p.NodeAddress{Protocol: "tcp", NodeID: selfID, Hostname: "2001:db8::1", Port: 26657} + + // Create a peer manager with SelfAddress defined. + peerManager, err := p2p.NewPeerManager(selfID, dbm.NewMemDB(), p2p.PeerManagerOptions{ + SelfAddress: self, + }) + require.NoError(t, err) + + // peer manager should always advertise its SelfAddress. + require.ElementsMatch(t, []p2p.NodeAddress{ + self, + }, peerManager.Advertise(dID, 100)) +} + func TestPeerManager_SetHeight_GetHeight(t *testing.T) { a := p2p.NodeAddress{Protocol: "memory", NodeID: types.NodeID(strings.Repeat("a", 40))} b := p2p.NodeAddress{Protocol: "memory", NodeID: types.NodeID(strings.Repeat("b", 40))} diff --git a/internal/p2p/pex/reactor_test.go b/internal/p2p/pex/reactor_test.go index 872d49701..b4197095f 100644 --- a/internal/p2p/pex/reactor_test.go +++ b/internal/p2p/pex/reactor_test.go @@ -1,3 +1,6 @@ +// Temporarily disabled pending ttps://github.com/tendermint/tendermint/issues/7626. +//go:build issue7626 + package pex_test import ( diff --git a/internal/proxy/app_conn.go b/internal/proxy/app_conn.go index 803875646..1a7c9af52 100644 --- a/internal/proxy/app_conn.go +++ b/internal/proxy/app_conn.go @@ -18,12 +18,12 @@ type AppConnConsensus interface { SetResponseCallback(abciclient.Callback) Error() error - InitChainSync(context.Context, types.RequestInitChain) (*types.ResponseInitChain, error) + InitChain(context.Context, types.RequestInitChain) (*types.ResponseInitChain, error) - BeginBlockSync(context.Context, types.RequestBeginBlock) (*types.ResponseBeginBlock, error) - DeliverTxAsync(context.Context, types.RequestDeliverTx) (*abciclient.ReqRes, error) - EndBlockSync(context.Context, types.RequestEndBlock) (*types.ResponseEndBlock, error) - CommitSync(context.Context) (*types.ResponseCommit, error) + BeginBlock(context.Context, types.RequestBeginBlock) (*types.ResponseBeginBlock, error) + DeliverTx(context.Context, types.RequestDeliverTx) (*types.ResponseDeliverTx, error) + EndBlock(context.Context, types.RequestEndBlock) (*types.ResponseEndBlock, error) + Commit(context.Context) (*types.ResponseCommit, error) } type AppConnMempool interface { @@ -31,27 +31,27 @@ type AppConnMempool interface { Error() error CheckTxAsync(context.Context, types.RequestCheckTx) (*abciclient.ReqRes, error) - CheckTxSync(context.Context, types.RequestCheckTx) (*types.ResponseCheckTx, error) + CheckTx(context.Context, types.RequestCheckTx) (*types.ResponseCheckTx, error) FlushAsync(context.Context) (*abciclient.ReqRes, error) - FlushSync(context.Context) error + Flush(context.Context) error } type AppConnQuery interface { Error() error - EchoSync(context.Context, string) (*types.ResponseEcho, error) - InfoSync(context.Context, types.RequestInfo) (*types.ResponseInfo, error) - QuerySync(context.Context, types.RequestQuery) (*types.ResponseQuery, error) + Echo(context.Context, string) (*types.ResponseEcho, error) + Info(context.Context, types.RequestInfo) (*types.ResponseInfo, error) + Query(context.Context, types.RequestQuery) (*types.ResponseQuery, error) } type AppConnSnapshot interface { Error() 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) + ListSnapshots(context.Context, types.RequestListSnapshots) (*types.ResponseListSnapshots, error) + OfferSnapshot(context.Context, types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) + LoadSnapshotChunk(context.Context, types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) + ApplySnapshotChunk(context.Context, types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) } //----------------------------------------------------------------------------------------- @@ -77,41 +77,41 @@ func (app *appConnConsensus) Error() error { return app.appConn.Error() } -func (app *appConnConsensus) InitChainSync( +func (app *appConnConsensus) InitChain( ctx context.Context, req types.RequestInitChain, ) (*types.ResponseInitChain, error) { defer addTimeSample(app.metrics.MethodTiming.With("method", "init_chain", "type", "sync"))() - return app.appConn.InitChainSync(ctx, req) + return app.appConn.InitChain(ctx, req) } -func (app *appConnConsensus) BeginBlockSync( +func (app *appConnConsensus) BeginBlock( ctx context.Context, req types.RequestBeginBlock, ) (*types.ResponseBeginBlock, error) { defer addTimeSample(app.metrics.MethodTiming.With("method", "begin_block", "type", "sync"))() - return app.appConn.BeginBlockSync(ctx, req) + return app.appConn.BeginBlock(ctx, req) } -func (app *appConnConsensus) DeliverTxAsync( +func (app *appConnConsensus) DeliverTx( ctx context.Context, req types.RequestDeliverTx, -) (*abciclient.ReqRes, error) { - defer addTimeSample(app.metrics.MethodTiming.With("method", "deliver_tx", "type", "async"))() - return app.appConn.DeliverTxAsync(ctx, req) +) (*types.ResponseDeliverTx, error) { + defer addTimeSample(app.metrics.MethodTiming.With("method", "deliver_tx", "type", "sync"))() + return app.appConn.DeliverTx(ctx, req) } -func (app *appConnConsensus) EndBlockSync( +func (app *appConnConsensus) EndBlock( ctx context.Context, req types.RequestEndBlock, ) (*types.ResponseEndBlock, error) { defer addTimeSample(app.metrics.MethodTiming.With("method", "deliver_tx", "type", "sync"))() - return app.appConn.EndBlockSync(ctx, req) + return app.appConn.EndBlock(ctx, req) } -func (app *appConnConsensus) CommitSync(ctx context.Context) (*types.ResponseCommit, error) { +func (app *appConnConsensus) Commit(ctx context.Context) (*types.ResponseCommit, error) { defer addTimeSample(app.metrics.MethodTiming.With("method", "commit", "type", "sync"))() - return app.appConn.CommitSync(ctx) + return app.appConn.Commit(ctx) } //------------------------------------------------ @@ -142,9 +142,9 @@ func (app *appConnMempool) FlushAsync(ctx context.Context) (*abciclient.ReqRes, return app.appConn.FlushAsync(ctx) } -func (app *appConnMempool) FlushSync(ctx context.Context) error { +func (app *appConnMempool) Flush(ctx context.Context) error { defer addTimeSample(app.metrics.MethodTiming.With("method", "flush", "type", "sync"))() - return app.appConn.FlushSync(ctx) + return app.appConn.Flush(ctx) } func (app *appConnMempool) CheckTxAsync(ctx context.Context, req types.RequestCheckTx) (*abciclient.ReqRes, error) { @@ -152,9 +152,9 @@ func (app *appConnMempool) CheckTxAsync(ctx context.Context, req types.RequestCh return app.appConn.CheckTxAsync(ctx, req) } -func (app *appConnMempool) CheckTxSync(ctx context.Context, req types.RequestCheckTx) (*types.ResponseCheckTx, error) { +func (app *appConnMempool) CheckTx(ctx context.Context, req types.RequestCheckTx) (*types.ResponseCheckTx, error) { defer addTimeSample(app.metrics.MethodTiming.With("method", "check_tx", "type", "sync"))() - return app.appConn.CheckTxSync(ctx, req) + return app.appConn.CheckTx(ctx, req) } //------------------------------------------------ @@ -176,19 +176,19 @@ func (app *appConnQuery) Error() error { return app.appConn.Error() } -func (app *appConnQuery) EchoSync(ctx context.Context, msg string) (*types.ResponseEcho, error) { +func (app *appConnQuery) Echo(ctx context.Context, msg string) (*types.ResponseEcho, error) { defer addTimeSample(app.metrics.MethodTiming.With("method", "echo", "type", "sync"))() - return app.appConn.EchoSync(ctx, msg) + return app.appConn.Echo(ctx, msg) } -func (app *appConnQuery) InfoSync(ctx context.Context, req types.RequestInfo) (*types.ResponseInfo, error) { +func (app *appConnQuery) Info(ctx context.Context, req types.RequestInfo) (*types.ResponseInfo, error) { defer addTimeSample(app.metrics.MethodTiming.With("method", "info", "type", "sync"))() - return app.appConn.InfoSync(ctx, req) + return app.appConn.Info(ctx, req) } -func (app *appConnQuery) QuerySync(ctx context.Context, reqQuery types.RequestQuery) (*types.ResponseQuery, error) { +func (app *appConnQuery) Query(ctx context.Context, reqQuery types.RequestQuery) (*types.ResponseQuery, error) { defer addTimeSample(app.metrics.MethodTiming.With("method", "query", "type", "sync"))() - return app.appConn.QuerySync(ctx, reqQuery) + return app.appConn.Query(ctx, reqQuery) } //------------------------------------------------ @@ -210,34 +210,34 @@ func (app *appConnSnapshot) Error() error { return app.appConn.Error() } -func (app *appConnSnapshot) ListSnapshotsSync( +func (app *appConnSnapshot) ListSnapshots( ctx context.Context, req types.RequestListSnapshots, ) (*types.ResponseListSnapshots, error) { defer addTimeSample(app.metrics.MethodTiming.With("method", "list_snapshots", "type", "sync"))() - return app.appConn.ListSnapshotsSync(ctx, req) + return app.appConn.ListSnapshots(ctx, req) } -func (app *appConnSnapshot) OfferSnapshotSync( +func (app *appConnSnapshot) OfferSnapshot( ctx context.Context, req types.RequestOfferSnapshot, ) (*types.ResponseOfferSnapshot, error) { defer addTimeSample(app.metrics.MethodTiming.With("method", "offer_snapshot", "type", "sync"))() - return app.appConn.OfferSnapshotSync(ctx, req) + return app.appConn.OfferSnapshot(ctx, req) } -func (app *appConnSnapshot) LoadSnapshotChunkSync( +func (app *appConnSnapshot) LoadSnapshotChunk( ctx context.Context, req types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { defer addTimeSample(app.metrics.MethodTiming.With("method", "load_snapshot_chunk", "type", "sync"))() - return app.appConn.LoadSnapshotChunkSync(ctx, req) + return app.appConn.LoadSnapshotChunk(ctx, req) } -func (app *appConnSnapshot) ApplySnapshotChunkSync( +func (app *appConnSnapshot) ApplySnapshotChunk( ctx context.Context, req types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { defer addTimeSample(app.metrics.MethodTiming.With("method", "apply_snapshot_chunk", "type", "sync"))() - return app.appConn.ApplySnapshotChunkSync(ctx, req) + return app.appConn.ApplySnapshotChunk(ctx, req) } // addTimeSample returns a function that, when called, adds an observation to m. diff --git a/internal/proxy/app_conn_test.go b/internal/proxy/app_conn_test.go index 1f0ec0a9d..de8eac35d 100644 --- a/internal/proxy/app_conn_test.go +++ b/internal/proxy/app_conn_test.go @@ -18,9 +18,9 @@ import ( //---------------------------------------- type appConnTestI interface { - EchoAsync(ctx context.Context, msg string) (*abciclient.ReqRes, error) - FlushSync(context.Context) error - InfoSync(context.Context, types.RequestInfo) (*types.ResponseInfo, error) + Echo(context.Context, string) (*types.ResponseEcho, error) + Flush(context.Context) error + Info(context.Context, types.RequestInfo) (*types.ResponseInfo, error) } type appConnTest struct { @@ -31,16 +31,16 @@ func newAppConnTest(appConn abciclient.Client) appConnTestI { return &appConnTest{appConn} } -func (app *appConnTest) EchoAsync(ctx context.Context, msg string) (*abciclient.ReqRes, error) { - return app.appConn.EchoAsync(ctx, msg) +func (app *appConnTest) Echo(ctx context.Context, msg string) (*types.ResponseEcho, error) { + return app.appConn.Echo(ctx, msg) } -func (app *appConnTest) FlushSync(ctx context.Context) error { - return app.appConn.FlushSync(ctx) +func (app *appConnTest) Flush(ctx context.Context) error { + return app.appConn.Flush(ctx) } -func (app *appConnTest) InfoSync(ctx context.Context, req types.RequestInfo) (*types.ResponseInfo, error) { - return app.appConn.InfoSync(ctx, req) +func (app *appConnTest) Info(ctx context.Context, req types.RequestInfo) (*types.ResponseInfo, error) { + return app.appConn.Info(ctx, req) } //---------------------------------------- @@ -70,18 +70,18 @@ func TestEcho(t *testing.T) { t.Log("Connected") for i := 0; i < 1000; i++ { - _, err = proxy.EchoAsync(ctx, fmt.Sprintf("echo-%v", i)) + _, err = proxy.Echo(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 { + if err := proxy.Flush(ctx); err != nil { t.Error(err) } } } - if err := proxy.FlushSync(ctx); err != nil { + if err := proxy.Flush(ctx); err != nil { t.Error(err) } } @@ -112,23 +112,23 @@ func BenchmarkEcho(b *testing.B) { b.StartTimer() // Start benchmarking tests for i := 0; i < b.N; i++ { - _, err = proxy.EchoAsync(ctx, echoString) + _, err = proxy.Echo(ctx, echoString) if err != nil { b.Error(err) } // flush sometimes if i%128 == 0 { - if err := proxy.FlushSync(ctx); err != nil { + if err := proxy.Flush(ctx); err != nil { b.Error(err) } } } - if err := proxy.FlushSync(ctx); err != nil { + if err := proxy.Flush(ctx); err != nil { b.Error(err) } b.StopTimer() - // info := proxy.InfoSync(types.RequestInfo{""}) + // info := proxy.Info(types.RequestInfo{""}) // b.Log("N: ", b.N, info) } @@ -154,7 +154,7 @@ func TestInfo(t *testing.T) { proxy := newAppConnTest(cli) t.Log("Connected") - resInfo, err := proxy.InfoSync(ctx, RequestInfo) + resInfo, err := proxy.Info(ctx, RequestInfo) require.NoError(t, err) if resInfo.Data != "{\"size\":0}" { diff --git a/internal/proxy/mocks/app_conn_consensus.go b/internal/proxy/mocks/app_conn_consensus.go index fa93b0931..4be489163 100644 --- a/internal/proxy/mocks/app_conn_consensus.go +++ b/internal/proxy/mocks/app_conn_consensus.go @@ -17,8 +17,8 @@ type AppConnConsensus struct { mock.Mock } -// BeginBlockSync provides a mock function with given fields: _a0, _a1 -func (_m *AppConnConsensus) BeginBlockSync(_a0 context.Context, _a1 types.RequestBeginBlock) (*types.ResponseBeginBlock, error) { +// BeginBlock provides a mock function with given fields: _a0, _a1 +func (_m *AppConnConsensus) BeginBlock(_a0 context.Context, _a1 types.RequestBeginBlock) (*types.ResponseBeginBlock, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseBeginBlock @@ -40,8 +40,8 @@ func (_m *AppConnConsensus) BeginBlockSync(_a0 context.Context, _a1 types.Reques return r0, r1 } -// CommitSync provides a mock function with given fields: _a0 -func (_m *AppConnConsensus) CommitSync(_a0 context.Context) (*types.ResponseCommit, error) { +// Commit provides a mock function with given fields: _a0 +func (_m *AppConnConsensus) Commit(_a0 context.Context) (*types.ResponseCommit, error) { ret := _m.Called(_a0) var r0 *types.ResponseCommit @@ -63,16 +63,16 @@ func (_m *AppConnConsensus) CommitSync(_a0 context.Context) (*types.ResponseComm return r0, r1 } -// DeliverTxAsync provides a mock function with given fields: _a0, _a1 -func (_m *AppConnConsensus) DeliverTxAsync(_a0 context.Context, _a1 types.RequestDeliverTx) (*abciclient.ReqRes, error) { +// DeliverTx provides a mock function with given fields: _a0, _a1 +func (_m *AppConnConsensus) DeliverTx(_a0 context.Context, _a1 types.RequestDeliverTx) (*types.ResponseDeliverTx, error) { ret := _m.Called(_a0, _a1) - var r0 *abciclient.ReqRes - if rf, ok := ret.Get(0).(func(context.Context, types.RequestDeliverTx) *abciclient.ReqRes); ok { + var r0 *types.ResponseDeliverTx + 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).(*abciclient.ReqRes) + r0 = ret.Get(0).(*types.ResponseDeliverTx) } } @@ -86,8 +86,8 @@ func (_m *AppConnConsensus) DeliverTxAsync(_a0 context.Context, _a1 types.Reques return r0, r1 } -// EndBlockSync provides a mock function with given fields: _a0, _a1 -func (_m *AppConnConsensus) EndBlockSync(_a0 context.Context, _a1 types.RequestEndBlock) (*types.ResponseEndBlock, error) { +// EndBlock provides a mock function with given fields: _a0, _a1 +func (_m *AppConnConsensus) EndBlock(_a0 context.Context, _a1 types.RequestEndBlock) (*types.ResponseEndBlock, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseEndBlock @@ -123,8 +123,8 @@ func (_m *AppConnConsensus) Error() error { return r0 } -// InitChainSync provides a mock function with given fields: _a0, _a1 -func (_m *AppConnConsensus) InitChainSync(_a0 context.Context, _a1 types.RequestInitChain) (*types.ResponseInitChain, error) { +// InitChain provides a mock function with given fields: _a0, _a1 +func (_m *AppConnConsensus) InitChain(_a0 context.Context, _a1 types.RequestInitChain) (*types.ResponseInitChain, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseInitChain diff --git a/internal/proxy/mocks/app_conn_mempool.go b/internal/proxy/mocks/app_conn_mempool.go index 5429d8f90..9d8b80717 100644 --- a/internal/proxy/mocks/app_conn_mempool.go +++ b/internal/proxy/mocks/app_conn_mempool.go @@ -17,6 +17,29 @@ type AppConnMempool struct { mock.Mock } +// CheckTx provides a mock function with given fields: _a0, _a1 +func (_m *AppConnMempool) CheckTx(_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(context.Context, types.RequestCheckTx) *types.ResponseCheckTx); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseCheckTx) + } + } + + 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 +} + // CheckTxAsync provides a mock function with given fields: _a0, _a1 func (_m *AppConnMempool) CheckTxAsync(_a0 context.Context, _a1 types.RequestCheckTx) (*abciclient.ReqRes, error) { ret := _m.Called(_a0, _a1) @@ -40,29 +63,6 @@ func (_m *AppConnMempool) CheckTxAsync(_a0 context.Context, _a1 types.RequestChe return r0, r1 } -// 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(context.Context, types.RequestCheckTx) *types.ResponseCheckTx); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.ResponseCheckTx) - } - } - - 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 -} - // Error provides a mock function with given fields: func (_m *AppConnMempool) Error() error { ret := _m.Called() @@ -77,6 +77,20 @@ func (_m *AppConnMempool) Error() error { return r0 } +// Flush provides a mock function with given fields: _a0 +func (_m *AppConnMempool) Flush(_a0 context.Context) error { + ret := _m.Called(_a0) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // FlushAsync provides a mock function with given fields: _a0 func (_m *AppConnMempool) FlushAsync(_a0 context.Context) (*abciclient.ReqRes, error) { ret := _m.Called(_a0) @@ -100,20 +114,6 @@ func (_m *AppConnMempool) FlushAsync(_a0 context.Context) (*abciclient.ReqRes, e return r0, r1 } -// 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(context.Context) error); ok { - r0 = rf(_a0) - } else { - r0 = ret.Error(0) - } - - return r0 -} - // SetResponseCallback provides a mock function with given fields: _a0 func (_m *AppConnMempool) SetResponseCallback(_a0 abciclient.Callback) { _m.Called(_a0) diff --git a/internal/proxy/mocks/app_conn_query.go b/internal/proxy/mocks/app_conn_query.go index 47ac5bef9..e515cb784 100644 --- a/internal/proxy/mocks/app_conn_query.go +++ b/internal/proxy/mocks/app_conn_query.go @@ -15,8 +15,8 @@ type AppConnQuery struct { mock.Mock } -// EchoSync provides a mock function with given fields: _a0, _a1 -func (_m *AppConnQuery) EchoSync(_a0 context.Context, _a1 string) (*types.ResponseEcho, error) { +// Echo provides a mock function with given fields: _a0, _a1 +func (_m *AppConnQuery) Echo(_a0 context.Context, _a1 string) (*types.ResponseEcho, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseEcho @@ -52,8 +52,8 @@ func (_m *AppConnQuery) Error() error { return r0 } -// InfoSync provides a mock function with given fields: _a0, _a1 -func (_m *AppConnQuery) InfoSync(_a0 context.Context, _a1 types.RequestInfo) (*types.ResponseInfo, error) { +// Info provides a mock function with given fields: _a0, _a1 +func (_m *AppConnQuery) Info(_a0 context.Context, _a1 types.RequestInfo) (*types.ResponseInfo, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseInfo @@ -75,8 +75,8 @@ func (_m *AppConnQuery) InfoSync(_a0 context.Context, _a1 types.RequestInfo) (*t return r0, r1 } -// QuerySync provides a mock function with given fields: _a0, _a1 -func (_m *AppConnQuery) QuerySync(_a0 context.Context, _a1 types.RequestQuery) (*types.ResponseQuery, error) { +// Query provides a mock function with given fields: _a0, _a1 +func (_m *AppConnQuery) Query(_a0 context.Context, _a1 types.RequestQuery) (*types.ResponseQuery, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseQuery diff --git a/internal/proxy/mocks/app_conn_snapshot.go b/internal/proxy/mocks/app_conn_snapshot.go index 0b6f10ce1..0b3f06ad7 100644 --- a/internal/proxy/mocks/app_conn_snapshot.go +++ b/internal/proxy/mocks/app_conn_snapshot.go @@ -15,8 +15,8 @@ type AppConnSnapshot struct { mock.Mock } -// ApplySnapshotChunkSync provides a mock function with given fields: _a0, _a1 -func (_m *AppConnSnapshot) ApplySnapshotChunkSync(_a0 context.Context, _a1 types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { +// ApplySnapshotChunk provides a mock function with given fields: _a0, _a1 +func (_m *AppConnSnapshot) ApplySnapshotChunk(_a0 context.Context, _a1 types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseApplySnapshotChunk @@ -52,8 +52,8 @@ func (_m *AppConnSnapshot) Error() error { return r0 } -// ListSnapshotsSync provides a mock function with given fields: _a0, _a1 -func (_m *AppConnSnapshot) ListSnapshotsSync(_a0 context.Context, _a1 types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { +// ListSnapshots provides a mock function with given fields: _a0, _a1 +func (_m *AppConnSnapshot) ListSnapshots(_a0 context.Context, _a1 types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseListSnapshots @@ -75,8 +75,8 @@ func (_m *AppConnSnapshot) ListSnapshotsSync(_a0 context.Context, _a1 types.Requ return r0, r1 } -// LoadSnapshotChunkSync provides a mock function with given fields: _a0, _a1 -func (_m *AppConnSnapshot) LoadSnapshotChunkSync(_a0 context.Context, _a1 types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { +// LoadSnapshotChunk provides a mock function with given fields: _a0, _a1 +func (_m *AppConnSnapshot) LoadSnapshotChunk(_a0 context.Context, _a1 types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseLoadSnapshotChunk @@ -98,8 +98,8 @@ func (_m *AppConnSnapshot) LoadSnapshotChunkSync(_a0 context.Context, _a1 types. return r0, r1 } -// OfferSnapshotSync provides a mock function with given fields: _a0, _a1 -func (_m *AppConnSnapshot) OfferSnapshotSync(_a0 context.Context, _a1 types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { +// OfferSnapshot provides a mock function with given fields: _a0, _a1 +func (_m *AppConnSnapshot) OfferSnapshot(_a0 context.Context, _a1 types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { ret := _m.Called(_a0, _a1) var r0 *types.ResponseOfferSnapshot diff --git a/internal/rpc/core/abci.go b/internal/rpc/core/abci.go index 783a78cb3..cbd27a09d 100644 --- a/internal/rpc/core/abci.go +++ b/internal/rpc/core/abci.go @@ -18,7 +18,7 @@ func (env *Environment) ABCIQuery( height int64, prove bool, ) (*coretypes.ResultABCIQuery, error) { - resQuery, err := env.ProxyAppQuery.QuerySync(ctx, abci.RequestQuery{ + resQuery, err := env.ProxyAppQuery.Query(ctx, abci.RequestQuery{ Path: path, Data: data, Height: height, @@ -34,7 +34,7 @@ func (env *Environment) ABCIQuery( // ABCIInfo gets some info about the application. // More: https://docs.tendermint.com/master/rpc/#/ABCI/abci_info func (env *Environment) ABCIInfo(ctx context.Context) (*coretypes.ResultABCIInfo, error) { - resInfo, err := env.ProxyAppQuery.InfoSync(ctx, proxy.RequestInfo) + resInfo, err := env.ProxyAppQuery.Info(ctx, proxy.RequestInfo) if err != nil { return nil, err } diff --git a/internal/rpc/core/mempool.go b/internal/rpc/core/mempool.go index 4087439cb..9b75e044e 100644 --- a/internal/rpc/core/mempool.go +++ b/internal/rpc/core/mempool.go @@ -153,7 +153,7 @@ func (env *Environment) NumUnconfirmedTxs(ctx context.Context) (*coretypes.Resul // be added to the mempool either. // More: https://docs.tendermint.com/master/rpc/#/Tx/check_tx func (env *Environment) CheckTx(ctx context.Context, tx types.Tx) (*coretypes.ResultCheckTx, error) { - res, err := env.ProxyAppMempool.CheckTxSync(ctx, abci.RequestCheckTx{Tx: tx}) + res, err := env.ProxyAppMempool.CheckTx(ctx, abci.RequestCheckTx{Tx: tx}) if err != nil { return nil, err } diff --git a/internal/state/execution.go b/internal/state/execution.go index f80d2fa9a..96a680a5b 100644 --- a/internal/state/execution.go +++ b/internal/state/execution.go @@ -255,9 +255,9 @@ func (blockExec *BlockExecutor) Commit( } // Commit block, get hash back - res, err := blockExec.proxyApp.CommitSync(ctx) + res, err := blockExec.proxyApp.Commit(ctx) if err != nil { - blockExec.logger.Error("client error during proxyAppConn.CommitSync", "err", err) + blockExec.logger.Error("client error during proxyAppConn.Commit", "err", err) return nil, 0, err } @@ -302,26 +302,6 @@ func execBlockOnProxyApp( dtxs := make([]*abci.ResponseDeliverTx, len(block.Txs)) abciResponses.DeliverTxs = dtxs - // Execute transactions and get hash. - proxyCb := func(req *abci.Request, res *abci.Response) { - if r, ok := res.Value.(*abci.Response_DeliverTx); ok { - // TODO: make use of res.Log - // TODO: make use of this info - // Blocks may include invalid txs. - txRes := r.DeliverTx - if txRes.Code == abci.CodeTypeOK { - validTxs++ - } else { - logger.Debug("invalid tx", "code", txRes.Code, "log", txRes.Log) - invalidTxs++ - } - - abciResponses.DeliverTxs[txIndex] = txRes - txIndex++ - } - } - proxyAppConn.SetResponseCallback(proxyCb) - commitInfo := getBeginBlockValidatorInfo(block, store, initialHeight) byzVals := make([]abci.Evidence, 0) @@ -336,7 +316,7 @@ func execBlockOnProxyApp( return nil, errors.New("nil header") } - abciResponses.BeginBlock, err = proxyAppConn.BeginBlockSync( + abciResponses.BeginBlock, err = proxyAppConn.BeginBlock( ctx, abci.RequestBeginBlock{ Hash: block.Hash(), @@ -352,13 +332,22 @@ func execBlockOnProxyApp( // run txs of block for _, tx := range block.Txs { - _, err = proxyAppConn.DeliverTxAsync(ctx, abci.RequestDeliverTx{Tx: tx}) + resp, err := proxyAppConn.DeliverTx(ctx, abci.RequestDeliverTx{Tx: tx}) if err != nil { return nil, err } + if resp.Code == abci.CodeTypeOK { + validTxs++ + } else { + logger.Debug("invalid tx", "code", resp.Code, "log", resp.Log) + invalidTxs++ + } + + abciResponses.DeliverTxs[txIndex] = resp + txIndex++ } - abciResponses.EndBlock, err = proxyAppConn.EndBlockSync(ctx, abci.RequestEndBlock{Height: block.Height}) + abciResponses.EndBlock, err = proxyAppConn.EndBlock(ctx, abci.RequestEndBlock{Height: block.Height}) if err != nil { logger.Error("error in proxyAppConn.EndBlock", "err", err) return nil, err @@ -604,9 +593,9 @@ func ExecCommitBlock( } // Commit block, get hash back - res, err := appConnConsensus.CommitSync(ctx) + res, err := appConnConsensus.Commit(ctx) if err != nil { - logger.Error("client error during proxyAppConn.CommitSync", "err", res) + logger.Error("client error during proxyAppConn.Commit", "err", res) return nil, err } diff --git a/internal/statesync/dispatcher.go b/internal/statesync/dispatcher.go index b12922343..9cdb34978 100644 --- a/internal/statesync/dispatcher.go +++ b/internal/statesync/dispatcher.go @@ -224,6 +224,9 @@ func (p *BlockProvider) ReportEvidence(ctx context.Context, ev types.Evidence) e // String implements stringer interface func (p *BlockProvider) String() string { return string(p.peer) } +// Returns the ID address of the provider (NodeID of peer) +func (p *BlockProvider) ID() string { return string(p.peer) } + //---------------------------------------------------------------- // peerList is a rolling list of peers. This is used to distribute the load of diff --git a/internal/statesync/reactor.go b/internal/statesync/reactor.go index 6ca0cb6b7..b1e286ad8 100644 --- a/internal/statesync/reactor.go +++ b/internal/statesync/reactor.go @@ -618,7 +618,7 @@ func (r *Reactor) handleChunkMessage(ctx context.Context, envelope *p2p.Envelope "chunk", msg.Index, "peer", envelope.From, ) - resp, err := r.conn.LoadSnapshotChunkSync(ctx, abci.RequestLoadSnapshotChunk{ + resp, err := r.conn.LoadSnapshotChunk(ctx, abci.RequestLoadSnapshotChunk{ Height: msg.Height, Format: msg.Format, Chunk: msg.Index, @@ -911,7 +911,7 @@ func (r *Reactor) processPeerUpdates(ctx context.Context) { // recentSnapshots fetches the n most recent snapshots from the app func (r *Reactor) recentSnapshots(ctx context.Context, n uint32) ([]*snapshot, error) { - resp, err := r.conn.ListSnapshotsSync(ctx, abci.RequestListSnapshots{}) + resp, err := r.conn.ListSnapshots(ctx, abci.RequestListSnapshots{}) if err != nil { return nil, err } diff --git a/internal/statesync/reactor_test.go b/internal/statesync/reactor_test.go index 62900133c..c1ca87b2c 100644 --- a/internal/statesync/reactor_test.go +++ b/internal/statesync/reactor_test.go @@ -214,15 +214,15 @@ func TestReactor_Sync(t *testing.T) { rts := setup(ctx, t, nil, nil, nil, 2) chain := buildLightBlockChain(ctx, t, 1, 10, time.Now()) // app accepts any snapshot - rts.conn.On("OfferSnapshotSync", ctx, mock.AnythingOfType("types.RequestOfferSnapshot")). + rts.conn.On("OfferSnapshot", ctx, mock.AnythingOfType("types.RequestOfferSnapshot")). Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ACCEPT}, nil) // app accepts every chunk - rts.conn.On("ApplySnapshotChunkSync", ctx, mock.AnythingOfType("types.RequestApplySnapshotChunk")). + rts.conn.On("ApplySnapshotChunk", ctx, mock.AnythingOfType("types.RequestApplySnapshotChunk")). Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) // app query returns valid state app hash - rts.connQuery.On("InfoSync", mock.Anything, proxy.RequestInfo).Return(&abci.ResponseInfo{ + rts.connQuery.On("Info", mock.Anything, proxy.RequestInfo).Return(&abci.ResponseInfo{ AppVersion: testAppVersion, LastBlockHeight: snapshotHeight, LastBlockAppHash: chain[snapshotHeight+1].AppHash, @@ -317,7 +317,7 @@ func TestReactor_ChunkRequest(t *testing.T) { // mock ABCI connection to return local snapshots conn := &proxymocks.AppConnSnapshot{} - conn.On("LoadSnapshotChunkSync", mock.Anything, abci.RequestLoadSnapshotChunk{ + conn.On("LoadSnapshotChunk", mock.Anything, abci.RequestLoadSnapshotChunk{ Height: tc.request.Height, Format: tc.request.Format, Chunk: tc.request.Index, @@ -404,7 +404,7 @@ func TestReactor_SnapshotsRequest(t *testing.T) { // mock ABCI connection to return local snapshots conn := &proxymocks.AppConnSnapshot{} - conn.On("ListSnapshotsSync", mock.Anything, abci.RequestListSnapshots{}).Return(&abci.ResponseListSnapshots{ + conn.On("ListSnapshots", mock.Anything, abci.RequestListSnapshots{}).Return(&abci.ResponseListSnapshots{ Snapshots: tc.snapshots, }, nil) diff --git a/internal/statesync/syncer.go b/internal/statesync/syncer.go index de80fe1fa..c22a59c38 100644 --- a/internal/statesync/syncer.go +++ b/internal/statesync/syncer.go @@ -367,7 +367,7 @@ func (s *syncer) Sync(ctx context.Context, snapshot *snapshot, chunks *chunkQueu func (s *syncer) offerSnapshot(ctx context.Context, snapshot *snapshot) error { s.logger.Info("Offering snapshot to ABCI app", "height", snapshot.Height, "format", snapshot.Format, "hash", snapshot.Hash) - resp, err := s.conn.OfferSnapshotSync(ctx, abci.RequestOfferSnapshot{ + resp, err := s.conn.OfferSnapshot(ctx, abci.RequestOfferSnapshot{ Snapshot: &abci.Snapshot{ Height: snapshot.Height, Format: snapshot.Format, @@ -409,7 +409,7 @@ func (s *syncer) applyChunks(ctx context.Context, chunks *chunkQueue, start time return fmt.Errorf("failed to fetch chunk: %w", err) } - resp, err := s.conn.ApplySnapshotChunkSync(ctx, abci.RequestApplySnapshotChunk{ + resp, err := s.conn.ApplySnapshotChunk(ctx, abci.RequestApplySnapshotChunk{ Index: chunk.Index, Chunk: chunk.Chunk, Sender: string(chunk.Sender), @@ -550,7 +550,7 @@ func (s *syncer) requestChunk(ctx context.Context, snapshot *snapshot, chunk uin // 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(ctx context.Context, snapshot *snapshot) (uint64, error) { - resp, err := s.connQuery.InfoSync(ctx, proxy.RequestInfo) + resp, err := s.connQuery.Info(ctx, proxy.RequestInfo) if err != nil { return 0, fmt.Errorf("failed to query ABCI app for appHash: %w", err) } diff --git a/internal/statesync/syncer_test.go b/internal/statesync/syncer_test.go index 6e7b57213..46287ada1 100644 --- a/internal/statesync/syncer_test.go +++ b/internal/statesync/syncer_test.go @@ -110,7 +110,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", mock.Anything, abci.RequestOfferSnapshot{ + connSnapshot.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{ Snapshot: &abci.Snapshot{ Height: 2, Format: 2, @@ -119,7 +119,7 @@ func TestSyncer_SyncAny(t *testing.T) { }, AppHash: []byte("app_hash_2"), }).Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT_FORMAT}, nil) - connSnapshot.On("OfferSnapshotSync", mock.Anything, abci.RequestOfferSnapshot{ + connSnapshot.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{ Snapshot: &abci.Snapshot{ Height: s.Height, Format: s.Format, @@ -171,7 +171,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", mock.Anything, abci.RequestApplySnapshotChunk{ + connSnapshot.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{ Index: 2, Chunk: []byte{1, 1, 2}, }).Once().Run(func(args mock.Arguments) { time.Sleep(2 * time.Second) }).Return( &abci.ResponseApplySnapshotChunk{ @@ -179,16 +179,16 @@ func TestSyncer_SyncAny(t *testing.T) { RefetchChunks: []uint32{1}, }, nil) - connSnapshot.On("ApplySnapshotChunkSync", mock.Anything, abci.RequestApplySnapshotChunk{ + connSnapshot.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{ Index: 0, Chunk: []byte{1, 1, 0}, }).Times(2).Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) - connSnapshot.On("ApplySnapshotChunkSync", mock.Anything, abci.RequestApplySnapshotChunk{ + connSnapshot.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{ Index: 1, Chunk: []byte{1, 1, 1}, }).Times(2).Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) - connSnapshot.On("ApplySnapshotChunkSync", mock.Anything, abci.RequestApplySnapshotChunk{ + connSnapshot.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{ Index: 2, Chunk: []byte{1, 1, 2}, }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) - connQuery.On("InfoSync", mock.Anything, proxy.RequestInfo).Return(&abci.ResponseInfo{ + connQuery.On("Info", mock.Anything, proxy.RequestInfo).Return(&abci.ResponseInfo{ AppVersion: 9, LastBlockHeight: 1, LastBlockAppHash: []byte("app_hash"), @@ -252,7 +252,7 @@ func TestSyncer_SyncAny_abort(t *testing.T) { _, err := rts.syncer.AddSnapshot(peerID, s) require.NoError(t, err) - rts.conn.On("OfferSnapshotSync", mock.Anything, abci.RequestOfferSnapshot{ + rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{ Snapshot: toABCI(s), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ABORT}, nil) @@ -286,15 +286,15 @@ func TestSyncer_SyncAny_reject(t *testing.T) { _, err = rts.syncer.AddSnapshot(peerID, s11) require.NoError(t, err) - rts.conn.On("OfferSnapshotSync", mock.Anything, abci.RequestOfferSnapshot{ + rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{ Snapshot: toABCI(s22), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT}, nil) - rts.conn.On("OfferSnapshotSync", mock.Anything, abci.RequestOfferSnapshot{ + rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{ Snapshot: toABCI(s12), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT}, nil) - rts.conn.On("OfferSnapshotSync", mock.Anything, abci.RequestOfferSnapshot{ + rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{ Snapshot: toABCI(s11), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT}, nil) @@ -328,11 +328,11 @@ func TestSyncer_SyncAny_reject_format(t *testing.T) { _, err = rts.syncer.AddSnapshot(peerID, s11) require.NoError(t, err) - rts.conn.On("OfferSnapshotSync", mock.Anything, abci.RequestOfferSnapshot{ + rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{ Snapshot: toABCI(s22), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT_FORMAT}, nil) - rts.conn.On("OfferSnapshotSync", mock.Anything, abci.RequestOfferSnapshot{ + rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{ Snapshot: toABCI(s11), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ABORT}, nil) @@ -377,11 +377,11 @@ func TestSyncer_SyncAny_reject_sender(t *testing.T) { _, err = rts.syncer.AddSnapshot(peerCID, sbc) require.NoError(t, err) - rts.conn.On("OfferSnapshotSync", mock.Anything, abci.RequestOfferSnapshot{ + rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{ Snapshot: toABCI(sbc), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT_SENDER}, nil) - rts.conn.On("OfferSnapshotSync", mock.Anything, abci.RequestOfferSnapshot{ + rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{ Snapshot: toABCI(sa), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT}, nil) @@ -407,7 +407,7 @@ func TestSyncer_SyncAny_abciError(t *testing.T) { _, err := rts.syncer.AddSnapshot(peerID, s) require.NoError(t, err) - rts.conn.On("OfferSnapshotSync", mock.Anything, abci.RequestOfferSnapshot{ + rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{ Snapshot: toABCI(s), AppHash: []byte("app_hash"), }).Once().Return(nil, errBoom) @@ -450,7 +450,7 @@ func TestSyncer_offerSnapshot(t *testing.T) { rts := setup(ctx, t, nil, nil, stateProvider, 2) s := &snapshot{Height: 1, Format: 1, Chunks: 3, Hash: []byte{1, 2, 3}, trustedAppHash: []byte("app_hash")} - rts.conn.On("OfferSnapshotSync", mock.Anything, abci.RequestOfferSnapshot{ + rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{ Snapshot: toABCI(s), AppHash: []byte("app_hash"), }).Return(&abci.ResponseOfferSnapshot{Result: tc.result}, tc.err) @@ -511,11 +511,11 @@ func TestSyncer_applyChunks_Results(t *testing.T) { _, err = chunks.Add(&chunk{Height: 1, Format: 1, Index: 0, Chunk: body}) require.NoError(t, err) - rts.conn.On("ApplySnapshotChunkSync", mock.Anything, abci.RequestApplySnapshotChunk{ + rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{ Index: 0, Chunk: body, }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: tc.result}, tc.err) if tc.result == abci.ResponseApplySnapshotChunk_RETRY { - rts.conn.On("ApplySnapshotChunkSync", mock.Anything, abci.RequestApplySnapshotChunk{ + rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{ Index: 0, Chunk: body, }).Once().Return(&abci.ResponseApplySnapshotChunk{ Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) @@ -578,13 +578,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 - rts.conn.On("ApplySnapshotChunkSync", mock.Anything, abci.RequestApplySnapshotChunk{ + rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{ Index: 0, Chunk: []byte{0}, }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) - rts.conn.On("ApplySnapshotChunkSync", mock.Anything, abci.RequestApplySnapshotChunk{ + rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{ Index: 1, Chunk: []byte{1}, }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) - rts.conn.On("ApplySnapshotChunkSync", mock.Anything, abci.RequestApplySnapshotChunk{ + rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{ Index: 2, Chunk: []byte{2}, }).Once().Return(&abci.ResponseApplySnapshotChunk{ Result: tc.result, @@ -678,13 +678,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 - rts.conn.On("ApplySnapshotChunkSync", mock.Anything, abci.RequestApplySnapshotChunk{ + rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{ Index: 0, Chunk: []byte{0}, Sender: "aa", }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) - rts.conn.On("ApplySnapshotChunkSync", mock.Anything, abci.RequestApplySnapshotChunk{ + rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{ Index: 1, Chunk: []byte{1}, Sender: "bb", }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) - rts.conn.On("ApplySnapshotChunkSync", mock.Anything, abci.RequestApplySnapshotChunk{ + rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{ Index: 2, Chunk: []byte{2}, Sender: "cc", }).Once().Return(&abci.ResponseApplySnapshotChunk{ Result: tc.result, @@ -693,7 +693,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 { - rts.conn.On("ApplySnapshotChunkSync", mock.Anything, abci.RequestApplySnapshotChunk{ + rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{ Index: 2, Chunk: []byte{2}, Sender: "cc", }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) } @@ -759,7 +759,7 @@ func TestSyncer_verifyApp(t *testing.T) { rts := setup(ctx, t, nil, nil, nil, 2) - rts.connQuery.On("InfoSync", mock.Anything, proxy.RequestInfo).Return(tc.response, tc.err) + rts.connQuery.On("Info", mock.Anything, proxy.RequestInfo).Return(tc.response, tc.err) version, err := rts.syncer.verifyApp(ctx, s) unwrapped := errors.Unwrap(err) if unwrapped != nil { diff --git a/light/client.go b/light/client.go index 99a44f498..443b4d822 100644 --- a/light/client.go +++ b/light/client.go @@ -13,6 +13,7 @@ import ( tmmath "github.com/tendermint/tendermint/libs/math" "github.com/tendermint/tendermint/light/provider" "github.com/tendermint/tendermint/light/store" + "github.com/tendermint/tendermint/types" ) @@ -1146,3 +1147,29 @@ func (c *Client) providerShouldBeRemoved(err error) bool { errors.As(err, &provider.ErrBadLightBlock{}) || errors.Is(err, provider.ErrConnectionClosed) } + +func (c *Client) Status(ctx context.Context) *types.LightClientInfo { + chunks := make([]string, len(c.witnesses)) + + // If primary is in witness list we do not want to count it twice in the number of peers + primaryNotInWitnessList := 1 + for i, val := range c.witnesses { + chunks[i] = val.ID() + if chunks[i] == c.primary.ID() { + primaryNotInWitnessList = 0 + } + } + + return &types.LightClientInfo{ + PrimaryID: c.primary.ID(), + WitnessesID: chunks, + NumPeers: len(chunks) + primaryNotInWitnessList, + LastTrustedHeight: c.latestTrustedBlock.Height, + LastTrustedHash: c.latestTrustedBlock.Hash(), + LatestBlockTime: c.latestTrustedBlock.Time, + TrustingPeriod: c.trustingPeriod.String(), + // The caller of /status can deduce this from the two variables above + // Having a boolean flag improves readbility + TrustedBlockExpired: HeaderExpired(c.latestTrustedBlock.SignedHeader, c.trustingPeriod, time.Now()), + } +} diff --git a/light/client_benchmark_test.go b/light/client_benchmark_test.go index 59eb79766..ca0e402a0 100644 --- a/light/client_benchmark_test.go +++ b/light/client_benchmark_test.go @@ -61,6 +61,10 @@ func (impl *providerBenchmarkImpl) ReportEvidence(_ context.Context, _ types.Evi return errors.New("not implemented") } +// provierBenchmarkImpl does not have an ID iteself. +// Thus we return a sample string +func (impl *providerBenchmarkImpl) ID() string { return "ip-not-defined.com" } + func BenchmarkSequence(b *testing.B) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -168,4 +172,5 @@ func BenchmarkBackwards(b *testing.B) { b.Fatal(err) } } + } diff --git a/light/light_test.go b/light/light_test.go index 49a69ae47..00d0741ce 100644 --- a/light/light_test.go +++ b/light/light_test.go @@ -167,3 +167,93 @@ func waitForBlock(ctx context.Context, p provider.Provider, height int64) (*type } } } + +func TestClientStatusRPC(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + conf, err := rpctest.CreateConfig(t.Name()) + require.NoError(t, err) + + // Start a test application + app := kvstore.NewApplication() + + _, closer, err := rpctest.StartTendermint(ctx, conf, app, rpctest.SuppressStdout) + require.NoError(t, err) + defer func() { require.NoError(t, closer(ctx)) }() + + dbDir, err := os.MkdirTemp("", "light-client-test-status-example") + require.NoError(t, err) + t.Cleanup(func() { os.RemoveAll(dbDir) }) + + chainID := conf.ChainID() + + primary, err := httpp.New(chainID, conf.RPC.ListenAddress) + require.NoError(t, err) + + // give Tendermint time to generate some blocks + block, err := waitForBlock(ctx, primary, 2) + require.NoError(t, err) + + db, err := dbm.NewGoLevelDB("light-client-db", dbDir) + require.NoError(t, err) + + // In order to not create a full testnet to verify whether we get the correct IPs + // if we have more than one witness, we add the primary multiple times + // TODO This should be buggy behavior, we should not be allowed to add the same nodes as witnesses + witnesses := []provider.Provider{primary, primary, primary} + + c, err := light.NewClient(ctx, + chainID, + light.TrustOptions{ + Period: 504 * time.Hour, // 21 days + Height: 2, + Hash: block.Hash(), + }, + primary, + witnesses, + dbs.New(db), + light.Logger(log.TestingLogger()), + ) + require.NoError(t, err) + + defer func() { require.NoError(t, c.Cleanup()) }() + + lightStatus := c.Status(ctx) + + // Verify primary IP + require.True(t, lightStatus.PrimaryID == primary.ID()) + + // Verify IPs of witnesses + require.ElementsMatch(t, mapProviderArrayToIP(witnesses), lightStatus.WitnessesID) + + // Verify that number of peers is equal to number of witnesses (+ 1 if the primary is not a witness) + require.Equal(t, len(witnesses)+1*primaryNotInWitnessList(witnesses, primary), lightStatus.NumPeers) + + // Verify that the last trusted hash returned matches the stored hash of the trusted + // block at the last trusted height. + blockAtTrustedHeight, err := c.TrustedLightBlock(lightStatus.LastTrustedHeight) + require.NoError(t, err) + + require.EqualValues(t, lightStatus.LastTrustedHash, blockAtTrustedHeight.Hash()) + +} + +// Extract the IP address of all the providers within an array +func mapProviderArrayToIP(el []provider.Provider) []string { + ips := make([]string, len(el)) + for i, v := range el { + ips[i] = v.ID() + } + return ips +} + +// If the primary is not in the witness list, we will return 1 +// Otherwise, return 0 +func primaryNotInWitnessList(witnesses []provider.Provider, primary provider.Provider) int { + for _, el := range witnesses { + if el == primary { + return 0 + } + } + return 1 +} diff --git a/light/provider/http/http.go b/light/provider/http/http.go index 79bb56c56..cf443e1b5 100644 --- a/light/provider/http/http.go +++ b/light/provider/http/http.go @@ -100,7 +100,8 @@ func NewWithClientAndOptions(chainID string, client rpcclient.RemoteClient, opti } } -func (p *http) String() string { +// Identifies the provider with an IP in string format +func (p *http) ID() string { return fmt.Sprintf("http{%s}", p.client.Remote()) } diff --git a/light/provider/http/http_test.go b/light/provider/http/http_test.go index 71cd78563..8749d4a11 100644 --- a/light/provider/http/http_test.go +++ b/light/provider/http/http_test.go @@ -3,7 +3,6 @@ package http_test import ( "context" "errors" - "fmt" "testing" "time" @@ -22,15 +21,15 @@ import ( func TestNewProvider(t *testing.T) { c, err := lighthttp.New("chain-test", "192.168.0.1:26657") require.NoError(t, err) - require.Equal(t, fmt.Sprintf("%s", c), "http{http://192.168.0.1:26657}") + require.Equal(t, c.ID(), "http{http://192.168.0.1:26657}") c, err = lighthttp.New("chain-test", "http://153.200.0.1:26657") require.NoError(t, err) - require.Equal(t, fmt.Sprintf("%s", c), "http{http://153.200.0.1:26657}") + require.Equal(t, c.ID(), "http{http://153.200.0.1:26657}") c, err = lighthttp.New("chain-test", "153.200.0.1") require.NoError(t, err) - require.Equal(t, fmt.Sprintf("%s", c), "http{http://153.200.0.1}") + require.Equal(t, c.ID(), "http{http://153.200.0.1}") } func TestProvider(t *testing.T) { diff --git a/light/provider/mocks/provider.go b/light/provider/mocks/provider.go index aa36fa2d3..1b4e583de 100644 --- a/light/provider/mocks/provider.go +++ b/light/provider/mocks/provider.go @@ -15,6 +15,20 @@ type Provider struct { mock.Mock } +// ID provides a mock function with given fields: +func (_m *Provider) ID() string { + ret := _m.Called() + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + // LightBlock provides a mock function with given fields: ctx, height func (_m *Provider) LightBlock(ctx context.Context, height int64) (*types.LightBlock, error) { ret := _m.Called(ctx, height) diff --git a/light/provider/provider.go b/light/provider/provider.go index 7f15d5c75..d1b3304da 100644 --- a/light/provider/provider.go +++ b/light/provider/provider.go @@ -25,4 +25,8 @@ type Provider interface { // ReportEvidence reports an evidence of misbehavior. ReportEvidence(context.Context, types.Evidence) error + + // Returns the ID of a provider. For RPC providers it returns the IP address of the client + // For p2p providers it returns a combination of NodeID and IP address + ID() string } diff --git a/light/rpc/client.go b/light/rpc/client.go index 272100422..3aab77c99 100644 --- a/light/rpc/client.go +++ b/light/rpc/client.go @@ -32,6 +32,7 @@ type LightClient interface { Update(ctx context.Context, now time.Time) (*types.LightBlock, error) VerifyLightBlockAtHeight(ctx context.Context, height int64, now time.Time) (*types.LightBlock, error) TrustedLightBlock(height int64) (*types.LightBlock, error) + Status(ctx context.Context) *types.LightClientInfo } var _ rpcclient.Client = (*Client)(nil) @@ -124,8 +125,18 @@ func (c *Client) OnStop() { } } +// Returns the status of the light client. Previously this was querying the primary connected to the client +// As a consequence of this change, running /status on the light client will return nil for SyncInfo, NodeInfo +// and ValdiatorInfo. func (c *Client) Status(ctx context.Context) (*coretypes.ResultStatus, error) { - return c.next.Status(ctx) + lightClientInfo := c.lc.Status(ctx) + + return &coretypes.ResultStatus{ + NodeInfo: types.NodeInfo{}, + SyncInfo: coretypes.SyncInfo{}, + ValidatorInfo: coretypes.ValidatorInfo{}, + LightClientInfo: *lightClientInfo, + }, nil } func (c *Client) ABCIInfo(ctx context.Context) (*coretypes.ResultABCIInfo, error) { diff --git a/light/rpc/mocks/light_client.go b/light/rpc/mocks/light_client.go index cc32cf649..347d14707 100644 --- a/light/rpc/mocks/light_client.go +++ b/light/rpc/mocks/light_client.go @@ -31,6 +31,22 @@ func (_m *LightClient) ChainID() string { return r0 } +// Status provides a mock function with given fields: ctx +func (_m *LightClient) Status(ctx context.Context) *types.LightClientInfo { + ret := _m.Called(ctx) + + var r0 *types.LightClientInfo + if rf, ok := ret.Get(0).(func(context.Context) *types.LightClientInfo); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.LightClientInfo) + } + } + + return r0 +} + // TrustedLightBlock provides a mock function with given fields: height func (_m *LightClient) TrustedLightBlock(height int64) (*types.LightBlock, error) { ret := _m.Called(height) diff --git a/node/node.go b/node/node.go index b559f057f..4a900368d 100644 --- a/node/node.go +++ b/node/node.go @@ -754,7 +754,7 @@ func getRouterConfig(conf *config.Config, proxyApp proxy.AppConns) p2p.RouterOpt if conf.FilterPeers && proxyApp != nil { opts.FilterPeerByID = func(ctx context.Context, id types.NodeID) error { - res, err := proxyApp.Query().QuerySync(ctx, abci.RequestQuery{ + res, err := proxyApp.Query().Query(ctx, abci.RequestQuery{ Path: fmt.Sprintf("/p2p/filter/id/%s", id), }) if err != nil { @@ -768,7 +768,7 @@ func getRouterConfig(conf *config.Config, proxyApp proxy.AppConns) p2p.RouterOpt } opts.FilterPeerByIP = func(ctx context.Context, ip net.IP, port uint16) error { - res, err := proxyApp.Query().QuerySync(ctx, abci.RequestQuery{ + res, err := proxyApp.Query().Query(ctx, abci.RequestQuery{ Path: fmt.Sprintf("/p2p/filter/addr/%s", net.JoinHostPort(ip.String(), strconv.Itoa(int(port)))), }) if err != nil { diff --git a/node/setup.go b/node/setup.go index 6f3b3245a..68371c45a 100644 --- a/node/setup.go +++ b/node/setup.go @@ -305,6 +305,11 @@ func createPeerManager( nodeID types.NodeID, ) (*p2p.PeerManager, closer, error) { + selfAddr, err := p2p.ParseNodeAddress(nodeID.AddressString(cfg.P2P.ExternalAddress)) + if err != nil { + return nil, func() error { return nil }, fmt.Errorf("couldn't parse ExternalAddress %q: %w", cfg.P2P.ExternalAddress, err) + } + privatePeerIDs := make(map[types.NodeID]struct{}) for _, id := range tmstrings.SplitAndTrimEmpty(cfg.P2P.PrivatePeerIDs, ",", " ") { privatePeerIDs[types.NodeID(id)] = struct{}{} @@ -320,6 +325,7 @@ func createPeerManager( } options := p2p.PeerManagerOptions{ + SelfAddress: selfAddr, MaxConnected: maxConns, MaxConnectedUpgrade: 4, MaxPeers: 1000, diff --git a/privval/file.go b/privval/file.go index b11346dc7..d5c959b9b 100644 --- a/privval/file.go +++ b/privval/file.go @@ -99,14 +99,14 @@ type FilePVLastSignState struct { filePath string } -// CheckHRS checks the given height, round, step (HRS) against that of the +// checkHRS checks the given height, round, step (HRS) against that of the // FilePVLastSignState. It returns an error if the arguments constitute a regression, // or if they match but the SignBytes are empty. // The returned boolean indicates whether the last Signature should be reused - // it returns true if the HRS matches the arguments and the SignBytes are not empty (indicating // we have already signed for this HRS, and can reuse the existing signature). // It panics if the HRS matches the arguments, there's a SignBytes, but no Signature. -func (lss *FilePVLastSignState) CheckHRS(height int64, round int32, step int8) (bool, error) { +func (lss *FilePVLastSignState) checkHRS(height int64, round int32, step int8) (bool, error) { if lss.Height > height { return false, fmt.Errorf("height regression. Got %v, last height %v", height, lss.Height) @@ -345,7 +345,7 @@ func (pv *FilePV) signVote(chainID string, vote *tmproto.Vote) error { round := vote.Round lss := pv.LastSignState - sameHRS, err := lss.CheckHRS(height, round, step) + sameHRS, err := lss.checkHRS(height, round, step) if err != nil { return err } @@ -371,8 +371,8 @@ func (pv *FilePV) signVote(chainID string, vote *tmproto.Vote) error { vote.Timestamp = timestamp vote.Signature = lss.Signature - return nil } + return nil } // It passed the checks. Sign the vote @@ -388,14 +388,12 @@ func (pv *FilePV) signVote(chainID string, vote *tmproto.Vote) error { } // signProposal checks if the proposal is good to sign and sets the proposal signature. -// It may need to set the timestamp as well if the proposal is otherwise the same as -// a previously signed proposal ie. we crashed after signing but before the proposal hit the WAL). func (pv *FilePV) signProposal(chainID string, proposal *tmproto.Proposal) error { height, round, step := proposal.Height, proposal.Round, stepPropose lss := pv.LastSignState - sameHRS, err := lss.CheckHRS(height, round, step) + sameHRS, err := lss.checkHRS(height, round, step) if err != nil { return err } @@ -405,23 +403,12 @@ func (pv *FilePV) signProposal(chainID string, proposal *tmproto.Proposal) error // We might crash before writing to the wal, // causing us to try to re-sign for the same HRS. // If signbytes are the same, use the last signature. - // If they only differ by timestamp, use last timestamp and signature - // Otherwise, return error if sameHRS { - if bytes.Equal(signBytes, lss.SignBytes) { - proposal.Signature = lss.Signature - } else { - timestamp, ok, err := checkProposalsOnlyDifferByTimestamp(lss.SignBytes, signBytes) - if err != nil { - return err - } - if !ok { - return errors.New("conflicting data") - } - proposal.Timestamp = timestamp - proposal.Signature = lss.Signature - return nil + if !bytes.Equal(signBytes, lss.SignBytes) { + return errors.New("conflicting data") } + proposal.Signature = lss.Signature + return nil } // It passed the checks. Sign the proposal @@ -467,23 +454,3 @@ func checkVotesOnlyDifferByTimestamp(lastSignBytes, newSignBytes []byte) (time.T return lastTime, proto.Equal(&newVote, &lastVote), nil } - -// returns the timestamp from the lastSignBytes. -// returns true if the only difference in the proposals is their timestamp -func checkProposalsOnlyDifferByTimestamp(lastSignBytes, newSignBytes []byte) (time.Time, bool, error) { - var lastProposal, newProposal tmproto.CanonicalProposal - if err := protoio.UnmarshalDelimited(lastSignBytes, &lastProposal); err != nil { - return time.Time{}, false, fmt.Errorf("LastSignBytes cannot be unmarshalled into proposal: %w", err) - } - if err := protoio.UnmarshalDelimited(newSignBytes, &newProposal); err != nil { - return time.Time{}, false, fmt.Errorf("signBytes cannot be unmarshalled into proposal: %w", err) - } - - lastTime := lastProposal.Timestamp - // set the times to the same value and check equality - now := tmtime.Now() - lastProposal.Timestamp = now - newProposal.Timestamp = now - - return lastTime, proto.Equal(&newProposal, &lastProposal), nil -} diff --git a/privval/file_test.go b/privval/file_test.go index 655a3d9b8..e51b488cb 100644 --- a/privval/file_test.go +++ b/privval/file_test.go @@ -234,7 +234,8 @@ func TestSignProposal(t *testing.T) { height, round := int64(10), int32(1) // sign a proposal for first time - proposal := newProposal(height, round, block1) + ts := tmtime.Now() + proposal := newProposal(height, round, block1, ts) pbp := proposal.ToProto() err = privVal.SignProposal(ctx, "mychainid", pbp) @@ -246,23 +247,17 @@ func TestSignProposal(t *testing.T) { // now try some bad Proposals cases := []*types.Proposal{ - newProposal(height, round-1, block1), // round regression - newProposal(height-1, round, block1), // height regression - newProposal(height-2, round+4, block1), // height regression and different round - newProposal(height, round, block2), // different block + newProposal(height, round-1, block1, ts), // round regression + newProposal(height-1, round, block1, ts), // height regression + newProposal(height-2, round+4, block1, ts), // height regression and different round + newProposal(height, round, block2, ts), // different block + newProposal(height, round, block1, ts.Add(time.Second)), // different timestamp } for _, c := range cases { - assert.Error(t, privVal.SignProposal(ctx, "mychainid", c.ToProto()), + assert.Errorf(t, privVal.SignProposal(ctx, "mychainid", c.ToProto()), "expected error on signing conflicting proposal") } - - // try signing a proposal with a different time stamp - sig := proposal.Signature - proposal.Timestamp = proposal.Timestamp.Add(time.Duration(1000)) - err = privVal.SignProposal(ctx, "mychainid", pbp) - assert.NoError(t, err) - assert.Equal(t, sig, proposal.Signature) } func TestDifferByTimestamp(t *testing.T) { @@ -277,33 +272,9 @@ func TestDifferByTimestamp(t *testing.T) { privVal, err := GenFilePV(tempKeyFile.Name(), tempStateFile.Name(), "") require.NoError(t, err) randbytes := tmrand.Bytes(tmhash.Size) - block1 := types.BlockID{Hash: randbytes, PartSetHeader: types.PartSetHeader{Total: 5, Hash: randbytes}} height, round := int64(10), int32(1) chainID := "mychainid" - // test proposal - { - proposal := newProposal(height, round, block1) - pb := proposal.ToProto() - err := privVal.SignProposal(ctx, chainID, pb) - require.NoError(t, err, "expected no error signing proposal") - signBytes := types.ProposalSignBytes(chainID, pb) - - sig := proposal.Signature - timeStamp := proposal.Timestamp - - // manipulate the timestamp. should get changed back - pb.Timestamp = pb.Timestamp.Add(time.Millisecond) - var emptySig []byte - proposal.Signature = emptySig - err = privVal.SignProposal(ctx, "mychainid", pb) - require.NoError(t, err, "expected no error on signing same proposal") - - assert.Equal(t, timeStamp, pb.Timestamp) - assert.Equal(t, signBytes, types.ProposalSignBytes(chainID, pb)) - assert.Equal(t, sig, proposal.Signature) - } - // test vote { voteType := tmproto.PrevoteType @@ -343,11 +314,11 @@ func newVote(addr types.Address, idx int32, height int64, round int32, } } -func newProposal(height int64, round int32, blockID types.BlockID) *types.Proposal { +func newProposal(height int64, round int32, blockID types.BlockID, t time.Time) *types.Proposal { return &types.Proposal{ Height: height, Round: round, BlockID: blockID, - Timestamp: tmtime.Now(), + Timestamp: t, } } diff --git a/rpc/client/mocks/client.go b/rpc/client/mocks/client.go index e638980a8..a74b6438f 100644 --- a/rpc/client/mocks/client.go +++ b/rpc/client/mocks/client.go @@ -713,13 +713,13 @@ func (_m *Client) TxSearch(ctx context.Context, query string, prove bool, page * return r0, r1 } -// UnconfirmedTxs provides a mock function with given fields: ctx, limit -func (_m *Client) UnconfirmedTxs(ctx context.Context, limit *int) (*coretypes.ResultUnconfirmedTxs, error) { - ret := _m.Called(ctx, limit) +// UnconfirmedTxs provides a mock function with given fields: ctx, page, perPage +func (_m *Client) UnconfirmedTxs(ctx context.Context, page *int, perPage *int) (*coretypes.ResultUnconfirmedTxs, error) { + ret := _m.Called(ctx, page, perPage) var r0 *coretypes.ResultUnconfirmedTxs - if rf, ok := ret.Get(0).(func(context.Context, *int) *coretypes.ResultUnconfirmedTxs); ok { - r0 = rf(ctx, limit) + if rf, ok := ret.Get(0).(func(context.Context, *int, *int) *coretypes.ResultUnconfirmedTxs); ok { + r0 = rf(ctx, page, perPage) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*coretypes.ResultUnconfirmedTxs) @@ -727,8 +727,8 @@ func (_m *Client) UnconfirmedTxs(ctx context.Context, limit *int) (*coretypes.Re } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *int) error); ok { - r1 = rf(ctx, limit) + if rf, ok := ret.Get(1).(func(context.Context, *int, *int) error); ok { + r1 = rf(ctx, page, perPage) } else { r1 = ret.Error(1) } diff --git a/rpc/coretypes/responses.go b/rpc/coretypes/responses.go index 223a25ff7..47649557c 100644 --- a/rpc/coretypes/responses.go +++ b/rpc/coretypes/responses.go @@ -124,9 +124,10 @@ type ValidatorInfo struct { // Node Status type ResultStatus struct { - NodeInfo types.NodeInfo `json:"node_info"` - SyncInfo SyncInfo `json:"sync_info"` - ValidatorInfo ValidatorInfo `json:"validator_info"` + NodeInfo types.NodeInfo `json:"node_info"` + SyncInfo SyncInfo `json:"sync_info"` + ValidatorInfo ValidatorInfo `json:"validator_info"` + LightClientInfo types.LightClientInfo `json:"light_client_info,omitempty"` } // Is TxIndexing enabled diff --git a/test/docker/Dockerfile b/test/docker/Dockerfile index 9110b4bf5..6d472db4c 100644 --- a/test/docker/Dockerfile +++ b/test/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.16 +FROM golang:1.17 # Grab deps (jq, hexdump, xxd, killall) RUN apt-get update && \ diff --git a/test/e2e/runner/rpc.go b/test/e2e/runner/rpc.go index f6a32b114..4ca8cc016 100644 --- a/test/e2e/runner/rpc.go +++ b/test/e2e/runner/rpc.go @@ -128,6 +128,8 @@ func waitForHeight(ctx context.Context, testnet *e2e.Testnet, height int64) (*ty // waitForNode waits for a node to become available and catch up to the given block height. func waitForNode(ctx context.Context, node *e2e.Node, height int64) (*rpctypes.ResultStatus, error) { + // If the node is the light client or seed note, we do not check for the last height. + // The light client and seed note can be behind the full node and validator if node.Mode == e2e.ModeSeed { return nil, nil } @@ -167,7 +169,10 @@ func waitForNode(ctx context.Context, node *e2e.Node, height int64) (*rpctypes.R return nil, fmt.Errorf("timed out waiting for %v to reach height %v", node.Name, height) case errors.Is(err, context.Canceled): return nil, err - case err == nil && status.SyncInfo.LatestBlockHeight >= height: + // If the node is the light client, it is not essential to wait for it to catch up, but we must return status info + case err == nil && node.Mode == e2e.ModeLight: + return status, nil + case err == nil && node.Mode != e2e.ModeLight && status.SyncInfo.LatestBlockHeight >= height: return status, nil case counter%500 == 0: switch { diff --git a/test/e2e/runner/start.go b/test/e2e/runner/start.go index 967d2519c..43ff2eef3 100644 --- a/test/e2e/runner/start.go +++ b/test/e2e/runner/start.go @@ -118,8 +118,17 @@ func Start(ctx context.Context, testnet *e2e.Testnet) error { wcancel() node.HasStarted = true + + var lastNodeHeight int64 + + // If the node is a light client, we fetch its current height + if node.Mode == e2e.ModeLight { + lastNodeHeight = status.LightClientInfo.LastTrustedHeight + } else { + lastNodeHeight = status.SyncInfo.LatestBlockHeight + } logger.Info(fmt.Sprintf("Node %v up on http://127.0.0.1:%v at height %v", - node.Name, node.ProxyPort, status.SyncInfo.LatestBlockHeight)) + node.Name, node.ProxyPort, lastNodeHeight)) } return nil diff --git a/types/light.go b/types/light.go index 5a650a159..3b1ddfcbe 100644 --- a/types/light.go +++ b/types/light.go @@ -4,10 +4,26 @@ import ( "bytes" "errors" "fmt" + "time" + tbytes "github.com/tendermint/tendermint/libs/bytes" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) +// Info about the status of the light client +type LightClientInfo struct { + PrimaryID string `json:"primaryID"` + WitnessesID []string `json:"witnessesID"` + NumPeers int `json:"number_of_peers,string"` + LastTrustedHeight int64 `json:"last_trusted_height,string"` + LastTrustedHash tbytes.HexBytes `json:"last_trusted_hash"` + LatestBlockTime time.Time `json:"latest_block_time"` + TrustingPeriod string `json:"trusting_period"` + // Boolean that reflects whether LatestBlockTime + trusting period is before + // time.Now() (time when /status is called) + TrustedBlockExpired bool `json:"trusted_block_expired"` +} + // LightBlock is a SignedHeader and a ValidatorSet. // It is the basis of the light client type LightBlock struct {