diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 77940da8a..842322e19 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -7,6 +7,8 @@ - CLI/RPC/Config - Apps + - [abci] \#9468 Introduce `FinalizeBlock` which condenses `BeginBlock`, `DeliverTx` and `EndBlock` + into a single method call (@cmwaters) - P2P Protocol diff --git a/abci/client/client.go b/abci/client/client.go index cffb62f12..27bf68c1d 100644 --- a/abci/client/client.go +++ b/abci/client/client.go @@ -1,6 +1,7 @@ package abcicli import ( + "context" "fmt" "sync" @@ -16,50 +17,28 @@ const ( //go:generate ../../scripts/mockery_generate.sh Client -// Client defines an interface for an ABCI client. -// All `Async` methods return a `ReqRes` object. -// All `Sync` methods return the appropriate protobuf ResponseXxx struct and an error. -// Note these are client errors, eg. ABCI socket connectivity issues. -// Application-related errors are reflected in response via ABCI error codes and logs. +// Client defines the interface for an ABCI client. +// +// NOTE these are client errors, eg. ABCI socket connectivity issues. +// Application-related errors are reflected in response via ABCI error codes +// and (potentially) error response. type Client interface { service.Service + types.Application - SetResponseCallback(Callback) + // TODO: remove as each method now returns an error Error() error + // TODO: remove as this is not implemented + Flush(context.Context) error + Echo(context.Context, string) (*types.ResponseEcho, error) - FlushAsync() *ReqRes - EchoAsync(msg string) *ReqRes - InfoAsync(types.RequestInfo) *ReqRes - DeliverTxAsync(types.RequestDeliverTx) *ReqRes - CheckTxAsync(types.RequestCheckTx) *ReqRes - QueryAsync(types.RequestQuery) *ReqRes - CommitAsync() *ReqRes - InitChainAsync(types.RequestInitChain) *ReqRes - PrepareProposalAsync(types.RequestPrepareProposal) *ReqRes - BeginBlockAsync(types.RequestBeginBlock) *ReqRes - EndBlockAsync(types.RequestEndBlock) *ReqRes - ListSnapshotsAsync(types.RequestListSnapshots) *ReqRes - OfferSnapshotAsync(types.RequestOfferSnapshot) *ReqRes - LoadSnapshotChunkAsync(types.RequestLoadSnapshotChunk) *ReqRes - ApplySnapshotChunkAsync(types.RequestApplySnapshotChunk) *ReqRes - ProcessProposalAsync(types.RequestProcessProposal) *ReqRes - - FlushSync() error - EchoSync(msg string) (*types.ResponseEcho, error) - InfoSync(types.RequestInfo) (*types.ResponseInfo, error) - DeliverTxSync(types.RequestDeliverTx) (*types.ResponseDeliverTx, error) - CheckTxSync(types.RequestCheckTx) (*types.ResponseCheckTx, error) - QuerySync(types.RequestQuery) (*types.ResponseQuery, error) - CommitSync() (*types.ResponseCommit, error) - InitChainSync(types.RequestInitChain) (*types.ResponseInitChain, error) - PrepareProposalSync(types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) - BeginBlockSync(types.RequestBeginBlock) (*types.ResponseBeginBlock, error) - EndBlockSync(types.RequestEndBlock) (*types.ResponseEndBlock, error) - ListSnapshotsSync(types.RequestListSnapshots) (*types.ResponseListSnapshots, error) - OfferSnapshotSync(types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) - LoadSnapshotChunkSync(types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) - ApplySnapshotChunkSync(types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) - ProcessProposalSync(types.RequestProcessProposal) (*types.ResponseProcessProposal, error) + // FIXME: All other operations are run synchronously and rely + // on the caller to dictate concurrency (i.e. run a go routine), + // with the exception of `CheckTxAsync` which we maintain + // for the v0 mempool. We should explore refactoring the + // mempool to remove this vestige behavior. + SetResponseCallback(Callback) + CheckTxAsync(context.Context, *types.RequestCheckTx) (*ReqRes, error) } //---------------------------------------- diff --git a/abci/client/grpc_client.go b/abci/client/grpc_client.go index 1258f013f..26fbf6337 100644 --- a/abci/client/grpc_client.go +++ b/abci/client/grpc_client.go @@ -1,18 +1,18 @@ package abcicli import ( + "context" "fmt" "net" "sync" "time" - "golang.org/x/net/context" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "github.com/tendermint/tendermint/abci/types" tmnet "github.com/tendermint/tendermint/libs/net" "github.com/tendermint/tendermint/libs/service" - tmsync "github.com/tendermint/tendermint/libs/sync" ) var _ Client = (*grpcClient)(nil) @@ -23,11 +23,11 @@ type grpcClient struct { service.BaseService mustConnect bool - client types.ABCIApplicationClient + client types.ABCIClient conn *grpc.ClientConn chReqRes chan *ReqRes // dispatches "async" responses to callbacks *in order*, needed by mempool - mtx tmsync.Mutex + mtx sync.Mutex addr string err error resCb func(*types.Request, *types.Response) // listens to all callbacks @@ -87,8 +87,10 @@ func (cli *grpcClient) OnStart() error { RETRY_LOOP: for { - //nolint:staticcheck // SA1019 Existing use of deprecated but supported dial option. - conn, err := grpc.Dial(cli.addr, grpc.WithInsecure(), grpc.WithContextDialer(dialerFunc)) + conn, err := grpc.Dial(cli.addr, + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithContextDialer(dialerFunc), + ) if err != nil { if cli.mustConnect { return err @@ -99,7 +101,7 @@ RETRY_LOOP: } cli.Logger.Info("Dialed server. Waiting for echo.", "addr", cli.addr) - client := types.NewABCIApplicationClient(conn) + client := types.NewABCIClient(conn) cli.conn = conn ENSURE_CONNECTED: @@ -158,156 +160,14 @@ func (cli *grpcClient) SetResponseCallback(resCb Callback) { } //---------------------------------------- -// GRPC calls are synchronous, but some callbacks expect to be called asynchronously -// (eg. the mempool expects to be able to lock to remove bad txs from cache). -// To accommodate, we finish each call in its own go-routine, -// which is expensive, but easy - if you want something better, use the socket protocol! -// maybe one day, if people really want it, we use grpc streams, -// but hopefully not :D -func (cli *grpcClient) EchoAsync(msg string) *ReqRes { - req := types.ToRequestEcho(msg) - res, err := cli.client.Echo(context.Background(), req.GetEcho(), grpc.WaitForReady(true)) +func (cli *grpcClient) CheckTxAsync(ctx context.Context, req *types.RequestCheckTx) (*ReqRes, error) { + res, err := cli.client.CheckTx(ctx, req, grpc.WaitForReady(true)) if err != nil { cli.StopForError(err) + return nil, err } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_Echo{Echo: res}}) -} - -func (cli *grpcClient) FlushAsync() *ReqRes { - req := types.ToRequestFlush() - res, err := cli.client.Flush(context.Background(), req.GetFlush(), grpc.WaitForReady(true)) - if err != nil { - cli.StopForError(err) - } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_Flush{Flush: res}}) -} - -func (cli *grpcClient) InfoAsync(params types.RequestInfo) *ReqRes { - req := types.ToRequestInfo(params) - res, err := cli.client.Info(context.Background(), req.GetInfo(), grpc.WaitForReady(true)) - if err != nil { - cli.StopForError(err) - } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_Info{Info: res}}) -} - -func (cli *grpcClient) DeliverTxAsync(params types.RequestDeliverTx) *ReqRes { - req := types.ToRequestDeliverTx(params) - res, err := cli.client.DeliverTx(context.Background(), req.GetDeliverTx(), grpc.WaitForReady(true)) - if err != nil { - cli.StopForError(err) - } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_DeliverTx{DeliverTx: res}}) -} - -func (cli *grpcClient) CheckTxAsync(params types.RequestCheckTx) *ReqRes { - req := types.ToRequestCheckTx(params) - res, err := cli.client.CheckTx(context.Background(), req.GetCheckTx(), grpc.WaitForReady(true)) - if err != nil { - cli.StopForError(err) - } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_CheckTx{CheckTx: res}}) -} - -func (cli *grpcClient) QueryAsync(params types.RequestQuery) *ReqRes { - req := types.ToRequestQuery(params) - res, err := cli.client.Query(context.Background(), req.GetQuery(), grpc.WaitForReady(true)) - if err != nil { - cli.StopForError(err) - } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_Query{Query: res}}) -} - -func (cli *grpcClient) CommitAsync() *ReqRes { - req := types.ToRequestCommit() - res, err := cli.client.Commit(context.Background(), req.GetCommit(), grpc.WaitForReady(true)) - if err != nil { - cli.StopForError(err) - } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_Commit{Commit: res}}) -} - -func (cli *grpcClient) InitChainAsync(params types.RequestInitChain) *ReqRes { - req := types.ToRequestInitChain(params) - res, err := cli.client.InitChain(context.Background(), req.GetInitChain(), grpc.WaitForReady(true)) - if err != nil { - cli.StopForError(err) - } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_InitChain{InitChain: res}}) -} - -func (cli *grpcClient) BeginBlockAsync(params types.RequestBeginBlock) *ReqRes { - req := types.ToRequestBeginBlock(params) - res, err := cli.client.BeginBlock(context.Background(), req.GetBeginBlock(), grpc.WaitForReady(true)) - if err != nil { - cli.StopForError(err) - } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_BeginBlock{BeginBlock: res}}) -} - -func (cli *grpcClient) EndBlockAsync(params types.RequestEndBlock) *ReqRes { - req := types.ToRequestEndBlock(params) - res, err := cli.client.EndBlock(context.Background(), req.GetEndBlock(), grpc.WaitForReady(true)) - if err != nil { - cli.StopForError(err) - } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_EndBlock{EndBlock: res}}) -} - -func (cli *grpcClient) ListSnapshotsAsync(params types.RequestListSnapshots) *ReqRes { - req := types.ToRequestListSnapshots(params) - res, err := cli.client.ListSnapshots(context.Background(), req.GetListSnapshots(), grpc.WaitForReady(true)) - if err != nil { - cli.StopForError(err) - } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_ListSnapshots{ListSnapshots: res}}) -} - -func (cli *grpcClient) OfferSnapshotAsync(params types.RequestOfferSnapshot) *ReqRes { - req := types.ToRequestOfferSnapshot(params) - res, err := cli.client.OfferSnapshot(context.Background(), req.GetOfferSnapshot(), grpc.WaitForReady(true)) - if err != nil { - cli.StopForError(err) - } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_OfferSnapshot{OfferSnapshot: res}}) -} - -func (cli *grpcClient) LoadSnapshotChunkAsync(params types.RequestLoadSnapshotChunk) *ReqRes { - req := types.ToRequestLoadSnapshotChunk(params) - res, err := cli.client.LoadSnapshotChunk(context.Background(), req.GetLoadSnapshotChunk(), grpc.WaitForReady(true)) - if err != nil { - cli.StopForError(err) - } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_LoadSnapshotChunk{LoadSnapshotChunk: res}}) -} - -func (cli *grpcClient) ApplySnapshotChunkAsync(params types.RequestApplySnapshotChunk) *ReqRes { - req := types.ToRequestApplySnapshotChunk(params) - res, err := cli.client.ApplySnapshotChunk(context.Background(), req.GetApplySnapshotChunk(), grpc.WaitForReady(true)) - if err != nil { - cli.StopForError(err) - } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_ApplySnapshotChunk{ApplySnapshotChunk: res}}) -} - -func (cli *grpcClient) PrepareProposalAsync(params types.RequestPrepareProposal) *ReqRes { - req := types.ToRequestPrepareProposal(params) - res, err := cli.client.PrepareProposal(context.Background(), req.GetPrepareProposal(), grpc.WaitForReady(true)) - if err != nil { - cli.StopForError(err) - } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_PrepareProposal{PrepareProposal: res}}) -} - -func (cli *grpcClient) ProcessProposalAsync(params types.RequestProcessProposal) *ReqRes { - req := types.ToRequestProcessProposal(params) - res, err := cli.client.ProcessProposal(context.Background(), req.GetProcessProposal(), grpc.WaitForReady(true)) - if err != nil { - cli.StopForError(err) - } - - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_ProcessProposal{ProcessProposal: res}}) + return cli.finishAsyncCall(types.ToRequestCheckTx(req), &types.Response{Value: &types.Response_CheckTx{CheckTx: res}}), nil } // finishAsyncCall creates a ReqRes for an async call, and immediately populates it @@ -319,117 +179,61 @@ func (cli *grpcClient) finishAsyncCall(req *types.Request, res *types.Response) return reqres } -// finishSyncCall waits for an async call to complete. It is necessary to call all -// sync calls asynchronously as well, to maintain call and response ordering via -// the channel, and this method will wait until the async call completes. -func (cli *grpcClient) finishSyncCall(reqres *ReqRes) *types.Response { - // It's possible that the callback is called twice, since the callback can - // be called immediately on SetCallback() in addition to after it has been - // set. This is because completing the ReqRes happens in a separate critical - // section from the one where the callback is called: there is a race where - // SetCallback() is called between completing the ReqRes and dispatching the - // callback. - // - // We also buffer the channel with 1 response, since SetCallback() will be - // called synchronously if the reqres is already completed, in which case - // it will block on sending to the channel since it hasn't gotten around to - // receiving from it yet. - // - // ReqRes should really handle callback dispatch internally, to guarantee - // that it's only called once and avoid the above race conditions. - var once sync.Once - ch := make(chan *types.Response, 1) - reqres.SetCallback(func(res *types.Response) { - once.Do(func() { - ch <- res - }) - }) - return <-ch -} - //---------------------------------------- -func (cli *grpcClient) FlushSync() error { - reqres := cli.FlushAsync() - cli.finishSyncCall(reqres).GetFlush() - return cli.Error() +func (cli *grpcClient) Flush(ctx context.Context) error { + _, err := cli.client.Flush(ctx, types.ToRequestFlush().GetFlush(), grpc.WaitForReady(true)) + return err } -func (cli *grpcClient) EchoSync(msg string) (*types.ResponseEcho, error) { - reqres := cli.EchoAsync(msg) - // StopForError should already have been called if error is set - return cli.finishSyncCall(reqres).GetEcho(), cli.Error() +func (cli *grpcClient) Echo(ctx context.Context, msg string) (*types.ResponseEcho, error) { + return cli.client.Echo(ctx, types.ToRequestEcho(msg).GetEcho(), grpc.WaitForReady(true)) } -func (cli *grpcClient) InfoSync(req types.RequestInfo) (*types.ResponseInfo, error) { - reqres := cli.InfoAsync(req) - return cli.finishSyncCall(reqres).GetInfo(), cli.Error() +func (cli *grpcClient) Info(ctx context.Context, req *types.RequestInfo) (*types.ResponseInfo, error) { + return cli.client.Info(ctx, req, grpc.WaitForReady(true)) } -func (cli *grpcClient) DeliverTxSync(params types.RequestDeliverTx) (*types.ResponseDeliverTx, error) { - reqres := cli.DeliverTxAsync(params) - return cli.finishSyncCall(reqres).GetDeliverTx(), cli.Error() +func (cli *grpcClient) CheckTx(ctx context.Context, req *types.RequestCheckTx) (*types.ResponseCheckTx, error) { + return cli.client.CheckTx(ctx, req, grpc.WaitForReady(true)) } -func (cli *grpcClient) CheckTxSync(params types.RequestCheckTx) (*types.ResponseCheckTx, error) { - reqres := cli.CheckTxAsync(params) - return cli.finishSyncCall(reqres).GetCheckTx(), cli.Error() +func (cli *grpcClient) Query(ctx context.Context, req *types.RequestQuery) (*types.ResponseQuery, error) { + return cli.client.Query(ctx, types.ToRequestQuery(req).GetQuery(), grpc.WaitForReady(true)) } -func (cli *grpcClient) QuerySync(req types.RequestQuery) (*types.ResponseQuery, error) { - reqres := cli.QueryAsync(req) - return cli.finishSyncCall(reqres).GetQuery(), cli.Error() +func (cli *grpcClient) Commit(ctx context.Context, req *types.RequestCommit) (*types.ResponseCommit, error) { + return cli.client.Commit(ctx, types.ToRequestCommit().GetCommit(), grpc.WaitForReady(true)) } -func (cli *grpcClient) CommitSync() (*types.ResponseCommit, error) { - reqres := cli.CommitAsync() - return cli.finishSyncCall(reqres).GetCommit(), cli.Error() +func (cli *grpcClient) InitChain(ctx context.Context, req *types.RequestInitChain) (*types.ResponseInitChain, error) { + return cli.client.InitChain(ctx, types.ToRequestInitChain(req).GetInitChain(), grpc.WaitForReady(true)) } -func (cli *grpcClient) InitChainSync(params types.RequestInitChain) (*types.ResponseInitChain, error) { - reqres := cli.InitChainAsync(params) - return cli.finishSyncCall(reqres).GetInitChain(), cli.Error() +func (cli *grpcClient) ListSnapshots(ctx context.Context, req *types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { + return cli.client.ListSnapshots(ctx, types.ToRequestListSnapshots(req).GetListSnapshots(), grpc.WaitForReady(true)) } -func (cli *grpcClient) BeginBlockSync(params types.RequestBeginBlock) (*types.ResponseBeginBlock, error) { - reqres := cli.BeginBlockAsync(params) - return cli.finishSyncCall(reqres).GetBeginBlock(), cli.Error() +func (cli *grpcClient) OfferSnapshot(ctx context.Context, req *types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { + return cli.client.OfferSnapshot(ctx, types.ToRequestOfferSnapshot(req).GetOfferSnapshot(), grpc.WaitForReady(true)) } -func (cli *grpcClient) EndBlockSync(params types.RequestEndBlock) (*types.ResponseEndBlock, error) { - reqres := cli.EndBlockAsync(params) - return cli.finishSyncCall(reqres).GetEndBlock(), cli.Error() +func (cli *grpcClient) LoadSnapshotChunk(ctx context.Context, req *types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { + return cli.client.LoadSnapshotChunk(ctx, types.ToRequestLoadSnapshotChunk(req).GetLoadSnapshotChunk(), grpc.WaitForReady(true)) } -func (cli *grpcClient) ListSnapshotsSync(params types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { - reqres := cli.ListSnapshotsAsync(params) - return cli.finishSyncCall(reqres).GetListSnapshots(), cli.Error() +func (cli *grpcClient) ApplySnapshotChunk(ctx context.Context, req *types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { + return cli.client.ApplySnapshotChunk(ctx, types.ToRequestApplySnapshotChunk(req).GetApplySnapshotChunk(), grpc.WaitForReady(true)) } -func (cli *grpcClient) OfferSnapshotSync(params types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { - reqres := cli.OfferSnapshotAsync(params) - return cli.finishSyncCall(reqres).GetOfferSnapshot(), cli.Error() +func (cli *grpcClient) PrepareProposal(ctx context.Context, req *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { + return cli.client.PrepareProposal(ctx, types.ToRequestPrepareProposal(req).GetPrepareProposal(), grpc.WaitForReady(true)) } -func (cli *grpcClient) LoadSnapshotChunkSync( - params types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { - reqres := cli.LoadSnapshotChunkAsync(params) - return cli.finishSyncCall(reqres).GetLoadSnapshotChunk(), cli.Error() +func (cli *grpcClient) ProcessProposal(ctx context.Context, req *types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { + return cli.client.ProcessProposal(ctx, types.ToRequestProcessProposal(req).GetProcessProposal(), grpc.WaitForReady(true)) } -func (cli *grpcClient) ApplySnapshotChunkSync( - params types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { - reqres := cli.ApplySnapshotChunkAsync(params) - return cli.finishSyncCall(reqres).GetApplySnapshotChunk(), cli.Error() -} - -func (cli *grpcClient) PrepareProposalSync( - params types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { - reqres := cli.PrepareProposalAsync(params) - return cli.finishSyncCall(reqres).GetPrepareProposal(), cli.Error() -} - -func (cli *grpcClient) ProcessProposalSync(params types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { - reqres := cli.ProcessProposalAsync(params) - return cli.finishSyncCall(reqres).GetProcessProposal(), cli.Error() +func (cli *grpcClient) FinalizeBlock(ctx context.Context, req *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { + return cli.client.FinalizeBlock(ctx, types.ToRequestFinalizeBlock(req).GetFinalizeBlock(), grpc.WaitForReady(true)) } diff --git a/abci/client/grpc_client_test.go b/abci/client/grpc_client_test.go new file mode 100644 index 000000000..7162ad7bb --- /dev/null +++ b/abci/client/grpc_client_test.go @@ -0,0 +1,80 @@ +package abcicli_test + +import ( + "fmt" + "math/rand" + "net" + "os" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "google.golang.org/grpc" + + "golang.org/x/net/context" + + "github.com/tendermint/tendermint/libs/log" + tmnet "github.com/tendermint/tendermint/libs/net" + + abciserver "github.com/tendermint/tendermint/abci/server" + "github.com/tendermint/tendermint/abci/types" +) + +func TestGRPC(t *testing.T) { + app := types.NewBaseApplication() + numCheckTxs := 2000 + socketFile := fmt.Sprintf("/tmp/test-%08x.sock", rand.Int31n(1<<30)) + defer os.Remove(socketFile) + socket := fmt.Sprintf("unix://%v", socketFile) + + // Start the listener + server := abciserver.NewGRPCServer(socket, app) + server.SetLogger(log.TestingLogger().With("module", "abci-server")) + err := server.Start() + require.NoError(t, err) + + t.Cleanup(func() { + if err := server.Stop(); err != nil { + t.Error(err) + } + }) + + // Connect to the socket + //nolint:staticcheck // SA1019 Existing use of deprecated but supported dial option. + conn, err := grpc.Dial(socket, grpc.WithInsecure(), grpc.WithContextDialer(dialerFunc)) + require.NoError(t, err) + + t.Cleanup(func() { + if err := conn.Close(); err != nil { + t.Error(err) + } + }) + + client := types.NewABCIClient(conn) + + // Write requests + for counter := 0; counter < numCheckTxs; counter++ { + // Send request + response, err := client.CheckTx(context.Background(), &types.RequestCheckTx{Tx: []byte("test")}) + require.NoError(t, err) + counter++ + if response.Code != 0 { + t.Error("CheckTx failed with ret_code", response.Code) + } + if counter > numCheckTxs { + t.Fatal("Too many CheckTx responses") + } + t.Log("response", counter) + if counter == numCheckTxs { + go func() { + time.Sleep(time.Second * 1) // Wait for a bit to allow counter overflow + }() + } + + } +} + +func dialerFunc(ctx context.Context, addr string) (net.Conn, error) { + return tmnet.Connect(addr) +} diff --git a/abci/client/local_client.go b/abci/client/local_client.go index a49b2c868..fe6e0cfd9 100644 --- a/abci/client/local_client.go +++ b/abci/client/local_client.go @@ -1,6 +1,8 @@ package abcicli import ( + "context" + types "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/libs/service" tmsync "github.com/tendermint/tendermint/libs/sync" @@ -20,8 +22,10 @@ type localClient struct { var _ Client = (*localClient)(nil) -// NewLocalClient creates a local client, which will be directly calling the -// methods of the given app. +// NewLocalClient creates a local client, which wraps the application interface that +// Tendermint as the client will call to the application as the server. The only +// difference, is that the local client has a global mutex which enforces serialization +// of all the ABCI calls from Tendermint to the Application. func NewLocalClient(mtx *tmsync.Mutex, app types.Application) Client { if mtx == nil { mtx = new(tmsync.Mutex) @@ -40,308 +44,20 @@ func (app *localClient) SetResponseCallback(cb Callback) { app.mtx.Unlock() } -// TODO: change types.Application to include Error()? -func (app *localClient) Error() error { - return nil -} - -func (app *localClient) FlushAsync() *ReqRes { - // Do nothing - return newLocalReqRes(types.ToRequestFlush(), nil) -} - -func (app *localClient) EchoAsync(msg string) *ReqRes { +func (app *localClient) CheckTxAsync(ctx context.Context, req *types.RequestCheckTx) (*ReqRes, error) { app.mtx.Lock() defer app.mtx.Unlock() - return app.callback( - types.ToRequestEcho(msg), - types.ToResponseEcho(msg), - ) -} - -func (app *localClient) InfoAsync(req types.RequestInfo) *ReqRes { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.Info(req) - return app.callback( - types.ToRequestInfo(req), - types.ToResponseInfo(res), - ) -} - -func (app *localClient) DeliverTxAsync(params types.RequestDeliverTx) *ReqRes { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.DeliverTx(params) - return app.callback( - types.ToRequestDeliverTx(params), - types.ToResponseDeliverTx(res), - ) -} - -func (app *localClient) CheckTxAsync(req types.RequestCheckTx) *ReqRes { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.CheckTx(req) + res, err := app.Application.CheckTx(ctx, req) + if err != nil { + return nil, err + } return app.callback( types.ToRequestCheckTx(req), types.ToResponseCheckTx(res), - ) + ), nil } -func (app *localClient) QueryAsync(req types.RequestQuery) *ReqRes { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.Query(req) - return app.callback( - types.ToRequestQuery(req), - types.ToResponseQuery(res), - ) -} - -func (app *localClient) CommitAsync() *ReqRes { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.Commit() - return app.callback( - types.ToRequestCommit(), - types.ToResponseCommit(res), - ) -} - -func (app *localClient) InitChainAsync(req types.RequestInitChain) *ReqRes { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.InitChain(req) - return app.callback( - types.ToRequestInitChain(req), - types.ToResponseInitChain(res), - ) -} - -func (app *localClient) BeginBlockAsync(req types.RequestBeginBlock) *ReqRes { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.BeginBlock(req) - return app.callback( - types.ToRequestBeginBlock(req), - types.ToResponseBeginBlock(res), - ) -} - -func (app *localClient) EndBlockAsync(req types.RequestEndBlock) *ReqRes { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.EndBlock(req) - return app.callback( - types.ToRequestEndBlock(req), - types.ToResponseEndBlock(res), - ) -} - -func (app *localClient) ListSnapshotsAsync(req types.RequestListSnapshots) *ReqRes { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.ListSnapshots(req) - return app.callback( - types.ToRequestListSnapshots(req), - types.ToResponseListSnapshots(res), - ) -} - -func (app *localClient) OfferSnapshotAsync(req types.RequestOfferSnapshot) *ReqRes { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.OfferSnapshot(req) - return app.callback( - types.ToRequestOfferSnapshot(req), - types.ToResponseOfferSnapshot(res), - ) -} - -func (app *localClient) LoadSnapshotChunkAsync(req types.RequestLoadSnapshotChunk) *ReqRes { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.LoadSnapshotChunk(req) - return app.callback( - types.ToRequestLoadSnapshotChunk(req), - types.ToResponseLoadSnapshotChunk(res), - ) -} - -func (app *localClient) ApplySnapshotChunkAsync(req types.RequestApplySnapshotChunk) *ReqRes { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.ApplySnapshotChunk(req) - return app.callback( - types.ToRequestApplySnapshotChunk(req), - types.ToResponseApplySnapshotChunk(res), - ) -} - -func (app *localClient) PrepareProposalAsync(req types.RequestPrepareProposal) *ReqRes { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.PrepareProposal(req) - return app.callback( - types.ToRequestPrepareProposal(req), - types.ToResponsePrepareProposal(res), - ) -} - -func (app *localClient) ProcessProposalAsync(req types.RequestProcessProposal) *ReqRes { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.ProcessProposal(req) - return app.callback( - types.ToRequestProcessProposal(req), - types.ToResponseProcessProposal(res), - ) -} - -//------------------------------------------------------- - -func (app *localClient) FlushSync() error { - return nil -} - -func (app *localClient) EchoSync(msg string) (*types.ResponseEcho, error) { - return &types.ResponseEcho{Message: msg}, nil -} - -func (app *localClient) InfoSync(req types.RequestInfo) (*types.ResponseInfo, error) { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.Info(req) - return &res, nil -} - -func (app *localClient) DeliverTxSync(req types.RequestDeliverTx) (*types.ResponseDeliverTx, error) { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.DeliverTx(req) - return &res, nil -} - -func (app *localClient) CheckTxSync(req types.RequestCheckTx) (*types.ResponseCheckTx, error) { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.CheckTx(req) - return &res, nil -} - -func (app *localClient) QuerySync(req types.RequestQuery) (*types.ResponseQuery, error) { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.Query(req) - return &res, nil -} - -func (app *localClient) CommitSync() (*types.ResponseCommit, error) { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.Commit() - return &res, nil -} - -func (app *localClient) InitChainSync(req types.RequestInitChain) (*types.ResponseInitChain, error) { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.InitChain(req) - return &res, nil -} - -func (app *localClient) BeginBlockSync(req types.RequestBeginBlock) (*types.ResponseBeginBlock, error) { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.BeginBlock(req) - return &res, nil -} - -func (app *localClient) EndBlockSync(req types.RequestEndBlock) (*types.ResponseEndBlock, error) { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.EndBlock(req) - return &res, nil -} - -func (app *localClient) ListSnapshotsSync(req types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.ListSnapshots(req) - return &res, nil -} - -func (app *localClient) OfferSnapshotSync(req types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.OfferSnapshot(req) - return &res, nil -} - -func (app *localClient) LoadSnapshotChunkSync( - req types.RequestLoadSnapshotChunk, -) (*types.ResponseLoadSnapshotChunk, error) { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.LoadSnapshotChunk(req) - return &res, nil -} - -func (app *localClient) ApplySnapshotChunkSync( - req types.RequestApplySnapshotChunk, -) (*types.ResponseApplySnapshotChunk, error) { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.ApplySnapshotChunk(req) - return &res, nil -} - -func (app *localClient) PrepareProposalSync(req types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.PrepareProposal(req) - return &res, nil -} - -func (app *localClient) ProcessProposalSync(req types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { - app.mtx.Lock() - defer app.mtx.Unlock() - - res := app.Application.ProcessProposal(req) - return &res, nil -} - -//------------------------------------------------------- - func (app *localClient) callback(req *types.Request, res *types.Response) *ReqRes { app.Callback(req, res) rr := newLocalReqRes(req, res) @@ -354,3 +70,103 @@ func newLocalReqRes(req *types.Request, res *types.Response) *ReqRes { reqRes.Response = res return reqRes } + +//------------------------------------------------------- + +func (app *localClient) Error() error { + return nil +} + +func (app *localClient) Flush(context.Context) error { + return nil +} + +func (app *localClient) Echo(_ context.Context, msg string) (*types.ResponseEcho, error) { + return &types.ResponseEcho{Message: msg}, nil +} + +func (app *localClient) Info(ctx context.Context, req *types.RequestInfo) (*types.ResponseInfo, error) { + app.mtx.Lock() + defer app.mtx.Unlock() + + return app.Application.Info(ctx, req) +} + +func (app *localClient) CheckTx(ctx context.Context, req *types.RequestCheckTx) (*types.ResponseCheckTx, error) { + app.mtx.Lock() + defer app.mtx.Unlock() + + return app.Application.CheckTx(ctx, req) +} + +func (app *localClient) Query(ctx context.Context, req *types.RequestQuery) (*types.ResponseQuery, error) { + app.mtx.Lock() + defer app.mtx.Unlock() + + return app.Application.Query(ctx, req) +} + +func (app *localClient) Commit(ctx context.Context, req *types.RequestCommit) (*types.ResponseCommit, error) { + app.mtx.Lock() + defer app.mtx.Unlock() + + return app.Application.Commit(ctx, req) +} + +func (app *localClient) InitChain(ctx context.Context, req *types.RequestInitChain) (*types.ResponseInitChain, error) { + app.mtx.Lock() + defer app.mtx.Unlock() + + return app.Application.InitChain(ctx, req) +} + +func (app *localClient) ListSnapshots(ctx context.Context, req *types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { + app.mtx.Lock() + defer app.mtx.Unlock() + + return app.Application.ListSnapshots(ctx, req) +} + +func (app *localClient) OfferSnapshot(ctx context.Context, req *types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { + app.mtx.Lock() + defer app.mtx.Unlock() + + return app.Application.OfferSnapshot(ctx, req) +} + +func (app *localClient) LoadSnapshotChunk(ctx context.Context, + req *types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { + app.mtx.Lock() + defer app.mtx.Unlock() + + return app.Application.LoadSnapshotChunk(ctx, req) +} + +func (app *localClient) ApplySnapshotChunk(ctx context.Context, + req *types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { + app.mtx.Lock() + defer app.mtx.Unlock() + + return app.Application.ApplySnapshotChunk(ctx, req) +} + +func (app *localClient) PrepareProposal(ctx context.Context, req *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { + app.mtx.Lock() + defer app.mtx.Unlock() + + return app.Application.PrepareProposal(ctx, req) +} + +func (app *localClient) ProcessProposal(ctx context.Context, req *types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { + app.mtx.Lock() + defer app.mtx.Unlock() + + return app.Application.ProcessProposal(ctx, req) +} + +func (app *localClient) FinalizeBlock(ctx context.Context, req *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { + app.mtx.Lock() + defer app.mtx.Unlock() + + return app.Application.FinalizeBlock(ctx, req) +} diff --git a/abci/client/mocks/client.go b/abci/client/mocks/client.go index 7356be39e..8892712ab 100644 --- a/abci/client/mocks/client.go +++ b/abci/client/mocks/client.go @@ -3,7 +3,10 @@ package mocks import ( + context "context" + abcicli "github.com/tendermint/tendermint/abci/client" + log "github.com/tendermint/tendermint/libs/log" mock "github.com/stretchr/testify/mock" @@ -16,29 +19,13 @@ type Client struct { mock.Mock } -// ApplySnapshotChunkAsync provides a mock function with given fields: _a0 -func (_m *Client) ApplySnapshotChunkAsync(_a0 types.RequestApplySnapshotChunk) *abcicli.ReqRes { - ret := _m.Called(_a0) - - var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestApplySnapshotChunk) *abcicli.ReqRes); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abcicli.ReqRes) - } - } - - return r0 -} - -// ApplySnapshotChunkSync provides a mock function with given fields: _a0 -func (_m *Client) ApplySnapshotChunkSync(_a0 types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { - ret := _m.Called(_a0) +// 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 - if rf, ok := ret.Get(0).(func(types.RequestApplySnapshotChunk) *types.ResponseApplySnapshotChunk); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestApplySnapshotChunk) *types.ResponseApplySnapshotChunk); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseApplySnapshotChunk) @@ -46,8 +33,8 @@ func (_m *Client) ApplySnapshotChunkSync(_a0 types.RequestApplySnapshotChunk) (* } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestApplySnapshotChunk) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestApplySnapshotChunk) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -55,68 +42,13 @@ func (_m *Client) ApplySnapshotChunkSync(_a0 types.RequestApplySnapshotChunk) (* return r0, r1 } -// BeginBlockAsync provides a mock function with given fields: _a0 -func (_m *Client) BeginBlockAsync(_a0 types.RequestBeginBlock) *abcicli.ReqRes { - ret := _m.Called(_a0) - - var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestBeginBlock) *abcicli.ReqRes); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abcicli.ReqRes) - } - } - - return r0 -} - -// BeginBlockSync provides a mock function with given fields: _a0 -func (_m *Client) BeginBlockSync(_a0 types.RequestBeginBlock) (*types.ResponseBeginBlock, error) { - ret := _m.Called(_a0) - - var r0 *types.ResponseBeginBlock - if rf, ok := ret.Get(0).(func(types.RequestBeginBlock) *types.ResponseBeginBlock); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.ResponseBeginBlock) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(types.RequestBeginBlock) error); ok { - r1 = rf(_a0) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// CheckTxAsync provides a mock function with given fields: _a0 -func (_m *Client) CheckTxAsync(_a0 types.RequestCheckTx) *abcicli.ReqRes { - ret := _m.Called(_a0) - - var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestCheckTx) *abcicli.ReqRes); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abcicli.ReqRes) - } - } - - return r0 -} - -// CheckTxSync provides a mock function with given fields: _a0 -func (_m *Client) CheckTxSync(_a0 types.RequestCheckTx) (*types.ResponseCheckTx, error) { - ret := _m.Called(_a0) +// 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(types.RequestCheckTx) *types.ResponseCheckTx); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestCheckTx) *types.ResponseCheckTx); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseCheckTx) @@ -124,8 +56,8 @@ func (_m *Client) CheckTxSync(_a0 types.RequestCheckTx) (*types.ResponseCheckTx, } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestCheckTx) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestCheckTx) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -133,29 +65,36 @@ func (_m *Client) CheckTxSync(_a0 types.RequestCheckTx) (*types.ResponseCheckTx, return r0, r1 } -// CommitAsync provides a mock function with given fields: -func (_m *Client) CommitAsync() *abcicli.ReqRes { - ret := _m.Called() +// CheckTxAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) CheckTxAsync(_a0 context.Context, _a1 *types.RequestCheckTx) (*abcicli.ReqRes, error) { + ret := _m.Called(_a0, _a1) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func() *abcicli.ReqRes); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestCheckTx) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestCheckTx) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// CommitSync provides a mock function with given fields: -func (_m *Client) CommitSync() (*types.ResponseCommit, error) { - ret := _m.Called() +// Commit provides a mock function with given fields: _a0, _a1 +func (_m *Client) Commit(_a0 context.Context, _a1 *types.RequestCommit) (*types.ResponseCommit, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponseCommit - if rf, ok := ret.Get(0).(func() *types.ResponseCommit); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestCommit) *types.ResponseCommit); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseCommit) @@ -163,8 +102,8 @@ func (_m *Client) CommitSync() (*types.ResponseCommit, error) { } var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestCommit) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -172,68 +111,13 @@ func (_m *Client) CommitSync() (*types.ResponseCommit, error) { return r0, r1 } -// DeliverTxAsync provides a mock function with given fields: _a0 -func (_m *Client) DeliverTxAsync(_a0 types.RequestDeliverTx) *abcicli.ReqRes { - ret := _m.Called(_a0) - - var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestDeliverTx) *abcicli.ReqRes); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abcicli.ReqRes) - } - } - - return r0 -} - -// DeliverTxSync provides a mock function with given fields: _a0 -func (_m *Client) DeliverTxSync(_a0 types.RequestDeliverTx) (*types.ResponseDeliverTx, error) { - ret := _m.Called(_a0) - - var r0 *types.ResponseDeliverTx - if rf, ok := ret.Get(0).(func(types.RequestDeliverTx) *types.ResponseDeliverTx); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.ResponseDeliverTx) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(types.RequestDeliverTx) error); ok { - r1 = rf(_a0) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// EchoAsync provides a mock function with given fields: msg -func (_m *Client) EchoAsync(msg string) *abcicli.ReqRes { - ret := _m.Called(msg) - - var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(string) *abcicli.ReqRes); ok { - r0 = rf(msg) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abcicli.ReqRes) - } - } - - return r0 -} - -// EchoSync provides a mock function with given fields: msg -func (_m *Client) EchoSync(msg string) (*types.ResponseEcho, error) { - ret := _m.Called(msg) +// Echo provides a mock function with given fields: _a0, _a1 +func (_m *Client) Echo(_a0 context.Context, _a1 string) (*types.ResponseEcho, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponseEcho - if rf, ok := ret.Get(0).(func(string) *types.ResponseEcho); ok { - r0 = rf(msg) + if rf, ok := ret.Get(0).(func(context.Context, string) *types.ResponseEcho); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseEcho) @@ -241,47 +125,8 @@ func (_m *Client) EchoSync(msg string) (*types.ResponseEcho, error) { } var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(msg) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// EndBlockAsync provides a mock function with given fields: _a0 -func (_m *Client) EndBlockAsync(_a0 types.RequestEndBlock) *abcicli.ReqRes { - ret := _m.Called(_a0) - - var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestEndBlock) *abcicli.ReqRes); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abcicli.ReqRes) - } - } - - return r0 -} - -// EndBlockSync provides a mock function with given fields: _a0 -func (_m *Client) EndBlockSync(_a0 types.RequestEndBlock) (*types.ResponseEndBlock, error) { - ret := _m.Called(_a0) - - var r0 *types.ResponseEndBlock - if rf, ok := ret.Get(0).(func(types.RequestEndBlock) *types.ResponseEndBlock); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.ResponseEndBlock) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(types.RequestEndBlock) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -303,68 +148,22 @@ func (_m *Client) Error() error { return r0 } -// FlushAsync provides a mock function with given fields: -func (_m *Client) FlushAsync() *abcicli.ReqRes { - ret := _m.Called() +// FinalizeBlock provides a mock function with given fields: _a0, _a1 +func (_m *Client) FinalizeBlock(_a0 context.Context, _a1 *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { + ret := _m.Called(_a0, _a1) - var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func() *abcicli.ReqRes); ok { - r0 = rf() + var r0 *types.ResponseFinalizeBlock + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestFinalizeBlock) *types.ResponseFinalizeBlock); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*abcicli.ReqRes) - } - } - - return r0 -} - -// FlushSync provides a mock function with given fields: -func (_m *Client) FlushSync() error { - ret := _m.Called() - - var r0 error - if rf, ok := ret.Get(0).(func() error); ok { - r0 = rf() - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// InfoAsync provides a mock function with given fields: _a0 -func (_m *Client) InfoAsync(_a0 types.RequestInfo) *abcicli.ReqRes { - ret := _m.Called(_a0) - - var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestInfo) *abcicli.ReqRes); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abcicli.ReqRes) - } - } - - return r0 -} - -// InfoSync provides a mock function with given fields: _a0 -func (_m *Client) InfoSync(_a0 types.RequestInfo) (*types.ResponseInfo, error) { - ret := _m.Called(_a0) - - var r0 *types.ResponseInfo - if rf, ok := ret.Get(0).(func(types.RequestInfo) *types.ResponseInfo); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.ResponseInfo) + r0 = ret.Get(0).(*types.ResponseFinalizeBlock) } } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestInfo) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestFinalizeBlock) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -372,29 +171,50 @@ func (_m *Client) InfoSync(_a0 types.RequestInfo) (*types.ResponseInfo, error) { return r0, r1 } -// InitChainAsync provides a mock function with given fields: _a0 -func (_m *Client) InitChainAsync(_a0 types.RequestInitChain) *abcicli.ReqRes { +// Flush provides a mock function with given fields: _a0 +func (_m *Client) Flush(_a0 context.Context) error { ret := _m.Called(_a0) - var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestInitChain) *abcicli.ReqRes); ok { + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { r0 = rf(_a0) } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abcicli.ReqRes) - } + r0 = ret.Error(0) } return r0 } -// InitChainSync provides a mock function with given fields: _a0 -func (_m *Client) InitChainSync(_a0 types.RequestInitChain) (*types.ResponseInitChain, error) { - ret := _m.Called(_a0) +// 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 + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestInfo) *types.ResponseInfo); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseInfo) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestInfo) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// 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 - if rf, ok := ret.Get(0).(func(types.RequestInitChain) *types.ResponseInitChain); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestInitChain) *types.ResponseInitChain); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseInitChain) @@ -402,8 +222,8 @@ func (_m *Client) InitChainSync(_a0 types.RequestInitChain) (*types.ResponseInit } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestInitChain) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestInitChain) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -425,29 +245,13 @@ func (_m *Client) IsRunning() bool { return r0 } -// ListSnapshotsAsync provides a mock function with given fields: _a0 -func (_m *Client) ListSnapshotsAsync(_a0 types.RequestListSnapshots) *abcicli.ReqRes { - ret := _m.Called(_a0) - - var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestListSnapshots) *abcicli.ReqRes); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abcicli.ReqRes) - } - } - - return r0 -} - -// ListSnapshotsSync provides a mock function with given fields: _a0 -func (_m *Client) ListSnapshotsSync(_a0 types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { - ret := _m.Called(_a0) +// 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 - if rf, ok := ret.Get(0).(func(types.RequestListSnapshots) *types.ResponseListSnapshots); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestListSnapshots) *types.ResponseListSnapshots); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseListSnapshots) @@ -455,8 +259,8 @@ func (_m *Client) ListSnapshotsSync(_a0 types.RequestListSnapshots) (*types.Resp } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestListSnapshots) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestListSnapshots) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -464,29 +268,13 @@ func (_m *Client) ListSnapshotsSync(_a0 types.RequestListSnapshots) (*types.Resp return r0, r1 } -// LoadSnapshotChunkAsync provides a mock function with given fields: _a0 -func (_m *Client) LoadSnapshotChunkAsync(_a0 types.RequestLoadSnapshotChunk) *abcicli.ReqRes { - ret := _m.Called(_a0) - - var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestLoadSnapshotChunk) *abcicli.ReqRes); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abcicli.ReqRes) - } - } - - return r0 -} - -// LoadSnapshotChunkSync provides a mock function with given fields: _a0 -func (_m *Client) LoadSnapshotChunkSync(_a0 types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { - ret := _m.Called(_a0) +// 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 - if rf, ok := ret.Get(0).(func(types.RequestLoadSnapshotChunk) *types.ResponseLoadSnapshotChunk); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestLoadSnapshotChunk) *types.ResponseLoadSnapshotChunk); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseLoadSnapshotChunk) @@ -494,8 +282,8 @@ func (_m *Client) LoadSnapshotChunkSync(_a0 types.RequestLoadSnapshotChunk) (*ty } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestLoadSnapshotChunk) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestLoadSnapshotChunk) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -503,29 +291,13 @@ func (_m *Client) LoadSnapshotChunkSync(_a0 types.RequestLoadSnapshotChunk) (*ty return r0, r1 } -// OfferSnapshotAsync provides a mock function with given fields: _a0 -func (_m *Client) OfferSnapshotAsync(_a0 types.RequestOfferSnapshot) *abcicli.ReqRes { - ret := _m.Called(_a0) - - var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestOfferSnapshot) *abcicli.ReqRes); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abcicli.ReqRes) - } - } - - return r0 -} - -// OfferSnapshotSync provides a mock function with given fields: _a0 -func (_m *Client) OfferSnapshotSync(_a0 types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { - ret := _m.Called(_a0) +// 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 - if rf, ok := ret.Get(0).(func(types.RequestOfferSnapshot) *types.ResponseOfferSnapshot); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestOfferSnapshot) *types.ResponseOfferSnapshot); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseOfferSnapshot) @@ -533,8 +305,8 @@ func (_m *Client) OfferSnapshotSync(_a0 types.RequestOfferSnapshot) (*types.Resp } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestOfferSnapshot) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestOfferSnapshot) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -575,29 +347,13 @@ func (_m *Client) OnStop() { _m.Called() } -// PrepareProposalAsync provides a mock function with given fields: _a0 -func (_m *Client) PrepareProposalAsync(_a0 types.RequestPrepareProposal) *abcicli.ReqRes { - ret := _m.Called(_a0) - - var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestPrepareProposal) *abcicli.ReqRes); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abcicli.ReqRes) - } - } - - return r0 -} - -// PrepareProposalSync provides a mock function with given fields: _a0 -func (_m *Client) PrepareProposalSync(_a0 types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { - ret := _m.Called(_a0) +// PrepareProposal provides a mock function with given fields: _a0, _a1 +func (_m *Client) PrepareProposal(_a0 context.Context, _a1 *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponsePrepareProposal - if rf, ok := ret.Get(0).(func(types.RequestPrepareProposal) *types.ResponsePrepareProposal); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestPrepareProposal) *types.ResponsePrepareProposal); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponsePrepareProposal) @@ -605,8 +361,8 @@ func (_m *Client) PrepareProposalSync(_a0 types.RequestPrepareProposal) (*types. } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestPrepareProposal) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestPrepareProposal) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -614,29 +370,13 @@ func (_m *Client) PrepareProposalSync(_a0 types.RequestPrepareProposal) (*types. return r0, r1 } -// ProcessProposalAsync provides a mock function with given fields: _a0 -func (_m *Client) ProcessProposalAsync(_a0 types.RequestProcessProposal) *abcicli.ReqRes { - ret := _m.Called(_a0) - - var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestProcessProposal) *abcicli.ReqRes); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abcicli.ReqRes) - } - } - - return r0 -} - -// ProcessProposalSync provides a mock function with given fields: _a0 -func (_m *Client) ProcessProposalSync(_a0 types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { - ret := _m.Called(_a0) +// ProcessProposal provides a mock function with given fields: _a0, _a1 +func (_m *Client) ProcessProposal(_a0 context.Context, _a1 *types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponseProcessProposal - if rf, ok := ret.Get(0).(func(types.RequestProcessProposal) *types.ResponseProcessProposal); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestProcessProposal) *types.ResponseProcessProposal); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseProcessProposal) @@ -644,8 +384,8 @@ func (_m *Client) ProcessProposalSync(_a0 types.RequestProcessProposal) (*types. } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestProcessProposal) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestProcessProposal) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -653,29 +393,13 @@ func (_m *Client) ProcessProposalSync(_a0 types.RequestProcessProposal) (*types. return r0, r1 } -// QueryAsync provides a mock function with given fields: _a0 -func (_m *Client) QueryAsync(_a0 types.RequestQuery) *abcicli.ReqRes { - ret := _m.Called(_a0) - - var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestQuery) *abcicli.ReqRes); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abcicli.ReqRes) - } - } - - return r0 -} - -// QuerySync provides a mock function with given fields: _a0 -func (_m *Client) QuerySync(_a0 types.RequestQuery) (*types.ResponseQuery, error) { - ret := _m.Called(_a0) +// 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 - if rf, ok := ret.Get(0).(func(types.RequestQuery) *types.ResponseQuery); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestQuery) *types.ResponseQuery); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseQuery) @@ -683,8 +407,8 @@ func (_m *Client) QuerySync(_a0 types.RequestQuery) (*types.ResponseQuery, error } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestQuery) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestQuery) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } diff --git a/abci/client/socket_client.go b/abci/client/socket_client.go index 3df6007d2..061cfc0a5 100644 --- a/abci/client/socket_client.go +++ b/abci/client/socket_client.go @@ -3,17 +3,17 @@ package abcicli import ( "bufio" "container/list" + "context" "errors" "fmt" "io" "net" - "reflect" + "sync" "time" "github.com/tendermint/tendermint/abci/types" tmnet "github.com/tendermint/tendermint/libs/net" "github.com/tendermint/tendermint/libs/service" - tmsync "github.com/tendermint/tendermint/libs/sync" "github.com/tendermint/tendermint/libs/timer" ) @@ -22,8 +22,12 @@ const ( flushThrottleMS = 20 // Don't wait longer than... ) -// This is goroutine-safe, but users should beware that the application in -// general is not meant to be interfaced with concurrent callers. +// socketClient is the client side implementation of the Tendermint +// Socket Protocol (TSP). It is used by an instance of Tendermint to pass +// ABCI requests to an out of process application running the socketServer. +// +// This is goroutine-safe. All calls are serialized to the server through an unbuffered queue. The socketClient +// tracks responses and expects them to respect the order of the requests sent. type socketClient struct { service.BaseService @@ -34,7 +38,7 @@ type socketClient struct { reqQueue chan *ReqRes flushTimer *timer.ThrottleTimer - mtx tmsync.Mutex + mtx sync.Mutex err error reqSent *list.List // list of requests sent, waiting for response resCb func(*types.Request, *types.Response) // called on all requests, if set. @@ -44,7 +48,7 @@ var _ Client = (*socketClient)(nil) // NewSocketClient creates a new socket client, which connects to a given // address. If mustConnect is true, the client will return an error upon start -// if it fails to connect. +// if it fails to connect else it will continue to retry. func NewSocketClient(addr string, mustConnect bool) Client { cli := &socketClient{ reqQueue: make(chan *ReqRes, reqQueueSize), @@ -104,6 +108,8 @@ func (cli *socketClient) Error() error { return cli.err } +//---------------------------------------- + // SetResponseCallback sets a callback, which will be executed for each // non-error & non-empty response from the server. // @@ -114,6 +120,10 @@ func (cli *socketClient) SetResponseCallback(resCb Callback) { cli.mtx.Unlock() } +func (cli *socketClient) CheckTxAsync(ctx context.Context, req *types.RequestCheckTx) (*ReqRes, error) { + return cli.queueRequest(ctx, types.ToRequestCheckTx(req)) +} + //---------------------------------------- func (cli *socketClient) sendRequestsRoutine(conn io.Writer) { @@ -121,9 +131,11 @@ func (cli *socketClient) sendRequestsRoutine(conn io.Writer) { for { select { case reqres := <-cli.reqQueue: - // cli.Logger.Debug("Sent request", "requestType", reflect.TypeOf(reqres.Request), "request", reqres.Request) + // N.B. We must enqueue before sending out the request, otherwise the + // server may reply before we do it, and the receiver will fail for an + // unsolicited reply. + cli.trackRequest(reqres) - cli.willSendReq(reqres) err := types.WriteMessage(reqres.Request, w) if err != nil { cli.stopForError(fmt.Errorf("write to buffer: %w", err)) @@ -153,6 +165,10 @@ func (cli *socketClient) sendRequestsRoutine(conn io.Writer) { func (cli *socketClient) recvResponseRoutine(conn io.Reader) { r := bufio.NewReader(conn) for { + if !cli.IsRunning() { + return + } + var res = &types.Response{} err := types.ReadMessage(r, res) if err != nil { @@ -160,8 +176,6 @@ func (cli *socketClient) recvResponseRoutine(conn io.Reader) { return } - // cli.Logger.Debug("Received response", "responseType", reflect.TypeOf(res), "response", res) - switch r := res.Value.(type) { case *types.Response_Exception: // app responded with error // XXX After setting cli.err, release waiters (e.g. reqres.Done()) @@ -177,7 +191,13 @@ func (cli *socketClient) recvResponseRoutine(conn io.Reader) { } } -func (cli *socketClient) willSendReq(reqres *ReqRes) { +func (cli *socketClient) trackRequest(reqres *ReqRes) { + // N.B. We must NOT hold the client state lock while checking this, or we + // may deadlock with shutdown. + if !cli.IsRunning() { + return + } + cli.mtx.Lock() defer cli.mtx.Unlock() cli.reqSent.PushBack(reqres) @@ -190,13 +210,12 @@ func (cli *socketClient) didRecvResponse(res *types.Response) error { // Get the first ReqRes. next := cli.reqSent.Front() if next == nil { - return fmt.Errorf("unexpected %v when nothing expected", reflect.TypeOf(res.Value)) + return fmt.Errorf("unexpected response %T when no call was made", res.Value) } reqres := next.Value.(*ReqRes) if !resMatchesReq(reqres.Request, res) { - return fmt.Errorf("unexpected %v when response to %v expected", - reflect.TypeOf(res.Value), reflect.TypeOf(reqres.Request.Value)) + return fmt.Errorf("unexpected response %T to the request %T", res.Value, reqres.Request.Value) } reqres.Response = res @@ -219,224 +238,167 @@ func (cli *socketClient) didRecvResponse(res *types.Response) error { //---------------------------------------- -func (cli *socketClient) EchoAsync(msg string) *ReqRes { - return cli.queueRequest(types.ToRequestEcho(msg)) -} - -func (cli *socketClient) FlushAsync() *ReqRes { - return cli.queueRequest(types.ToRequestFlush()) -} - -func (cli *socketClient) InfoAsync(req types.RequestInfo) *ReqRes { - return cli.queueRequest(types.ToRequestInfo(req)) -} - -func (cli *socketClient) DeliverTxAsync(req types.RequestDeliverTx) *ReqRes { - return cli.queueRequest(types.ToRequestDeliverTx(req)) -} - -func (cli *socketClient) CheckTxAsync(req types.RequestCheckTx) *ReqRes { - return cli.queueRequest(types.ToRequestCheckTx(req)) -} - -func (cli *socketClient) QueryAsync(req types.RequestQuery) *ReqRes { - return cli.queueRequest(types.ToRequestQuery(req)) -} - -func (cli *socketClient) CommitAsync() *ReqRes { - return cli.queueRequest(types.ToRequestCommit()) -} - -func (cli *socketClient) InitChainAsync(req types.RequestInitChain) *ReqRes { - return cli.queueRequest(types.ToRequestInitChain(req)) -} - -func (cli *socketClient) BeginBlockAsync(req types.RequestBeginBlock) *ReqRes { - return cli.queueRequest(types.ToRequestBeginBlock(req)) -} - -func (cli *socketClient) EndBlockAsync(req types.RequestEndBlock) *ReqRes { - return cli.queueRequest(types.ToRequestEndBlock(req)) -} - -func (cli *socketClient) ListSnapshotsAsync(req types.RequestListSnapshots) *ReqRes { - return cli.queueRequest(types.ToRequestListSnapshots(req)) -} - -func (cli *socketClient) OfferSnapshotAsync(req types.RequestOfferSnapshot) *ReqRes { - return cli.queueRequest(types.ToRequestOfferSnapshot(req)) -} - -func (cli *socketClient) LoadSnapshotChunkAsync(req types.RequestLoadSnapshotChunk) *ReqRes { - return cli.queueRequest(types.ToRequestLoadSnapshotChunk(req)) -} - -func (cli *socketClient) ApplySnapshotChunkAsync(req types.RequestApplySnapshotChunk) *ReqRes { - return cli.queueRequest(types.ToRequestApplySnapshotChunk(req)) -} - -func (cli *socketClient) PrepareProposalAsync(req types.RequestPrepareProposal) *ReqRes { - return cli.queueRequest(types.ToRequestPrepareProposal(req)) -} - -func (cli *socketClient) ProcessProposalAsync(req types.RequestProcessProposal) *ReqRes { - return cli.queueRequest(types.ToRequestProcessProposal(req)) -} - -//---------------------------------------- - -func (cli *socketClient) FlushSync() error { - reqRes := cli.queueRequest(types.ToRequestFlush()) - if err := cli.Error(); err != nil { +func (cli *socketClient) Flush(ctx context.Context) error { + reqRes, err := cli.queueRequest(ctx, types.ToRequestFlush()) + if err != nil { return err } - reqRes.Wait() // NOTE: if we don't flush the queue, its possible to get stuck here - return cli.Error() + reqRes.Wait() + return nil } -func (cli *socketClient) EchoSync(msg string) (*types.ResponseEcho, error) { - reqres := cli.queueRequest(types.ToRequestEcho(msg)) - if err := cli.FlushSync(); err != nil { +func (cli *socketClient) Echo(ctx context.Context, msg string) (*types.ResponseEcho, error) { + reqRes, err := cli.queueRequest(ctx, types.ToRequestEcho(msg)) + if err != nil { return nil, err } - - return reqres.Response.GetEcho(), cli.Error() -} - -func (cli *socketClient) InfoSync(req types.RequestInfo) (*types.ResponseInfo, error) { - reqres := cli.queueRequest(types.ToRequestInfo(req)) - if err := cli.FlushSync(); err != nil { + if err := cli.Flush(ctx); err != nil { return nil, err } - - return reqres.Response.GetInfo(), cli.Error() + return reqRes.Response.GetEcho(), cli.Error() } -func (cli *socketClient) DeliverTxSync(req types.RequestDeliverTx) (*types.ResponseDeliverTx, error) { - reqres := cli.queueRequest(types.ToRequestDeliverTx(req)) - if err := cli.FlushSync(); err != nil { +func (cli *socketClient) Info(ctx context.Context, req *types.RequestInfo) (*types.ResponseInfo, error) { + reqRes, err := cli.queueRequest(ctx, types.ToRequestInfo(req)) + if err != nil { return nil, err } - - return reqres.Response.GetDeliverTx(), cli.Error() -} - -func (cli *socketClient) CheckTxSync(req types.RequestCheckTx) (*types.ResponseCheckTx, error) { - reqres := cli.queueRequest(types.ToRequestCheckTx(req)) - if err := cli.FlushSync(); err != nil { + if err := cli.Flush(ctx); err != nil { return nil, err } - - return reqres.Response.GetCheckTx(), cli.Error() + return reqRes.Response.GetInfo(), cli.Error() } -func (cli *socketClient) QuerySync(req types.RequestQuery) (*types.ResponseQuery, error) { - reqres := cli.queueRequest(types.ToRequestQuery(req)) - if err := cli.FlushSync(); err != nil { +func (cli *socketClient) CheckTx(ctx context.Context, req *types.RequestCheckTx) (*types.ResponseCheckTx, error) { + reqRes, err := cli.queueRequest(ctx, types.ToRequestCheckTx(req)) + if err != nil { return nil, err } - - return reqres.Response.GetQuery(), cli.Error() -} - -func (cli *socketClient) CommitSync() (*types.ResponseCommit, error) { - reqres := cli.queueRequest(types.ToRequestCommit()) - if err := cli.FlushSync(); err != nil { + if err := cli.Flush(ctx); err != nil { return nil, err } - - return reqres.Response.GetCommit(), cli.Error() + return reqRes.Response.GetCheckTx(), cli.Error() } -func (cli *socketClient) InitChainSync(req types.RequestInitChain) (*types.ResponseInitChain, error) { - reqres := cli.queueRequest(types.ToRequestInitChain(req)) - if err := cli.FlushSync(); err != nil { +func (cli *socketClient) Query(ctx context.Context, req *types.RequestQuery) (*types.ResponseQuery, error) { + reqRes, err := cli.queueRequest(ctx, types.ToRequestQuery(req)) + if err != nil { return nil, err } - - return reqres.Response.GetInitChain(), cli.Error() -} - -func (cli *socketClient) BeginBlockSync(req types.RequestBeginBlock) (*types.ResponseBeginBlock, error) { - reqres := cli.queueRequest(types.ToRequestBeginBlock(req)) - if err := cli.FlushSync(); err != nil { + if err := cli.Flush(ctx); err != nil { return nil, err } - - return reqres.Response.GetBeginBlock(), cli.Error() + return reqRes.Response.GetQuery(), cli.Error() } -func (cli *socketClient) EndBlockSync(req types.RequestEndBlock) (*types.ResponseEndBlock, error) { - reqres := cli.queueRequest(types.ToRequestEndBlock(req)) - if err := cli.FlushSync(); err != nil { +func (cli *socketClient) Commit(ctx context.Context, req *types.RequestCommit) (*types.ResponseCommit, error) { + reqRes, err := cli.queueRequest(ctx, types.ToRequestCommit()) + if err != nil { return nil, err } - - return reqres.Response.GetEndBlock(), cli.Error() -} - -func (cli *socketClient) ListSnapshotsSync(req types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { - reqres := cli.queueRequest(types.ToRequestListSnapshots(req)) - if err := cli.FlushSync(); err != nil { + if err := cli.Flush(ctx); err != nil { return nil, err } - - return reqres.Response.GetListSnapshots(), cli.Error() + return reqRes.Response.GetCommit(), cli.Error() } -func (cli *socketClient) OfferSnapshotSync(req types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { - reqres := cli.queueRequest(types.ToRequestOfferSnapshot(req)) - if err := cli.FlushSync(); err != nil { +func (cli *socketClient) InitChain(ctx context.Context, req *types.RequestInitChain) (*types.ResponseInitChain, error) { + reqRes, err := cli.queueRequest(ctx, types.ToRequestInitChain(req)) + if err != nil { return nil, err } - - return reqres.Response.GetOfferSnapshot(), cli.Error() -} - -func (cli *socketClient) LoadSnapshotChunkSync( - req types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { - reqres := cli.queueRequest(types.ToRequestLoadSnapshotChunk(req)) - if err := cli.FlushSync(); err != nil { + if err := cli.Flush(ctx); err != nil { return nil, err } - - return reqres.Response.GetLoadSnapshotChunk(), cli.Error() + return reqRes.Response.GetInitChain(), cli.Error() } -func (cli *socketClient) ApplySnapshotChunkSync( - req types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { - reqres := cli.queueRequest(types.ToRequestApplySnapshotChunk(req)) - if err := cli.FlushSync(); err != nil { +func (cli *socketClient) ListSnapshots(ctx context.Context, req *types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { + reqRes, err := cli.queueRequest(ctx, types.ToRequestListSnapshots(req)) + if err != nil { return nil, err } - return reqres.Response.GetApplySnapshotChunk(), cli.Error() -} - -func (cli *socketClient) PrepareProposalSync(req types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { - reqres := cli.queueRequest(types.ToRequestPrepareProposal(req)) - if err := cli.FlushSync(); err != nil { + if err := cli.Flush(ctx); err != nil { return nil, err } - - return reqres.Response.GetPrepareProposal(), cli.Error() + return reqRes.Response.GetListSnapshots(), cli.Error() } -func (cli *socketClient) ProcessProposalSync(req types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { - reqres := cli.queueRequest(types.ToRequestProcessProposal(req)) - if err := cli.FlushSync(); err != nil { +func (cli *socketClient) OfferSnapshot(ctx context.Context, req *types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { + reqRes, err := cli.queueRequest(ctx, types.ToRequestOfferSnapshot(req)) + if err != nil { return nil, err } - - return reqres.Response.GetProcessProposal(), cli.Error() + if err := cli.Flush(ctx); err != nil { + return nil, err + } + return reqRes.Response.GetOfferSnapshot(), cli.Error() } -//---------------------------------------- +func (cli *socketClient) LoadSnapshotChunk(ctx context.Context, req *types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { + reqRes, err := cli.queueRequest(ctx, types.ToRequestLoadSnapshotChunk(req)) + if err != nil { + return nil, err + } + if err := cli.Flush(ctx); err != nil { + return nil, err + } + return reqRes.Response.GetLoadSnapshotChunk(), cli.Error() +} -func (cli *socketClient) queueRequest(req *types.Request) *ReqRes { +func (cli *socketClient) ApplySnapshotChunk(ctx context.Context, req *types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { + reqRes, err := cli.queueRequest(ctx, types.ToRequestApplySnapshotChunk(req)) + if err != nil { + return nil, err + } + if err := cli.Flush(ctx); err != nil { + return nil, err + } + return reqRes.Response.GetApplySnapshotChunk(), cli.Error() +} + +func (cli *socketClient) PrepareProposal(ctx context.Context, req *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { + reqRes, err := cli.queueRequest(ctx, types.ToRequestPrepareProposal(req)) + if err != nil { + return nil, err + } + if err := cli.Flush(ctx); err != nil { + return nil, err + } + return reqRes.Response.GetPrepareProposal(), cli.Error() +} + +func (cli *socketClient) ProcessProposal(ctx context.Context, req *types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { + reqRes, err := cli.queueRequest(ctx, types.ToRequestProcessProposal(req)) + if err != nil { + return nil, err + } + if err := cli.Flush(ctx); err != nil { + return nil, err + } + return reqRes.Response.GetProcessProposal(), cli.Error() +} + +func (cli *socketClient) FinalizeBlock(ctx context.Context, req *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { + reqRes, err := cli.queueRequest(ctx, types.ToRequestFinalizeBlock(req)) + if err != nil { + return nil, err + } + if err := cli.Flush(ctx); err != nil { + return nil, err + } + return reqRes.Response.GetFinalizeBlock(), cli.Error() +} + +func (cli *socketClient) queueRequest(ctx context.Context, req *types.Request) (*ReqRes, error) { reqres := NewReqRes(req) // TODO: set cli.err if reqQueue times out - cli.reqQueue <- reqres + select { + case cli.reqQueue <- reqres: + case <-ctx.Done(): + return nil, ctx.Err() + } // Maybe auto-flush, or unset auto-flush switch req.Value.(type) { @@ -446,9 +408,11 @@ func (cli *socketClient) queueRequest(req *types.Request) *ReqRes { cli.flushTimer.Set() } - return reqres + return reqres, nil } +// flushQueue marks as complete and discards all remaining pending requests +// from the queue. func (cli *socketClient) flushQueue() { cli.mtx.Lock() defer cli.mtx.Unlock() @@ -481,8 +445,6 @@ func resMatchesReq(req *types.Request, res *types.Response) (ok bool) { _, ok = res.Value.(*types.Response_Flush) case *types.Request_Info: _, ok = res.Value.(*types.Response_Info) - case *types.Request_DeliverTx: - _, ok = res.Value.(*types.Response_DeliverTx) case *types.Request_CheckTx: _, ok = res.Value.(*types.Response_CheckTx) case *types.Request_Commit: @@ -491,10 +453,6 @@ func resMatchesReq(req *types.Request, res *types.Response) (ok bool) { _, ok = res.Value.(*types.Response_Query) case *types.Request_InitChain: _, ok = res.Value.(*types.Response_InitChain) - case *types.Request_BeginBlock: - _, ok = res.Value.(*types.Response_BeginBlock) - case *types.Request_EndBlock: - _, ok = res.Value.(*types.Response_EndBlock) case *types.Request_ApplySnapshotChunk: _, ok = res.Value.(*types.Response_ApplySnapshotChunk) case *types.Request_LoadSnapshotChunk: @@ -507,6 +465,8 @@ func resMatchesReq(req *types.Request, res *types.Response) (ok bool) { _, ok = res.Value.(*types.Response_PrepareProposal) case *types.Request_ProcessProposal: _, ok = res.Value.(*types.Response_ProcessProposal) + case *types.Request_FinalizeBlock: + _, ok = res.Value.(*types.Response_FinalizeBlock) } return ok } diff --git a/abci/client/socket_client_test.go b/abci/client/socket_client_test.go index 9bf28fe12..54757eca8 100644 --- a/abci/client/socket_client_test.go +++ b/abci/client/socket_client_test.go @@ -1,7 +1,10 @@ package abcicli_test import ( + "context" "fmt" + "math/rand" + "os" "sync" "testing" "time" @@ -16,28 +19,17 @@ import ( "github.com/tendermint/tendermint/libs/service" ) -func TestProperSyncCalls(t *testing.T) { - app := slowApp{} +func TestCalls(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + app := types.BaseApplication{} - s, c := setupClientServer(t, app) - t.Cleanup(func() { - if err := s.Stop(); err != nil { - t.Error(err) - } - }) - t.Cleanup(func() { - if err := c.Stop(); err != nil { - t.Error(err) - } - }) + _, c := setupClientServer(t, app) resp := make(chan error, 1) go func() { - // This is BeginBlockSync unrolled.... - reqres := c.BeginBlockAsync(types.RequestBeginBlock{}) - err := c.FlushSync() + res, err := c.Echo(ctx, "hello") require.NoError(t, err) - res := reqres.Response.GetBeginBlock() require.NotNil(t, res) resp <- c.Error() }() @@ -51,36 +43,25 @@ func TestProperSyncCalls(t *testing.T) { } } -func TestHangingSyncCalls(t *testing.T) { +func TestHangingAsyncCalls(t *testing.T) { app := slowApp{} s, c := setupClientServer(t, app) - t.Cleanup(func() { - if err := s.Stop(); err != nil { - t.Log(err) - } - }) - t.Cleanup(func() { - if err := c.Stop(); err != nil { - t.Log(err) - } - }) resp := make(chan error, 1) go func() { - // Start BeginBlock and flush it - reqres := c.BeginBlockAsync(types.RequestBeginBlock{}) - flush := c.FlushAsync() - // wait 20 ms for all events to travel socket, but + // Call CheckTx + reqres, err := c.CheckTxAsync(context.Background(), &types.RequestCheckTx{}) + require.NoError(t, err) + // wait 50 ms for all events to travel socket, but // no response yet from server - time.Sleep(20 * time.Millisecond) + time.Sleep(50 * time.Millisecond) // kill the server, so the connections break - err := s.Stop() + err = s.Stop() require.NoError(t, err) - // wait for the response from BeginBlock + // wait for the response from CheckTx reqres.Wait() - flush.Wait() resp <- c.Error() }() @@ -93,21 +74,81 @@ func TestHangingSyncCalls(t *testing.T) { } } +func TestBulk(t *testing.T) { + const numTxs = 700000 + // use a socket instead of a port + socketFile := fmt.Sprintf("test-%08x.sock", rand.Int31n(1<<30)) + defer os.Remove(socketFile) + socket := fmt.Sprintf("unix://%v", socketFile) + app := types.NewBaseApplication() + // Start the listener + server := server.NewSocketServer(socket, app) + t.Cleanup(func() { + if err := server.Stop(); err != nil { + t.Log(err) + } + }) + err := server.Start() + require.NoError(t, err) + + // Connect to the socket + client := abcicli.NewSocketClient(socket, false) + + t.Cleanup(func() { + if err := client.Stop(); err != nil { + t.Log(err) + } + }) + + err = client.Start() + require.NoError(t, err) + + // Construct request + rfb := &types.RequestFinalizeBlock{Txs: make([][]byte, numTxs)} + for counter := 0; counter < numTxs; counter++ { + rfb.Txs[counter] = []byte("test") + } + // Send bulk request + res, err := client.FinalizeBlock(context.Background(), rfb) + require.NoError(t, err) + require.Equal(t, numTxs, len(res.TxResults), "Number of txs doesn't match") + for _, tx := range res.TxResults { + require.Equal(t, uint32(0), tx.Code, "Tx failed") + } + + // Send final flush message + err = client.Flush(context.Background()) + require.NoError(t, err) +} + func setupClientServer(t *testing.T, app types.Application) ( service.Service, abcicli.Client) { + t.Helper() + // some port between 20k and 30k port := 20000 + tmrand.Int32()%10000 addr := fmt.Sprintf("localhost:%d", port) - s, err := server.NewServer(addr, "socket", app) - require.NoError(t, err) - err = s.Start() + s := server.NewSocketServer(addr, app) + err := s.Start() require.NoError(t, err) + t.Cleanup(func() { + if err := s.Stop(); err != nil { + t.Log(err) + } + }) + c := abcicli.NewSocketClient(addr, true) err = c.Start() require.NoError(t, err) + t.Cleanup(func() { + if err := c.Stop(); err != nil { + t.Log(err) + } + }) + return s, c } @@ -115,9 +156,9 @@ type slowApp struct { types.BaseApplication } -func (slowApp) BeginBlock(req types.RequestBeginBlock) types.ResponseBeginBlock { - time.Sleep(200 * time.Millisecond) - return types.ResponseBeginBlock{} +func (slowApp) CheckTx(_ context.Context, req *types.RequestCheckTx) (*types.ResponseCheckTx, error) { + time.Sleep(time.Second) + return &types.ResponseCheckTx{}, nil } // TestCallbackInvokedWhenSetLaet ensures that the callback is invoked when @@ -125,13 +166,17 @@ func (slowApp) BeginBlock(req types.RequestBeginBlock) types.ResponseBeginBlock // test relies on the callback being allowed to be invoked twice if set multiple // times, once when set early and once when set late. func TestCallbackInvokedWhenSetLate(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + wg := &sync.WaitGroup{} wg.Add(1) app := blockedABCIApplication{ wg: wg, } _, c := setupClientServer(t, app) - reqRes := c.CheckTxAsync(types.RequestCheckTx{}) + reqRes, err := c.CheckTxAsync(ctx, &types.RequestCheckTx{}) + require.NoError(t, err) done := make(chan struct{}) cb := func(_ *types.Response) { @@ -154,21 +199,25 @@ type blockedABCIApplication struct { types.BaseApplication } -func (b blockedABCIApplication) CheckTx(r types.RequestCheckTx) types.ResponseCheckTx { +func (b blockedABCIApplication) CheckTxAsync(ctx context.Context, r *types.RequestCheckTx) (*types.ResponseCheckTx, error) { b.wg.Wait() - return b.BaseApplication.CheckTx(r) + return b.BaseApplication.CheckTx(ctx, r) } // TestCallbackInvokedWhenSetEarly ensures that the callback is invoked when // set before the client completes the call into the app. func TestCallbackInvokedWhenSetEarly(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + wg := &sync.WaitGroup{} wg.Add(1) app := blockedABCIApplication{ wg: wg, } _, c := setupClientServer(t, app) - reqRes := c.CheckTxAsync(types.RequestCheckTx{}) + reqRes, err := c.CheckTxAsync(ctx, &types.RequestCheckTx{}) + require.NoError(t, err) done := make(chan struct{}) cb := func(_ *types.Response) { diff --git a/abci/client/unsync_local_client.go b/abci/client/unsync_local_client.go index 3198c1720..0f37c0fda 100644 --- a/abci/client/unsync_local_client.go +++ b/abci/client/unsync_local_client.go @@ -1,6 +1,7 @@ package abcicli import ( + "context" "sync" types "github.com/tendermint/tendermint/abci/types" @@ -32,227 +33,38 @@ func NewUnsyncLocalClient(app types.Application) Client { return cli } +// TODO: change types.Application to include Error()? +func (app *unsyncLocalClient) Error() error { + return nil +} + +func (app *unsyncLocalClient) Flush(_ context.Context) error { + return nil +} + +func (app *unsyncLocalClient) Echo(ctx context.Context, msg string) (*types.ResponseEcho, error) { + return &types.ResponseEcho{Message: msg}, nil +} + +//------------------------------------------------------- + func (app *unsyncLocalClient) SetResponseCallback(cb Callback) { app.mtx.Lock() defer app.mtx.Unlock() app.Callback = cb } -// TODO: change types.Application to include Error()? -func (app *unsyncLocalClient) Error() error { - return nil -} - -func (app *unsyncLocalClient) FlushAsync() *ReqRes { - // Do nothing - return newLocalReqRes(types.ToRequestFlush(), nil) -} - -func (app *unsyncLocalClient) EchoAsync(msg string) *ReqRes { - return app.callback( - types.ToRequestEcho(msg), - types.ToResponseEcho(msg), - ) -} - -func (app *unsyncLocalClient) InfoAsync(req types.RequestInfo) *ReqRes { - res := app.Application.Info(req) - return app.callback( - types.ToRequestInfo(req), - types.ToResponseInfo(res), - ) -} - -func (app *unsyncLocalClient) DeliverTxAsync(params types.RequestDeliverTx) *ReqRes { - res := app.Application.DeliverTx(params) - return app.callback( - types.ToRequestDeliverTx(params), - types.ToResponseDeliverTx(res), - ) -} - -func (app *unsyncLocalClient) CheckTxAsync(req types.RequestCheckTx) *ReqRes { - res := app.Application.CheckTx(req) +func (app *unsyncLocalClient) CheckTxAsync(ctx context.Context, req *types.RequestCheckTx) (*ReqRes, error) { + res, err := app.Application.CheckTx(ctx, req) + if err != nil { + return nil, err + } return app.callback( types.ToRequestCheckTx(req), types.ToResponseCheckTx(res), - ) + ), nil } -func (app *unsyncLocalClient) QueryAsync(req types.RequestQuery) *ReqRes { - res := app.Application.Query(req) - return app.callback( - types.ToRequestQuery(req), - types.ToResponseQuery(res), - ) -} - -func (app *unsyncLocalClient) CommitAsync() *ReqRes { - res := app.Application.Commit() - return app.callback( - types.ToRequestCommit(), - types.ToResponseCommit(res), - ) -} - -func (app *unsyncLocalClient) InitChainAsync(req types.RequestInitChain) *ReqRes { - res := app.Application.InitChain(req) - return app.callback( - types.ToRequestInitChain(req), - types.ToResponseInitChain(res), - ) -} - -func (app *unsyncLocalClient) BeginBlockAsync(req types.RequestBeginBlock) *ReqRes { - res := app.Application.BeginBlock(req) - return app.callback( - types.ToRequestBeginBlock(req), - types.ToResponseBeginBlock(res), - ) -} - -func (app *unsyncLocalClient) EndBlockAsync(req types.RequestEndBlock) *ReqRes { - res := app.Application.EndBlock(req) - return app.callback( - types.ToRequestEndBlock(req), - types.ToResponseEndBlock(res), - ) -} - -func (app *unsyncLocalClient) ListSnapshotsAsync(req types.RequestListSnapshots) *ReqRes { - res := app.Application.ListSnapshots(req) - return app.callback( - types.ToRequestListSnapshots(req), - types.ToResponseListSnapshots(res), - ) -} - -func (app *unsyncLocalClient) OfferSnapshotAsync(req types.RequestOfferSnapshot) *ReqRes { - res := app.Application.OfferSnapshot(req) - return app.callback( - types.ToRequestOfferSnapshot(req), - types.ToResponseOfferSnapshot(res), - ) -} - -func (app *unsyncLocalClient) LoadSnapshotChunkAsync(req types.RequestLoadSnapshotChunk) *ReqRes { - res := app.Application.LoadSnapshotChunk(req) - return app.callback( - types.ToRequestLoadSnapshotChunk(req), - types.ToResponseLoadSnapshotChunk(res), - ) -} - -func (app *unsyncLocalClient) ApplySnapshotChunkAsync(req types.RequestApplySnapshotChunk) *ReqRes { - res := app.Application.ApplySnapshotChunk(req) - return app.callback( - types.ToRequestApplySnapshotChunk(req), - types.ToResponseApplySnapshotChunk(res), - ) -} - -func (app *unsyncLocalClient) PrepareProposalAsync(req types.RequestPrepareProposal) *ReqRes { - res := app.Application.PrepareProposal(req) - return app.callback( - types.ToRequestPrepareProposal(req), - types.ToResponsePrepareProposal(res), - ) -} - -func (app *unsyncLocalClient) ProcessProposalAsync(req types.RequestProcessProposal) *ReqRes { - res := app.Application.ProcessProposal(req) - return app.callback( - types.ToRequestProcessProposal(req), - types.ToResponseProcessProposal(res), - ) -} - -//------------------------------------------------------- - -func (app *unsyncLocalClient) FlushSync() error { - return nil -} - -func (app *unsyncLocalClient) EchoSync(msg string) (*types.ResponseEcho, error) { - return &types.ResponseEcho{Message: msg}, nil -} - -func (app *unsyncLocalClient) InfoSync(req types.RequestInfo) (*types.ResponseInfo, error) { - res := app.Application.Info(req) - return &res, nil -} - -func (app *unsyncLocalClient) DeliverTxSync(req types.RequestDeliverTx) (*types.ResponseDeliverTx, error) { - res := app.Application.DeliverTx(req) - return &res, nil -} - -func (app *unsyncLocalClient) CheckTxSync(req types.RequestCheckTx) (*types.ResponseCheckTx, error) { - res := app.Application.CheckTx(req) - return &res, nil -} - -func (app *unsyncLocalClient) QuerySync(req types.RequestQuery) (*types.ResponseQuery, error) { - res := app.Application.Query(req) - return &res, nil -} - -func (app *unsyncLocalClient) CommitSync() (*types.ResponseCommit, error) { - res := app.Application.Commit() - return &res, nil -} - -func (app *unsyncLocalClient) InitChainSync(req types.RequestInitChain) (*types.ResponseInitChain, error) { - res := app.Application.InitChain(req) - return &res, nil -} - -func (app *unsyncLocalClient) BeginBlockSync(req types.RequestBeginBlock) (*types.ResponseBeginBlock, error) { - res := app.Application.BeginBlock(req) - return &res, nil -} - -func (app *unsyncLocalClient) EndBlockSync(req types.RequestEndBlock) (*types.ResponseEndBlock, error) { - res := app.Application.EndBlock(req) - return &res, nil -} - -func (app *unsyncLocalClient) ListSnapshotsSync(req types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { - res := app.Application.ListSnapshots(req) - return &res, nil -} - -func (app *unsyncLocalClient) OfferSnapshotSync(req types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { - res := app.Application.OfferSnapshot(req) - return &res, nil -} - -func (app *unsyncLocalClient) LoadSnapshotChunkSync( - req types.RequestLoadSnapshotChunk, -) (*types.ResponseLoadSnapshotChunk, error) { - res := app.Application.LoadSnapshotChunk(req) - return &res, nil -} - -func (app *unsyncLocalClient) ApplySnapshotChunkSync( - req types.RequestApplySnapshotChunk, -) (*types.ResponseApplySnapshotChunk, error) { - res := app.Application.ApplySnapshotChunk(req) - return &res, nil -} - -func (app *unsyncLocalClient) PrepareProposalSync(req types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { - res := app.Application.PrepareProposal(req) - return &res, nil -} - -func (app *unsyncLocalClient) ProcessProposalSync(req types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { - res := app.Application.ProcessProposal(req) - return &res, nil -} - -//------------------------------------------------------- - func (app *unsyncLocalClient) callback(req *types.Request, res *types.Response) *ReqRes { app.mtx.RLock() defer app.mtx.RUnlock() diff --git a/abci/cmd/abci-cli/abci-cli.go b/abci/cmd/abci-cli/abci-cli.go index e8de62d10..11ffe2016 100644 --- a/abci/cmd/abci-cli/abci-cli.go +++ b/abci/cmd/abci-cli/abci-cli.go @@ -15,7 +15,6 @@ import ( tmos "github.com/tendermint/tendermint/libs/os" abcicli "github.com/tendermint/tendermint/abci/client" - "github.com/tendermint/tendermint/abci/example/code" "github.com/tendermint/tendermint/abci/example/kvstore" "github.com/tendermint/tendermint/abci/server" servertest "github.com/tendermint/tendermint/abci/tests/server" @@ -139,7 +138,6 @@ func addCommands() { RootCmd.AddCommand(consoleCmd) RootCmd.AddCommand(echoCmd) RootCmd.AddCommand(infoCmd) - RootCmd.AddCommand(deliverTxCmd) RootCmd.AddCommand(checkTxCmd) RootCmd.AddCommand(commitCmd) RootCmd.AddCommand(versionCmd) @@ -148,6 +146,7 @@ func addCommands() { RootCmd.AddCommand(processProposalCmd) addQueryFlags() RootCmd.AddCommand(queryCmd) + RootCmd.AddCommand(finalizeBlockCmd) // examples addKVStoreFlags() @@ -168,10 +167,9 @@ where example.file looks something like: check_tx 0x00 check_tx 0xff - deliver_tx 0x00 + finalize_block 0x00 check_tx 0x00 - deliver_tx 0x01 - deliver_tx 0x04 + finalize_block 0x01 0x04 0xff info `, Args: cobra.ExactArgs(0), @@ -187,7 +185,7 @@ This command opens an interactive console for running any of the other commands without opening a new connection each time `, Args: cobra.ExactArgs(0), - ValidArgs: []string{"echo", "info", "deliver_tx", "check_tx", "prepare_proposal", "process_proposal", "commit", "query"}, + ValidArgs: []string{"echo", "info", "finalize_block", "check_tx", "prepare_proposal", "process_proposal", "commit", "query"}, RunE: cmdConsole, } @@ -206,12 +204,12 @@ var infoCmd = &cobra.Command{ RunE: cmdInfo, } -var deliverTxCmd = &cobra.Command{ - Use: "deliver_tx", - Short: "deliver a new transaction to the application", - Long: "deliver a new transaction to the application", - Args: cobra.ExactArgs(1), - RunE: cmdDeliverTx, +var finalizeBlockCmd = &cobra.Command{ + Use: "finalize_block", + Short: "deliver a block of transactions to the application", + Long: "deliver a block of transactions to the application", + Args: cobra.MinimumNArgs(1), + RunE: cmdFinalizeBlock, } var checkTxCmd = &cobra.Command{ @@ -311,30 +309,52 @@ func compose(fs []func() error) error { } func cmdTest(cmd *cobra.Command, args []string) error { + ctx := cmd.Context() return compose( []func() error{ - func() error { return servertest.InitChain(client) }, - func() error { return servertest.Commit(client, nil) }, - func() error { return servertest.DeliverTx(client, []byte("abc"), code.CodeTypeBadNonce, nil) }, - func() error { return servertest.Commit(client, nil) }, - func() error { return servertest.DeliverTx(client, []byte{0x00}, code.CodeTypeOK, nil) }, - func() error { return servertest.Commit(client, []byte{0, 0, 0, 0, 0, 0, 0, 1}) }, - func() error { return servertest.DeliverTx(client, []byte{0x00}, code.CodeTypeBadNonce, nil) }, - func() error { return servertest.DeliverTx(client, []byte{0x01}, code.CodeTypeOK, nil) }, - func() error { return servertest.DeliverTx(client, []byte{0x00, 0x02}, code.CodeTypeOK, nil) }, - func() error { return servertest.DeliverTx(client, []byte{0x00, 0x03}, code.CodeTypeOK, nil) }, - func() error { return servertest.DeliverTx(client, []byte{0x00, 0x00, 0x04}, code.CodeTypeOK, nil) }, + func() error { return servertest.InitChain(ctx, client) }, + func() error { return servertest.Commit(ctx, client) }, func() error { - return servertest.DeliverTx(client, []byte{0x00, 0x00, 0x06}, code.CodeTypeBadNonce, nil) + return servertest.FinalizeBlock(ctx, client, [][]byte{ + []byte("abc"), + }, []uint32{ + kvstore.CodeTypeInvalidTxFormat, + }, nil, nil) }, - func() error { return servertest.Commit(client, []byte{0, 0, 0, 0, 0, 0, 0, 5}) }, + func() error { return servertest.Commit(ctx, client) }, func() error { - return servertest.PrepareProposal(client, [][]byte{ + return servertest.FinalizeBlock(ctx, client, [][]byte{ + {0x00}, + }, []uint32{ + kvstore.CodeTypeOK, + }, nil, []byte{0, 0, 0, 0, 0, 0, 0, 1}) + }, + func() error { return servertest.Commit(ctx, client) }, + func() error { + return servertest.FinalizeBlock(ctx, client, [][]byte{ + {0x00}, + {0x01}, + {0x00, 0x02}, + {0x00, 0x03}, + {0x00, 0x00, 0x04}, + {0x00, 0x00, 0x06}, + }, []uint32{ + kvstore.CodeTypeInvalidTxFormat, + kvstore.CodeTypeOK, + kvstore.CodeTypeOK, + kvstore.CodeTypeOK, + kvstore.CodeTypeOK, + kvstore.CodeTypeInvalidTxFormat, + }, nil, []byte{0, 0, 0, 0, 0, 0, 0, 5}) + }, + func() error { return servertest.Commit(ctx, client) }, + func() error { + return servertest.PrepareProposal(ctx, client, [][]byte{ {0x01}, }, [][]byte{{0x01}}, nil) }, func() error { - return servertest.ProcessProposal(client, [][]byte{ + return servertest.ProcessProposal(ctx, client, [][]byte{ {0x01}, }, types.ResponseProcessProposal_ACCEPT) }, @@ -430,8 +450,8 @@ func muxOnCommands(cmd *cobra.Command, pArgs []string) error { return cmdCheckTx(cmd, actualArgs) case "commit": return cmdCommit(cmd, actualArgs) - case "deliver_tx": - return cmdDeliverTx(cmd, actualArgs) + case "finalize_block": + return cmdFinalizeBlock(cmd, actualArgs) case "echo": return cmdEcho(cmd, actualArgs) case "info": @@ -462,7 +482,7 @@ func cmdUnimplemented(cmd *cobra.Command, args []string) error { fmt.Printf("%s: %s\n", echoCmd.Use, echoCmd.Short) fmt.Printf("%s: %s\n", infoCmd.Use, infoCmd.Short) fmt.Printf("%s: %s\n", checkTxCmd.Use, checkTxCmd.Short) - fmt.Printf("%s: %s\n", deliverTxCmd.Use, deliverTxCmd.Short) + fmt.Printf("%s: %s\n", finalizeBlockCmd.Use, finalizeBlockCmd.Short) fmt.Printf("%s: %s\n", queryCmd.Use, queryCmd.Short) fmt.Printf("%s: %s\n", commitCmd.Use, commitCmd.Short) fmt.Println("Use \"[command] --help\" for more information about a command.") @@ -476,13 +496,15 @@ func cmdEcho(cmd *cobra.Command, args []string) error { if len(args) > 0 { msg = args[0] } - res, err := client.EchoSync(msg) + res, err := client.Echo(cmd.Context(), msg) if err != nil { return err } + printResponse(cmd, args, response{ Data: []byte(res.Message), }) + return nil } @@ -492,7 +514,7 @@ func cmdInfo(cmd *cobra.Command, args []string) error { if len(args) == 1 { version = args[0] } - res, err := client.InfoSync(types.RequestInfo{Version: version}) + res, err := client.Info(cmd.Context(), &types.RequestInfo{Version: version}) if err != nil { return err } @@ -504,29 +526,40 @@ func cmdInfo(cmd *cobra.Command, args []string) error { const codeBad uint32 = 10 -// Append a new tx to application -func cmdDeliverTx(cmd *cobra.Command, args []string) error { +// Append new txs to application +func cmdFinalizeBlock(cmd *cobra.Command, args []string) error { if len(args) == 0 { printResponse(cmd, args, response{ Code: codeBad, - Log: "want the tx", + Log: "Must provide at least one transaction", }) return nil } - txBytes, err := stringOrHexToBytes(args[0]) + txs := make([][]byte, len(args)) + for i, arg := range args { + txBytes, err := stringOrHexToBytes(arg) + if err != nil { + return err + } + txs[i] = txBytes + } + res, err := client.FinalizeBlock(cmd.Context(), &types.RequestFinalizeBlock{Txs: txs}) if err != nil { return err } - res, err := client.DeliverTxSync(types.RequestDeliverTx{Tx: txBytes}) - if err != nil { - return err + resps := make([]response, 0, len(res.TxResults)+1) + for _, tx := range res.TxResults { + resps = append(resps, response{ + Code: tx.Code, + Data: tx.Data, + Info: tx.Info, + Log: tx.Log, + }) } - printResponse(cmd, args, response{ - Code: res.Code, - Data: res.Data, - Info: res.Info, - Log: res.Log, + resps = append(resps, response{ + Data: res.AgreedAppData, }) + printResponse(cmd, args, resps...) return nil } @@ -543,7 +576,7 @@ func cmdCheckTx(cmd *cobra.Command, args []string) error { if err != nil { return err } - res, err := client.CheckTxSync(types.RequestCheckTx{Tx: txBytes}) + res, err := client.CheckTx(cmd.Context(), &types.RequestCheckTx{Tx: txBytes}) if err != nil { return err } @@ -558,13 +591,11 @@ 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() + _, err := client.Commit(cmd.Context(), &types.RequestCommit{}) if err != nil { return err } - printResponse(cmd, args, response{ - Data: res.Data, - }) + printResponse(cmd, args, response{}) return nil } @@ -583,7 +614,7 @@ func cmdQuery(cmd *cobra.Command, args []string) error { return err } - resQuery, err := client.QuerySync(types.RequestQuery{ + resQuery, err := client.Query(cmd.Context(), &types.RequestQuery{ Data: queryBytes, Path: flagPath, Height: int64(flagHeight), @@ -617,7 +648,7 @@ func cmdPrepareProposal(cmd *cobra.Command, args []string) error { txsBytesArray[i] = txBytes } - res, err := client.PrepareProposalSync(types.RequestPrepareProposal{ + res, err := client.PrepareProposal(cmd.Context(), &types.RequestPrepareProposal{ Txs: txsBytesArray, // kvstore has to have this parameter in order not to reject a tx as the default value is 0 MaxTxBytes: 65536, @@ -628,7 +659,7 @@ func cmdPrepareProposal(cmd *cobra.Command, args []string) error { resps := make([]response, 0, len(res.Txs)) for _, tx := range res.Txs { resps = append(resps, response{ - Code: code.CodeTypeOK, + Code: 0, // CodeOK Log: "Succeeded. Tx: " + string(tx), }) } @@ -648,7 +679,7 @@ func cmdProcessProposal(cmd *cobra.Command, args []string) error { txsBytesArray[i] = txBytes } - res, err := client.ProcessProposalSync(types.RequestProcessProposal{ + res, err := client.ProcessProposal(cmd.Context(), &types.RequestProcessProposal{ Txs: txsBytesArray, }) if err != nil { @@ -673,8 +704,7 @@ func cmdKVStore(cmd *cobra.Command, args []string) error { return err } } - app = kvstore.NewPersistentKVStoreApplication(flagPersist) - app.(*kvstore.PersistentKVStoreApplication).SetLogger(logger.With("module", "kvstore")) + app = kvstore.NewPersistentApplication(flagPersist) // Start the listener srv, err := server.NewServer(flagAddress, flagAbci, app) @@ -716,9 +746,9 @@ func printResponse(cmd *cobra.Command, args []string, rsps ...response) { } if len(rsp.Data) != 0 { - // Do no print this line when using the commit command + // Do no print this line when using the finalize_block command // because the string comes out as gibberish - if cmd.Use != "commit" { + if cmd.Use != "finalize_block" { fmt.Printf("-> data: %s\n", rsp.Data) } fmt.Printf("-> data.hex: 0x%X\n", rsp.Data) diff --git a/abci/example/code/code.go b/abci/example/code/code.go deleted file mode 100644 index 6d011ed9d..000000000 --- a/abci/example/code/code.go +++ /dev/null @@ -1,11 +0,0 @@ -package code - -// Return codes for the examples -const ( - CodeTypeOK uint32 = 0 - CodeTypeEncodingError uint32 = 1 - CodeTypeBadNonce uint32 = 2 - CodeTypeUnauthorized uint32 = 3 - CodeTypeUnknownError uint32 = 4 - CodeTypeExecuted uint32 = 5 -) diff --git a/abci/example/example.go b/abci/example/example.go deleted file mode 100644 index ee491c1b5..000000000 --- a/abci/example/example.go +++ /dev/null @@ -1,3 +0,0 @@ -package example - -// so the go tool doesn't return errors about no buildable go files ... diff --git a/abci/example/example_test.go b/abci/example/example_test.go deleted file mode 100644 index e5c99b1cd..000000000 --- a/abci/example/example_test.go +++ /dev/null @@ -1,187 +0,0 @@ -package example - -import ( - "fmt" - "math/rand" - "net" - "os" - "reflect" - "testing" - "time" - - "github.com/stretchr/testify/require" - - "google.golang.org/grpc" - - "golang.org/x/net/context" - - "github.com/tendermint/tendermint/libs/log" - tmnet "github.com/tendermint/tendermint/libs/net" - - abcicli "github.com/tendermint/tendermint/abci/client" - "github.com/tendermint/tendermint/abci/example/code" - "github.com/tendermint/tendermint/abci/example/kvstore" - abciserver "github.com/tendermint/tendermint/abci/server" - "github.com/tendermint/tendermint/abci/types" -) - -func init() { - rand.Seed(time.Now().UnixNano()) -} - -func TestKVStore(t *testing.T) { - fmt.Println("### Testing KVStore") - testStream(t, kvstore.NewApplication()) -} - -func TestBaseApp(t *testing.T) { - fmt.Println("### Testing BaseApp") - testStream(t, types.NewBaseApplication()) -} - -func TestGRPC(t *testing.T) { - fmt.Println("### Testing GRPC") - testGRPCSync(t, types.NewGRPCApplication(types.NewBaseApplication())) -} - -func testStream(t *testing.T, app types.Application) { - numDeliverTxs := 20000 - socketFile := fmt.Sprintf("test-%08x.sock", rand.Int31n(1<<30)) - defer os.Remove(socketFile) - socket := fmt.Sprintf("unix://%v", socketFile) - - // Start the listener - server := abciserver.NewSocketServer(socket, app) - server.SetLogger(log.TestingLogger().With("module", "abci-server")) - if err := server.Start(); err != nil { - require.NoError(t, err, "Error starting socket server") - } - t.Cleanup(func() { - if err := server.Stop(); err != nil { - t.Error(err) - } - }) - - // Connect to the socket - client := abcicli.NewSocketClient(socket, false) - client.SetLogger(log.TestingLogger().With("module", "abci-client")) - if err := client.Start(); err != nil { - t.Fatalf("Error starting socket client: %v", err.Error()) - } - t.Cleanup(func() { - if err := client.Stop(); err != nil { - t.Error(err) - } - }) - - done := make(chan struct{}) - counter := 0 - client.SetResponseCallback(func(req *types.Request, res *types.Response) { - // Process response - switch r := res.Value.(type) { - case *types.Response_DeliverTx: - counter++ - if r.DeliverTx.Code != code.CodeTypeOK { - t.Error("DeliverTx failed with ret_code", r.DeliverTx.Code) - } - if counter > numDeliverTxs { - t.Fatalf("Too many DeliverTx responses. Got %d, expected %d", counter, numDeliverTxs) - } - if counter == numDeliverTxs { - go func() { - time.Sleep(time.Second * 1) // Wait for a bit to allow counter overflow - close(done) - }() - return - } - case *types.Response_Flush: - // ignore - default: - t.Error("Unexpected response type", reflect.TypeOf(res.Value)) - } - }) - - // Write requests - for counter := 0; counter < numDeliverTxs; counter++ { - // Send request - reqRes := client.DeliverTxAsync(types.RequestDeliverTx{Tx: []byte("test")}) - _ = reqRes - // check err ? - - // Sometimes send flush messages - if counter%123 == 0 { - client.FlushAsync() - // check err ? - } - } - - // Send final flush message - client.FlushAsync() - - <-done -} - -//------------------------- -// test grpc - -func dialerFunc(ctx context.Context, addr string) (net.Conn, error) { - return tmnet.Connect(addr) -} - -func testGRPCSync(t *testing.T, app types.ABCIApplicationServer) { - numDeliverTxs := 2000 - socketFile := fmt.Sprintf("/tmp/test-%08x.sock", rand.Int31n(1<<30)) - defer os.Remove(socketFile) - socket := fmt.Sprintf("unix://%v", socketFile) - - // Start the listener - server := abciserver.NewGRPCServer(socket, app) - server.SetLogger(log.TestingLogger().With("module", "abci-server")) - if err := server.Start(); err != nil { - t.Fatalf("Error starting GRPC server: %v", err.Error()) - } - - t.Cleanup(func() { - if err := server.Stop(); err != nil { - t.Error(err) - } - }) - - // Connect to the socket - //nolint:staticcheck // SA1019 Existing use of deprecated but supported dial option. - conn, err := grpc.Dial(socket, grpc.WithInsecure(), grpc.WithContextDialer(dialerFunc)) - if err != nil { - t.Fatalf("Error dialing GRPC server: %v", err.Error()) - } - - t.Cleanup(func() { - if err := conn.Close(); err != nil { - t.Error(err) - } - }) - - client := types.NewABCIApplicationClient(conn) - - // Write requests - for counter := 0; counter < numDeliverTxs; counter++ { - // Send request - response, err := client.DeliverTx(context.Background(), &types.RequestDeliverTx{Tx: []byte("test")}) - if err != nil { - t.Fatalf("Error in GRPC DeliverTx: %v", err.Error()) - } - counter++ - if response.Code != code.CodeTypeOK { - t.Error("DeliverTx failed with ret_code", response.Code) - } - if counter > numDeliverTxs { - t.Fatal("Too many DeliverTx responses") - } - t.Log("response", counter) - if counter == numDeliverTxs { - go func() { - time.Sleep(time.Second * 1) // Wait for a bit to allow counter overflow - }() - } - - } -} diff --git a/abci/example/kvstore/README.md b/abci/example/kvstore/README.md index edc2c47a5..e97debb1d 100644 --- a/abci/example/kvstore/README.md +++ b/abci/example/kvstore/README.md @@ -1,24 +1,10 @@ # KVStore -There are two app's here: the KVStoreApplication and the PersistentKVStoreApplication. - -## KVStoreApplication - The KVStoreApplication is a simple merkle key-value store. Transactions of the form `key=value` are stored as key-value pairs in the tree. Transactions without an `=` sign set the value to the key. The app has no replay protection (other than what the mempool provides). -## PersistentKVStoreApplication - -The PersistentKVStoreApplication wraps the KVStoreApplication -and provides two additional features: - -1) persistence of state across app restarts (using Tendermint's ABCI-Handshake mechanism) -2) validator set changes - -The state is persisted in leveldb along with the last block committed, -and the Handshake allows any necessary blocks to be replayed. Validator set changes are effected using the following transaction format: ```md @@ -27,4 +13,4 @@ Validator set changes are effected using the following transaction format: where `pubkeyN` is a base64-encoded 32-byte ed25519 key and `powerN` is a new voting power for the validator with `pubkeyN` (possibly a new one). To remove a validator from the validator set, set power to `0`. -There is no sybil protection against new validators joining. +There is no sybil protection against new validators joining. diff --git a/abci/example/kvstore/code.go b/abci/example/kvstore/code.go new file mode 100644 index 000000000..f58cfb83c --- /dev/null +++ b/abci/example/kvstore/code.go @@ -0,0 +1,10 @@ +package kvstore + +// Return codes for the examples +const ( + CodeTypeOK uint32 = 0 + CodeTypeEncodingError uint32 = 1 + CodeTypeInvalidTxFormat uint32 = 2 + CodeTypeUnauthorized uint32 = 3 + CodeTypeExecuted uint32 = 5 +) diff --git a/abci/example/kvstore/helpers.go b/abci/example/kvstore/helpers.go index e59fee279..dc1c607e3 100644 --- a/abci/example/kvstore/helpers.go +++ b/abci/example/kvstore/helpers.go @@ -1,8 +1,15 @@ package kvstore import ( + "context" + "encoding/base64" + "fmt" + "strings" + "github.com/tendermint/tendermint/abci/types" + cryptoencoding "github.com/tendermint/tendermint/crypto/encoding" tmrand "github.com/tendermint/tendermint/libs/rand" + "github.com/tendermint/tendermint/proto/tendermint/crypto" ) // RandVal creates one random validator, with a key derived @@ -29,8 +36,44 @@ func RandVals(cnt int) []types.ValidatorUpdate { // InitKVStore initializes the kvstore app with some data, // which allows tests to pass and is fine as long as you // don't make any tx that modify the validator state -func InitKVStore(app *PersistentKVStoreApplication) { - app.InitChain(types.RequestInitChain{ +func InitKVStore(ctx context.Context, app *Application) error { + _, err := app.InitChain(ctx, &types.RequestInitChain{ Validators: RandVals(1), }) + return err +} + +// Create a new transaction +func NewTx(key, value string) []byte { + return []byte(strings.Join([]string{key, value}, "=")) +} + +func NewRandomTx(size int) []byte { + if size < 4 { + panic("random tx size must be greater than 3") + } + return NewTx(tmrand.Str(2), tmrand.Str(size-3)) +} + +func NewRandomTxs(n int) [][]byte { + txs := make([][]byte, n) + for i := 0; i < n; i++ { + txs[i] = NewRandomTx(10) + } + return txs +} + +func NewTxFromID(i int) []byte { + return []byte(fmt.Sprintf("%d=%d", i, i)) +} + +// Create a transaction to add/remove/update a validator +// To remove, set power to 0. +func MakeValSetChangeTx(pubkey crypto.PublicKey, power int64) []byte { + pk, err := cryptoencoding.PubKeyFromProto(pubkey) + if err != nil { + panic(err) + } + pubStr := base64.StdEncoding.EncodeToString(pk.Bytes()) + return []byte(fmt.Sprintf("%s%s!%d", ValidatorPrefix, pubStr, power)) } diff --git a/abci/example/kvstore/kvstore.go b/abci/example/kvstore/kvstore.go index 3188c9425..bb8149761 100644 --- a/abci/example/kvstore/kvstore.go +++ b/abci/example/kvstore/kvstore.go @@ -2,29 +2,426 @@ package kvstore import ( "bytes" + "context" + "encoding/base64" "encoding/binary" "encoding/json" "fmt" + "strconv" + "strings" dbm "github.com/tendermint/tm-db" - "github.com/tendermint/tendermint/abci/example/code" "github.com/tendermint/tendermint/abci/types" + cryptoencoding "github.com/tendermint/tendermint/crypto/encoding" + "github.com/tendermint/tendermint/libs/log" + cryptoproto "github.com/tendermint/tendermint/proto/tendermint/crypto" "github.com/tendermint/tendermint/version" ) var ( stateKey = []byte("stateKey") kvPairPrefixKey = []byte("kvPairKey:") - - ProtocolVersion uint64 = 0x1 ) +const ( + ValidatorPrefix = "val=" + AppVersion uint64 = 1 +) + +var _ types.Application = (*Application)(nil) + +// Application is the kvstore state machine. It complies with the abci.Application interface. +// It takes transactions in the form of key=value and saves them in a database. This is +// a somewhat trivial example as there is no real state execution +type Application struct { + types.BaseApplication + + state State + RetainBlocks int64 // blocks to retain after commit (via ResponseCommit.RetainHeight) + stagedTxs [][]byte + logger log.Logger + + // validator set + valUpdates []types.ValidatorUpdate + valAddrToPubKeyMap map[string]cryptoproto.PublicKey +} + +// NewApplication creates an instance of the kvstore from the provided database +func NewApplication(db dbm.DB) *Application { + return &Application{ + logger: log.NewNopLogger(), + state: loadState(db), + valAddrToPubKeyMap: make(map[string]cryptoproto.PublicKey), + } +} + +// NewPersistentApplication creates a new application using the goleveldb database engine +func NewPersistentApplication(dbDir string) *Application { + name := "kvstore" + db, err := dbm.NewGoLevelDB(name, dbDir) + if err != nil { + panic(fmt.Errorf("failed to create persistent app at %s: %w", dbDir, err)) + } + return NewApplication(db) +} + +// NewInMemoryApplication creates a new application from an in memory database. +// Nothing will be persisted. +func NewInMemoryApplication() *Application { + return NewApplication(dbm.NewMemDB()) +} + +// Info returns information about the state of the application. This is generally used everytime a Tendermint instance +// begins and let's the application know what Tendermint versions it's interacting with. Based from this information, +// Tendermint will ensure it is in sync with the application by potentially replaying the blocks it has. If the +// Application returns a 0 appBlockHeight, Tendermint will call InitChain to initialize the application with consensus related data +func (app *Application) Info(_ context.Context, req *types.RequestInfo) (*types.ResponseInfo, error) { + // Tendermint expects the application to persist validators, on start-up we need to reload them to memory if they exist + if len(app.valAddrToPubKeyMap) == 0 && app.state.Height > 0 { + validators := app.getValidators() + for _, v := range validators { + pubkey, err := cryptoencoding.PubKeyFromProto(v.PubKey) + if err != nil { + panic(fmt.Errorf("can't decode public key: %w", err)) + } + app.valAddrToPubKeyMap[string(pubkey.Address())] = v.PubKey + } + } + + return &types.ResponseInfo{ + Data: fmt.Sprintf("{\"size\":%v}", app.state.Size), + Version: version.ABCIVersion, + AppVersion: AppVersion, + LastBlockHeight: app.state.Height, + LastBlockAppHash: app.state.Hash(), + }, nil +} + +// InitChain takes the genesis validators and stores them in the kvstore. It returns the application hash in the +// case that the application starts prepopulated with values. This method is called whenever a new instance of the application +// starts (i.e. app height = 0). +func (app *Application) InitChain(_ context.Context, req *types.RequestInitChain) (*types.ResponseInitChain, error) { + for _, v := range req.Validators { + app.updateValidator(v) + } + appHash := make([]byte, 8) + binary.PutVarint(appHash, app.state.Size) + return &types.ResponseInitChain{ + AppHash: appHash, + }, nil +} + +// CheckTx handles inbound transactions or in the case of recheckTx assesses old transaction validity after a state transition. +// As this is called frequently, it's preferably to keep the check as stateless and as quick as possible. +// Here we check that the transaction has the correctly key=value format. +// For the KVStore we check that each transaction has the valid tx format: +// - Contains one and only one `=` +// - `=` is not the first or last byte. +// - if key is `val` that the validator update transaction is also valid +func (app *Application) CheckTx(_ context.Context, req *types.RequestCheckTx) (*types.ResponseCheckTx, error) { + // If it is a validator update transaction, check that it is correctly formatted + if isValidatorTx(req.Tx) { + if _, _, err := parseValidatorTx(req.Tx); err != nil { + return &types.ResponseCheckTx{Code: CodeTypeInvalidTxFormat}, nil + } + } else if !isValidTx(req.Tx) { + return &types.ResponseCheckTx{Code: CodeTypeInvalidTxFormat}, nil + } + + return &types.ResponseCheckTx{Code: CodeTypeOK, GasWanted: 1}, nil +} + +// Tx must have a format like key:value or key=value. That is: +// - it must have one and only one ":" or "=" +// - It must not begin or end with these special characters +func isValidTx(tx []byte) bool { + if bytes.Count(tx, []byte(":")) == 1 && bytes.Count(tx, []byte("=")) == 0 { + if !bytes.HasPrefix(tx, []byte(":")) && !bytes.HasSuffix(tx, []byte(":")) { + return true + } + } else if bytes.Count(tx, []byte("=")) == 1 && bytes.Count(tx, []byte(":")) == 0 { + if !bytes.HasPrefix(tx, []byte("=")) && !bytes.HasSuffix(tx, []byte("=")) { + return true + } + } + return false +} + +// PrepareProposal is called when the node is a proposer. Tendermint stages a set of transactions to the application. As the +// KVStore has two accepted formats, `:` and `=`, we modify all instances of `:` with `=` to make it consistent. Note: this is +// quite a trivial example of transaction modification. +// NOTE: we assume that Tendermint will never provide more transactions than can fit in a block. +func (app *Application) PrepareProposal(_ context.Context, req *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { + return &types.ResponsePrepareProposal{Txs: formatTxs(req.Txs)}, nil +} + +// formatTxs substitutes all the transactions with x:y to x=y +func formatTxs(blockData [][]byte) [][]byte { + txs := make([][]byte, len(blockData)) + for idx, tx := range blockData { + txs[idx] = bytes.Replace(tx, []byte(":"), []byte("="), 1) + } + return txs +} + +// ProcessProposal is called whenever a node receives a complete proposal. It allows the application to validate the proposal. +// Only validators who can vote will have this method called. For the KVstore we reuse CheckTx. +func (app *Application) ProcessProposal(ctx context.Context, req *types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { + for _, tx := range req.Txs { + // As CheckTx is a full validity check we can simply reuse this + if resp, err := app.CheckTx(ctx, &types.RequestCheckTx{Tx: tx}); resp.Code != CodeTypeOK || err != nil { + return &types.ResponseProcessProposal{Status: types.ResponseProcessProposal_REJECT}, nil + } + } + return &types.ResponseProcessProposal{Status: types.ResponseProcessProposal_ACCEPT}, nil +} + +// FinalizeBlock executes the block against the application state. It punishes validators who equivocated and +// updates validators according to transactions in a block. The rest of the transactions are regular key value +// updates and are cached in memory and will be persisted once Commit is called. +// ConsensusParams are never changed. +func (app *Application) FinalizeBlock(_ context.Context, req *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { + // reset valset changes + app.valUpdates = make([]types.ValidatorUpdate, 0) + app.stagedTxs = make([][]byte, 0) + + // Punish validators who committed equivocation. + for _, ev := range req.Misbehavior { + if ev.Type == types.MisbehaviorType_DUPLICATE_VOTE { + addr := string(ev.Validator.Address) + if pubKey, ok := app.valAddrToPubKeyMap[addr]; ok { + app.valUpdates = append(app.valUpdates, types.ValidatorUpdate{ + PubKey: pubKey, + Power: ev.Validator.Power - 1, + }) + app.logger.Info("Decreased val power by 1 because of the equivocation", + "val", addr) + } else { + panic(fmt.Errorf("wanted to punish val %q but can't find it", addr)) + } + } + } + + respTxs := make([]*types.ExecTxResult, len(req.Txs)) + for i, tx := range req.Txs { + if isValidatorTx(tx) { + pubKey, power, err := parseValidatorTx(tx) + if err != nil { + panic(err) + } + app.valUpdates = append(app.valUpdates, types.UpdateValidator(pubKey, power, "")) + } else { + app.stagedTxs = append(app.stagedTxs, tx) + } + respTxs[i] = &types.ExecTxResult{ + Code: CodeTypeOK, + // With every transaction we can emit a series of events. To make it simple, we just emit the same events. + Events: []types.Event{ + { + Type: "app", + Attributes: []types.EventAttribute{ + {Key: "creator", Value: "Cosmoshi Netowoko", Index: true}, + {Key: "index_key", Value: "index is working", Index: true}, + {Key: "noindex_key", Value: "index is working", Index: false}, + }, + }, + }, + } + app.state.Size++ + } + + app.state.Height = req.Height + + return &types.ResponseFinalizeBlock{TxResults: respTxs, ValidatorUpdates: app.valUpdates, AgreedAppData: app.state.Hash()}, nil +} + +// Commit is called after FinalizeBlock and after Tendermint state which includes the updates to +// AppHash, ConsensusParams and ValidatorSet has occurred. +// The KVStore persists the validator updates and the new key values +func (app *Application) Commit(_ context.Context, _ *types.RequestCommit) (*types.ResponseCommit, error) { + + // apply the validator updates to state (note this is really the validator set at h + 2) + for _, valUpdate := range app.valUpdates { + app.updateValidator(valUpdate) + } + + // persist all the staged txs in the kvstore + for _, tx := range app.stagedTxs { + parts := bytes.Split(tx, []byte("=")) + if len(parts) != 2 { + panic(fmt.Sprintf("unexpected tx format. Expected 2 got %d: %s", len(parts), parts)) + } + key, value := string(parts[0]), string(parts[1]) + err := app.state.db.Set(prefixKey([]byte(key)), []byte(value)) + if err != nil { + panic(err) + } + } + + // persist the state (i.e. size and height) + saveState(app.state) + + resp := &types.ResponseCommit{} + if app.RetainBlocks > 0 && app.state.Height >= app.RetainBlocks { + resp.RetainHeight = app.state.Height - app.RetainBlocks + 1 + } + return resp, nil +} + +// Returns an associated value or nil if missing. +func (app *Application) Query(_ context.Context, reqQuery *types.RequestQuery) (*types.ResponseQuery, error) { + resQuery := &types.ResponseQuery{} + + if reqQuery.Path == "/val" { + key := []byte(ValidatorPrefix + string(reqQuery.Data)) + value, err := app.state.db.Get(key) + if err != nil { + panic(err) + } + + return &types.ResponseQuery{ + Key: reqQuery.Data, + Value: value, + }, nil + } + + if reqQuery.Prove { + value, err := app.state.db.Get(prefixKey(reqQuery.Data)) + if err != nil { + panic(err) + } + + if value == nil { + resQuery.Log = "does not exist" + } else { + resQuery.Log = "exists" + } + resQuery.Index = -1 // TODO make Proof return index + resQuery.Key = reqQuery.Data + resQuery.Value = value + resQuery.Height = app.state.Height + + return resQuery, nil + } + + resQuery.Key = reqQuery.Data + value, err := app.state.db.Get(prefixKey(reqQuery.Data)) + if err != nil { + panic(err) + } + if value == nil { + resQuery.Log = "does not exist" + } else { + resQuery.Log = "exists" + } + resQuery.Value = value + resQuery.Height = app.state.Height + + return resQuery, nil +} + +func (app *Application) Close() error { + return app.state.db.Close() +} + +func isValidatorTx(tx []byte) bool { + return strings.HasPrefix(string(tx), ValidatorPrefix) +} + +func parseValidatorTx(tx []byte) ([]byte, int64, error) { + tx = tx[len(ValidatorPrefix):] + + // get the pubkey and power + pubKeyAndPower := strings.Split(string(tx), "!") + if len(pubKeyAndPower) != 2 { + return nil, 0, fmt.Errorf("expected 'pubkey!power'. Got %v", pubKeyAndPower) + } + pubkeyS, powerS := pubKeyAndPower[0], pubKeyAndPower[1] + + // decode the pubkey + pubkey, err := base64.StdEncoding.DecodeString(pubkeyS) + if err != nil { + return nil, 0, fmt.Errorf("pubkey (%s) is invalid base64", pubkeyS) + } + + // decode the power + power, err := strconv.ParseInt(powerS, 10, 64) + if err != nil { + return nil, 0, fmt.Errorf("power (%s) is not an int", powerS) + } + + if power < 0 { + return nil, 0, fmt.Errorf("power can not be less than 0, got %d", power) + } + + return pubkey, power, nil +} + +// add, update, or remove a validator +func (app *Application) updateValidator(v types.ValidatorUpdate) { + pubkey, err := cryptoencoding.PubKeyFromProto(v.PubKey) + if err != nil { + panic(fmt.Errorf("can't decode public key: %w", err)) + } + key := []byte(ValidatorPrefix + string(pubkey.Bytes())) + + if v.Power == 0 { + // remove validator + hasKey, err := app.state.db.Has(key) + if err != nil { + panic(err) + } + if !hasKey { + pubStr := base64.StdEncoding.EncodeToString(pubkey.Bytes()) + app.logger.Info("tried to remove non existent validator. Skipping...", "pubKey", pubStr) + } + if err = app.state.db.Delete(key); err != nil { + panic(err) + } + delete(app.valAddrToPubKeyMap, string(pubkey.Address())) + } else { + // add or update validator + value := bytes.NewBuffer(make([]byte, 0)) + if err := types.WriteMessage(&v, value); err != nil { + panic(err) + } + if err = app.state.db.Set(key, value.Bytes()); err != nil { + panic(err) + } + app.valAddrToPubKeyMap[string(pubkey.Address())] = v.PubKey + } +} + +func (app *Application) getValidators() (validators []types.ValidatorUpdate) { + itr, err := app.state.db.Iterator(nil, nil) + if err != nil { + panic(err) + } + for ; itr.Valid(); itr.Next() { + if isValidatorTx(itr.Key()) { + validator := new(types.ValidatorUpdate) + err := types.ReadMessage(bytes.NewBuffer(itr.Value()), validator) + if err != nil { + panic(err) + } + validators = append(validators, *validator) + } + } + if err = itr.Error(); err != nil { + panic(err) + } + return +} + +// ----------------------------- + type State struct { - db dbm.DB - Size int64 `json:"size"` - Height int64 `json:"height"` - AppHash []byte `json:"app_hash"` + db dbm.DB + // Size is essentially the amount of transactions that have been processes. + // This is used for the appHash + Size int64 `json:"size"` + Height int64 `json:"height"` } func loadState(db dbm.DB) State { @@ -55,145 +452,17 @@ func saveState(state State) { } } +// Hash returns the hash of the application state. This is computed +// as the size or number of transactions processed within the state. Note that this isn't +// a strong guarantee of state machine replication because states could +// have different kv values but still have the same size. +// This function is used as the "AgreedAppData" +func (s State) Hash() []byte { + appHash := make([]byte, 8) + binary.PutVarint(appHash, s.Size) + return appHash +} + func prefixKey(key []byte) []byte { return append(kvPairPrefixKey, key...) } - -//--------------------------------------------------- - -var _ types.Application = (*Application)(nil) - -type Application struct { - types.BaseApplication - - state State - RetainBlocks int64 // blocks to retain after commit (via ResponseCommit.RetainHeight) - txToRemove map[string]struct{} -} - -func NewApplication() *Application { - state := loadState(dbm.NewMemDB()) - return &Application{state: state} -} - -func (app *Application) Info(req types.RequestInfo) (resInfo types.ResponseInfo) { - return types.ResponseInfo{ - Data: fmt.Sprintf("{\"size\":%v}", app.state.Size), - Version: version.ABCISemVer, - AppVersion: ProtocolVersion, - LastBlockHeight: app.state.Height, - LastBlockAppHash: app.state.AppHash, - } -} - -// tx is either "key=value" or just arbitrary bytes -func (app *Application) DeliverTx(req types.RequestDeliverTx) types.ResponseDeliverTx { - if isReplacedTx(req.Tx) { - app.txToRemove[string(req.Tx)] = struct{}{} - } - var key, value string - - parts := bytes.Split(req.Tx, []byte("=")) - if len(parts) == 2 { - key, value = string(parts[0]), string(parts[1]) - } else { - key, value = string(req.Tx), string(req.Tx) - } - - err := app.state.db.Set(prefixKey([]byte(key)), []byte(value)) - if err != nil { - panic(err) - } - app.state.Size++ - - events := []types.Event{ - { - Type: "app", - Attributes: []types.EventAttribute{ - {Key: "creator", Value: "Cosmoshi Netowoko", Index: true}, - {Key: "key", Value: key, Index: true}, - {Key: "index_key", Value: "index is working", Index: true}, - {Key: "noindex_key", Value: "index is working", Index: false}, - }, - }, - } - - return types.ResponseDeliverTx{Code: code.CodeTypeOK, Events: events} -} - -func (app *Application) CheckTx(req types.RequestCheckTx) types.ResponseCheckTx { - if req.Type == types.CheckTxType_Recheck { - if _, ok := app.txToRemove[string(req.Tx)]; ok { - return types.ResponseCheckTx{Code: code.CodeTypeExecuted, GasWanted: 1} - } - } - return types.ResponseCheckTx{Code: code.CodeTypeOK, GasWanted: 1} -} - -func (app *Application) Commit() types.ResponseCommit { - // Using a memdb - just return the big endian size of the db - appHash := make([]byte, 8) - binary.PutVarint(appHash, app.state.Size) - app.state.AppHash = appHash - app.state.Height++ - - // empty out the set of transactions to remove via rechecktx - saveState(app.state) - - resp := types.ResponseCommit{Data: appHash} - if app.RetainBlocks > 0 && app.state.Height >= app.RetainBlocks { - resp.RetainHeight = app.state.Height - app.RetainBlocks + 1 - } - return resp -} - -// Returns an associated value or nil if missing. -func (app *Application) Query(reqQuery types.RequestQuery) (resQuery types.ResponseQuery) { - if reqQuery.Prove { - value, err := app.state.db.Get(prefixKey(reqQuery.Data)) - if err != nil { - panic(err) - } - if value == nil { - resQuery.Log = "does not exist" - } else { - resQuery.Log = "exists" - } - resQuery.Index = -1 // TODO make Proof return index - resQuery.Key = reqQuery.Data - resQuery.Value = value - resQuery.Height = app.state.Height - - return - } - - resQuery.Key = reqQuery.Data - value, err := app.state.db.Get(prefixKey(reqQuery.Data)) - if err != nil { - panic(err) - } - if value == nil { - resQuery.Log = "does not exist" - } else { - resQuery.Log = "exists" - } - resQuery.Value = value - resQuery.Height = app.state.Height - - return resQuery -} - -func (app *Application) BeginBlock(req types.RequestBeginBlock) types.ResponseBeginBlock { - app.txToRemove = map[string]struct{}{} - return types.ResponseBeginBlock{} -} - -func (app *Application) ProcessProposal( - req types.RequestProcessProposal) types.ResponseProcessProposal { - for _, tx := range req.Txs { - if len(tx) == 0 { - return types.ResponseProcessProposal{Status: types.ResponseProcessProposal_REJECT} - } - } - return types.ResponseProcessProposal{Status: types.ResponseProcessProposal_ACCEPT} -} diff --git a/abci/example/kvstore/kvstore_test.go b/abci/example/kvstore/kvstore_test.go index 5d91f3699..74df9ce42 100644 --- a/abci/example/kvstore/kvstore_test.go +++ b/abci/example/kvstore/kvstore_test.go @@ -1,8 +1,8 @@ package kvstore import ( + "context" "fmt" - "os" "sort" "testing" @@ -12,10 +12,8 @@ import ( "github.com/tendermint/tendermint/libs/service" abcicli "github.com/tendermint/tendermint/abci/client" - "github.com/tendermint/tendermint/abci/example/code" abciserver "github.com/tendermint/tendermint/abci/server" "github.com/tendermint/tendermint/abci/types" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) const ( @@ -23,79 +21,82 @@ const ( testValue = "def" ) -func testKVStore(t *testing.T, app types.Application, tx []byte, key, value string) { - req := types.RequestDeliverTx{Tx: tx} - ar := app.DeliverTx(req) - require.False(t, ar.IsErr(), ar) - // repeating tx doesn't raise error - ar = app.DeliverTx(req) - require.False(t, ar.IsErr(), ar) - // commit - app.Commit() +func TestKVStoreKV(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() - info := app.Info(types.RequestInfo{}) + kvstore := NewInMemoryApplication() + tx := []byte(testKey + ":" + testValue) + testKVStore(ctx, t, kvstore, tx, testKey, testValue) + tx = []byte(testKey + "=" + testValue) + testKVStore(ctx, t, kvstore, tx, testKey, testValue) +} + +func testKVStore(ctx context.Context, t *testing.T, app types.Application, tx []byte, key, value string) { + checkTxResp, err := app.CheckTx(ctx, &types.RequestCheckTx{Tx: tx}) + require.NoError(t, err) + require.Equal(t, uint32(0), checkTxResp.Code) + + ppResp, err := app.PrepareProposal(ctx, &types.RequestPrepareProposal{Txs: [][]byte{tx}}) + require.NoError(t, err) + require.Len(t, ppResp.Txs, 1) + req := &types.RequestFinalizeBlock{Height: 1, Txs: ppResp.Txs} + ar, err := app.FinalizeBlock(ctx, req) + require.NoError(t, err) + require.Equal(t, 1, len(ar.TxResults)) + require.False(t, ar.TxResults[0].IsErr()) + // commit + _, err = app.Commit(ctx, &types.RequestCommit{}) + require.NoError(t, err) + + info, err := app.Info(ctx, &types.RequestInfo{}) + require.NoError(t, err) require.NotZero(t, info.LastBlockHeight) // make sure query is fine - resQuery := app.Query(types.RequestQuery{ + resQuery, err := app.Query(ctx, &types.RequestQuery{ Path: "/store", Data: []byte(key), }) - require.Equal(t, code.CodeTypeOK, resQuery.Code) + require.NoError(t, err) + require.Equal(t, CodeTypeOK, resQuery.Code) require.Equal(t, key, string(resQuery.Key)) require.Equal(t, value, string(resQuery.Value)) require.EqualValues(t, info.LastBlockHeight, resQuery.Height) // make sure proof is fine - resQuery = app.Query(types.RequestQuery{ + resQuery, err = app.Query(ctx, &types.RequestQuery{ Path: "/store", Data: []byte(key), Prove: true, }) - require.EqualValues(t, code.CodeTypeOK, resQuery.Code) + require.NoError(t, err) + require.EqualValues(t, CodeTypeOK, resQuery.Code) require.Equal(t, key, string(resQuery.Key)) require.Equal(t, value, string(resQuery.Value)) require.EqualValues(t, info.LastBlockHeight, resQuery.Height) } -func TestKVStoreKV(t *testing.T) { - kvstore := NewApplication() - key := testKey - value := key - tx := []byte(key) - testKVStore(t, kvstore, tx, key, value) - - value = testValue - tx = []byte(key + "=" + value) - testKVStore(t, kvstore, tx, key, value) -} - func TestPersistentKVStoreKV(t *testing.T) { - dir, err := os.MkdirTemp("/tmp", "abci-kvstore-test") // TODO - if err != nil { - t.Fatal(err) - } - kvstore := NewPersistentKVStoreApplication(dir) - key := testKey - value := key - tx := []byte(key) - testKVStore(t, kvstore, tx, key, value) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() - value = testValue - tx = []byte(key + "=" + value) - testKVStore(t, kvstore, tx, key, value) + kvstore := NewPersistentApplication(t.TempDir()) + key := testKey + value := testValue + testKVStore(ctx, t, kvstore, NewTx(key, value), key, value) } func TestPersistentKVStoreInfo(t *testing.T) { - dir, err := os.MkdirTemp("/tmp", "abci-kvstore-test") // TODO - if err != nil { - t.Fatal(err) - } - kvstore := NewPersistentKVStoreApplication(dir) - InitKVStore(kvstore) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + kvstore := NewPersistentApplication(t.TempDir()) + require.NoError(t, InitKVStore(ctx, kvstore)) height := int64(0) - resInfo := kvstore.Info(types.RequestInfo{}) + resInfo, err := kvstore.Info(ctx, &types.RequestInfo{}) + require.NoError(t, err) if resInfo.LastBlockHeight != height { t.Fatalf("expected height of %d, got %d", height, resInfo.LastBlockHeight) } @@ -103,38 +104,37 @@ func TestPersistentKVStoreInfo(t *testing.T) { // make and apply block height = int64(1) hash := []byte("foo") - header := tmproto.Header{ - Height: height, + if _, err := kvstore.FinalizeBlock(ctx, &types.RequestFinalizeBlock{Hash: hash, Height: height}); err != nil { + t.Fatal(err) } - kvstore.BeginBlock(types.RequestBeginBlock{Hash: hash, Header: header}) - kvstore.EndBlock(types.RequestEndBlock{Height: header.Height}) - kvstore.Commit() - resInfo = kvstore.Info(types.RequestInfo{}) - if resInfo.LastBlockHeight != height { - t.Fatalf("expected height of %d, got %d", height, resInfo.LastBlockHeight) - } + _, err = kvstore.Commit(ctx, &types.RequestCommit{}) + require.NoError(t, err) + + resInfo, err = kvstore.Info(ctx, &types.RequestInfo{}) + require.NoError(t, err) + require.Equal(t, height, resInfo.LastBlockHeight) } // add a validator, remove a validator, update a validator func TestValUpdates(t *testing.T) { - dir, err := os.MkdirTemp("/tmp", "abci-kvstore-test") // TODO - if err != nil { - t.Fatal(err) - } - kvstore := NewPersistentKVStoreApplication(dir) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + kvstore := NewInMemoryApplication() // init with some validators total := 10 nInit := 5 vals := RandVals(total) // initialize with the first nInit - kvstore.InitChain(types.RequestInitChain{ + _, err := kvstore.InitChain(ctx, &types.RequestInitChain{ Validators: vals[:nInit], }) + require.NoError(t, err) - vals1, vals2 := vals[:nInit], kvstore.Validators() + vals1, vals2 := vals[:nInit], kvstore.getValidators() valsEqual(t, vals1, vals2) var v1, v2, v3 types.ValidatorUpdate @@ -145,9 +145,9 @@ func TestValUpdates(t *testing.T) { tx1 := MakeValSetChangeTx(v1.PubKey, v1.Power) tx2 := MakeValSetChangeTx(v2.PubKey, v2.Power) - makeApplyBlock(t, kvstore, 1, diff, tx1, tx2) + makeApplyBlock(ctx, t, kvstore, 1, diff, tx1, tx2) - vals1, vals2 = vals[:nInit+2], kvstore.Validators() + vals1, vals2 = vals[:nInit+2], kvstore.getValidators() valsEqual(t, vals1, vals2) // remove some validators @@ -160,10 +160,10 @@ func TestValUpdates(t *testing.T) { tx2 = MakeValSetChangeTx(v2.PubKey, v2.Power) tx3 := MakeValSetChangeTx(v3.PubKey, v3.Power) - makeApplyBlock(t, kvstore, 2, diff, tx1, tx2, tx3) + makeApplyBlock(ctx, t, kvstore, 2, diff, tx1, tx2, tx3) vals1 = append(vals[:nInit-2], vals[nInit+1]) //nolint: gocritic - vals2 = kvstore.Validators() + vals2 = kvstore.getValidators() valsEqual(t, vals1, vals2) // update some validators @@ -176,15 +176,62 @@ func TestValUpdates(t *testing.T) { diff = []types.ValidatorUpdate{v1} tx1 = MakeValSetChangeTx(v1.PubKey, v1.Power) - makeApplyBlock(t, kvstore, 3, diff, tx1) + makeApplyBlock(ctx, t, kvstore, 3, diff, tx1) vals1 = append([]types.ValidatorUpdate{v1}, vals1[1:]...) - vals2 = kvstore.Validators() + vals2 = kvstore.getValidators() valsEqual(t, vals1, vals2) } +func TestCheckTx(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + kvstore := NewInMemoryApplication() + + val := RandVal(1) + + testCases := []struct { + expCode uint32 + tx []byte + }{ + {CodeTypeOK, NewTx("hello", "world")}, + {CodeTypeInvalidTxFormat, []byte("hello")}, + {CodeTypeOK, []byte("space:jam")}, + {CodeTypeInvalidTxFormat, []byte("=hello")}, + {CodeTypeInvalidTxFormat, []byte("hello=")}, + {CodeTypeOK, []byte("a=b")}, + {CodeTypeInvalidTxFormat, []byte("val=hello")}, + {CodeTypeInvalidTxFormat, []byte("val=hi!5")}, + {CodeTypeOK, MakeValSetChangeTx(val.PubKey, 10)}, + } + + for idx, tc := range testCases { + resp, err := kvstore.CheckTx(ctx, &types.RequestCheckTx{Tx: tc.tx}) + require.NoError(t, err, idx) + fmt.Println(string(tc.tx)) + require.Equal(t, tc.expCode, resp.Code, idx) + } +} + +func TestClientServer(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + // set up socket app + kvstore := NewInMemoryApplication() + client, _, err := makeClientServer(t, kvstore, "kvstore-socket", "socket") + require.NoError(t, err) + runClientTests(ctx, t, client) + + // set up grpc app + kvstore = NewInMemoryApplication() + gclient, _, err := makeClientServer(t, kvstore, t.TempDir(), "grpc") + require.NoError(t, err) + runClientTests(ctx, t, gclient) +} + func makeApplyBlock( + ctx context.Context, t *testing.T, kvstore types.Application, heightInt int, @@ -193,25 +240,23 @@ func makeApplyBlock( // make and apply block height := int64(heightInt) hash := []byte("foo") - header := tmproto.Header{ + resFinalizeBlock, err := kvstore.FinalizeBlock(ctx, &types.RequestFinalizeBlock{ + Hash: hash, Height: height, - } + Txs: txs, + }) + require.NoError(t, err) - kvstore.BeginBlock(types.RequestBeginBlock{Hash: hash, Header: header}) - for _, tx := range txs { - if r := kvstore.DeliverTx(types.RequestDeliverTx{Tx: tx}); r.IsErr() { - t.Fatal(r) - } - } - resEndBlock := kvstore.EndBlock(types.RequestEndBlock{Height: header.Height}) - kvstore.Commit() + _, err = kvstore.Commit(ctx, &types.RequestCommit{}) + require.NoError(t, err) - valsEqual(t, diff, resEndBlock.ValidatorUpdates) + valsEqual(t, diff, resFinalizeBlock.ValidatorUpdates) } // order doesn't matter func valsEqual(t *testing.T, vals1, vals2 []types.ValidatorUpdate) { + t.Helper() if len(vals1) != len(vals2) { t.Fatalf("vals dont match in len. got %d, expected %d", len(vals2), len(vals1)) } @@ -226,138 +271,50 @@ func valsEqual(t *testing.T, vals1, vals2 []types.ValidatorUpdate) { } } -func makeSocketClientServer(app types.Application, name string) (abcicli.Client, service.Service, error) { +func makeClientServer(t *testing.T, app types.Application, name, transport string) (abcicli.Client, service.Service, error) { // Start the listener - socket := fmt.Sprintf("unix://%s.sock", name) + addr := fmt.Sprintf("unix://%s.sock", name) logger := log.TestingLogger() - server := abciserver.NewSocketServer(socket, app) - server.SetLogger(logger.With("module", "abci-server")) - if err := server.Start(); err != nil { - return nil, nil, err - } - - // Connect to the socket - client := abcicli.NewSocketClient(socket, false) - client.SetLogger(logger.With("module", "abci-client")) - if err := client.Start(); err != nil { - if err = server.Stop(); err != nil { - return nil, nil, err - } - return nil, nil, err - } - - return client, server, nil -} - -func makeGRPCClientServer(app types.Application, name string) (abcicli.Client, service.Service, error) { - // Start the listener - socket := fmt.Sprintf("unix://%s.sock", name) - logger := log.TestingLogger() - - gapp := types.NewGRPCApplication(app) - server := abciserver.NewGRPCServer(socket, gapp) - server.SetLogger(logger.With("module", "abci-server")) - if err := server.Start(); err != nil { - return nil, nil, err - } - - client := abcicli.NewGRPCClient(socket, true) - client.SetLogger(logger.With("module", "abci-client")) - if err := client.Start(); err != nil { - if err := server.Stop(); err != nil { - return nil, nil, err - } - return nil, nil, err - } - return client, server, nil -} - -func TestClientServer(t *testing.T) { - // set up socket app - kvstore := NewApplication() - client, server, err := makeSocketClientServer(kvstore, "kvstore-socket") + server, err := abciserver.NewServer(addr, transport, app) require.NoError(t, err) + server.SetLogger(logger.With("module", "abci-server")) + if err := server.Start(); err != nil { + return nil, nil, err + } + t.Cleanup(func() { if err := server.Stop(); err != nil { t.Error(err) } }) + + // Connect to the client + client, err := abcicli.NewClient(addr, transport, false) + require.NoError(t, err) + client.SetLogger(logger.With("module", "abci-client")) + if err := client.Start(); err != nil { + return nil, nil, err + } + t.Cleanup(func() { if err := client.Stop(); err != nil { t.Error(err) } }) - runClientTests(t, client) - - // set up grpc app - kvstore = NewApplication() - gclient, gserver, err := makeGRPCClientServer(kvstore, "/tmp/kvstore-grpc") - require.NoError(t, err) - - t.Cleanup(func() { - if err := gserver.Stop(); err != nil { - t.Error(err) - } - }) - t.Cleanup(func() { - if err := gclient.Stop(); err != nil { - t.Error(err) - } - }) - - runClientTests(t, gclient) + return client, server, nil } -func runClientTests(t *testing.T, client abcicli.Client) { +func runClientTests(ctx context.Context, t *testing.T, client abcicli.Client) { // run some tests.... - key := testKey - value := key - tx := []byte(key) - testClient(t, client, tx, key, value) - - value = testValue - tx = []byte(key + "=" + value) - testClient(t, client, tx, key, value) + tx := []byte(testKey + ":" + testValue) + testKVStore(ctx, t, client, tx, testKey, testValue) + tx = []byte(testKey + "=" + testValue) + testKVStore(ctx, t, client, tx, testKey, testValue) } -func testClient(t *testing.T, app abcicli.Client, tx []byte, key, value string) { - ar, err := app.DeliverTxSync(types.RequestDeliverTx{Tx: tx}) - require.NoError(t, err) - require.False(t, ar.IsErr(), ar) - // repeating tx doesn't raise error - ar, err = app.DeliverTxSync(types.RequestDeliverTx{Tx: tx}) - require.NoError(t, err) - require.False(t, ar.IsErr(), ar) - // commit - _, err = app.CommitSync() - require.NoError(t, err) - - info, err := app.InfoSync(types.RequestInfo{}) - require.NoError(t, err) - require.NotZero(t, info.LastBlockHeight) - - // make sure query is fine - resQuery, err := app.QuerySync(types.RequestQuery{ - Path: "/store", - Data: []byte(key), - }) - require.Nil(t, err) - require.Equal(t, code.CodeTypeOK, resQuery.Code) - require.Equal(t, key, string(resQuery.Key)) - require.Equal(t, value, string(resQuery.Value)) - require.EqualValues(t, info.LastBlockHeight, resQuery.Height) - - // make sure proof is fine - resQuery, err = app.QuerySync(types.RequestQuery{ - Path: "/store", - Data: []byte(key), - Prove: true, - }) - require.Nil(t, err) - require.Equal(t, code.CodeTypeOK, resQuery.Code) - require.Equal(t, key, string(resQuery.Key)) - require.Equal(t, value, string(resQuery.Value)) - require.EqualValues(t, info.LastBlockHeight, resQuery.Height) +func TestTxGeneration(t *testing.T) { + require.Len(t, NewRandomTx(20), 20) + require.Len(t, NewRandomTxs(10), 10) } diff --git a/abci/example/kvstore/persistent_kvstore.go b/abci/example/kvstore/persistent_kvstore.go deleted file mode 100644 index 500d4c5c9..000000000 --- a/abci/example/kvstore/persistent_kvstore.go +++ /dev/null @@ -1,343 +0,0 @@ -package kvstore - -import ( - "bytes" - "encoding/base64" - "fmt" - "strconv" - "strings" - - dbm "github.com/tendermint/tm-db" - - "github.com/tendermint/tendermint/abci/example/code" - "github.com/tendermint/tendermint/abci/types" - cryptoenc "github.com/tendermint/tendermint/crypto/encoding" - "github.com/tendermint/tendermint/libs/log" - pc "github.com/tendermint/tendermint/proto/tendermint/crypto" -) - -const ( - ValidatorSetChangePrefix string = "val:" -) - -//----------------------------------------- - -var _ types.Application = (*PersistentKVStoreApplication)(nil) - -type PersistentKVStoreApplication struct { - app *Application - - // validator set - ValUpdates []types.ValidatorUpdate - - valAddrToPubKeyMap map[string]pc.PublicKey - - logger log.Logger -} - -func NewPersistentKVStoreApplication(dbDir string) *PersistentKVStoreApplication { - name := "kvstore" - db, err := dbm.NewGoLevelDB(name, dbDir) - if err != nil { - panic(err) - } - - state := loadState(db) - - return &PersistentKVStoreApplication{ - app: &Application{ - state: state, - txToRemove: map[string]struct{}{}, - }, - valAddrToPubKeyMap: make(map[string]pc.PublicKey), - logger: log.NewNopLogger(), - } -} - -func (app *PersistentKVStoreApplication) SetLogger(l log.Logger) { - app.logger = l -} - -func (app *PersistentKVStoreApplication) Info(req types.RequestInfo) types.ResponseInfo { - res := app.app.Info(req) - res.LastBlockHeight = app.app.state.Height - res.LastBlockAppHash = app.app.state.AppHash - return res -} - -// tx is either "val:pubkey!power" or "key=value" or just arbitrary bytes -func (app *PersistentKVStoreApplication) DeliverTx(req types.RequestDeliverTx) types.ResponseDeliverTx { - // if it starts with "val:", update the validator set - // format is "val:pubkey!power" - if isValidatorTx(req.Tx) { - // update validators in the merkle tree - // and in app.ValUpdates - return app.execValidatorTx(req.Tx) - } - - if isPrepareTx(req.Tx) { - return app.execPrepareTx(req.Tx) - } - - // otherwise, update the key-value store - return app.app.DeliverTx(req) -} - -func (app *PersistentKVStoreApplication) CheckTx(req types.RequestCheckTx) types.ResponseCheckTx { - return app.app.CheckTx(req) -} - -// Commit will panic if InitChain was not called -func (app *PersistentKVStoreApplication) Commit() types.ResponseCommit { - return app.app.Commit() -} - -// When path=/val and data={validator address}, returns the validator update (types.ValidatorUpdate) varint encoded. -// For any other path, returns an associated value or nil if missing. -func (app *PersistentKVStoreApplication) Query(reqQuery types.RequestQuery) (resQuery types.ResponseQuery) { - switch reqQuery.Path { - case "/val": - key := []byte("val:" + string(reqQuery.Data)) - value, err := app.app.state.db.Get(key) - if err != nil { - panic(err) - } - - resQuery.Key = reqQuery.Data - resQuery.Value = value - return - default: - return app.app.Query(reqQuery) - } -} - -// Save the validators in the merkle tree -func (app *PersistentKVStoreApplication) InitChain(req types.RequestInitChain) types.ResponseInitChain { - for _, v := range req.Validators { - r := app.updateValidator(v) - if r.IsErr() { - app.logger.Error("Error updating validators", "r", r) - } - } - return types.ResponseInitChain{} -} - -// Track the block hash and header information -func (app *PersistentKVStoreApplication) BeginBlock(req types.RequestBeginBlock) types.ResponseBeginBlock { - // reset valset changes - app.ValUpdates = make([]types.ValidatorUpdate, 0) - - // Punish validators who committed equivocation. - for _, ev := range req.ByzantineValidators { - if ev.Type == types.MisbehaviorType_DUPLICATE_VOTE { - addr := string(ev.Validator.Address) - if pubKey, ok := app.valAddrToPubKeyMap[addr]; ok { - app.updateValidator(types.ValidatorUpdate{ - PubKey: pubKey, - Power: ev.Validator.Power - 1, - }) - app.logger.Info("Decreased val power by 1 because of the equivocation", - "val", addr) - } else { - app.logger.Error("Wanted to punish val, but can't find it", - "val", addr) - } - } - } - - return app.app.BeginBlock(req) -} - -// Update the validator set -func (app *PersistentKVStoreApplication) EndBlock(req types.RequestEndBlock) types.ResponseEndBlock { - return types.ResponseEndBlock{ValidatorUpdates: app.ValUpdates} -} - -func (app *PersistentKVStoreApplication) ListSnapshots( - req types.RequestListSnapshots) types.ResponseListSnapshots { - return types.ResponseListSnapshots{} -} - -func (app *PersistentKVStoreApplication) LoadSnapshotChunk( - req types.RequestLoadSnapshotChunk) types.ResponseLoadSnapshotChunk { - return types.ResponseLoadSnapshotChunk{} -} - -func (app *PersistentKVStoreApplication) OfferSnapshot( - req types.RequestOfferSnapshot) types.ResponseOfferSnapshot { - return types.ResponseOfferSnapshot{Result: types.ResponseOfferSnapshot_ABORT} -} - -func (app *PersistentKVStoreApplication) ApplySnapshotChunk( - req types.RequestApplySnapshotChunk) types.ResponseApplySnapshotChunk { - return types.ResponseApplySnapshotChunk{Result: types.ResponseApplySnapshotChunk_ABORT} -} - -func (app *PersistentKVStoreApplication) PrepareProposal( - req types.RequestPrepareProposal) types.ResponsePrepareProposal { - return types.ResponsePrepareProposal{Txs: app.substPrepareTx(req.Txs, req.MaxTxBytes)} -} - -func (app *PersistentKVStoreApplication) ProcessProposal( - req types.RequestProcessProposal) types.ResponseProcessProposal { - for _, tx := range req.Txs { - if len(tx) == 0 || isPrepareTx(tx) { - return types.ResponseProcessProposal{Status: types.ResponseProcessProposal_REJECT} - } - } - return types.ResponseProcessProposal{Status: types.ResponseProcessProposal_ACCEPT} -} - -//--------------------------------------------- -// update validators - -func (app *PersistentKVStoreApplication) Validators() (validators []types.ValidatorUpdate) { - itr, err := app.app.state.db.Iterator(nil, nil) - if err != nil { - panic(err) - } - for ; itr.Valid(); itr.Next() { - if isValidatorTx(itr.Key()) { - validator := new(types.ValidatorUpdate) - err := types.ReadMessage(bytes.NewBuffer(itr.Value()), validator) - if err != nil { - panic(err) - } - validators = append(validators, *validator) - } - } - if err = itr.Error(); err != nil { - panic(err) - } - return -} - -func MakeValSetChangeTx(pubkey pc.PublicKey, power int64) []byte { - pk, err := cryptoenc.PubKeyFromProto(pubkey) - if err != nil { - panic(err) - } - pubStr := base64.StdEncoding.EncodeToString(pk.Bytes()) - return []byte(fmt.Sprintf("val:%s!%d", pubStr, power)) -} - -func isValidatorTx(tx []byte) bool { - return strings.HasPrefix(string(tx), ValidatorSetChangePrefix) -} - -// format is "val:pubkey!power" -// pubkey is a base64-encoded 32-byte ed25519 key -func (app *PersistentKVStoreApplication) execValidatorTx(tx []byte) types.ResponseDeliverTx { - tx = tx[len(ValidatorSetChangePrefix):] - - // get the pubkey and power - pubKeyAndPower := strings.Split(string(tx), "!") - if len(pubKeyAndPower) != 2 { - return types.ResponseDeliverTx{ - Code: code.CodeTypeEncodingError, - Log: fmt.Sprintf("Expected 'pubkey!power'. Got %v", pubKeyAndPower)} - } - pubkeyS, powerS := pubKeyAndPower[0], pubKeyAndPower[1] - - // decode the pubkey - pubkey, err := base64.StdEncoding.DecodeString(pubkeyS) - if err != nil { - return types.ResponseDeliverTx{ - Code: code.CodeTypeEncodingError, - Log: fmt.Sprintf("Pubkey (%s) is invalid base64", pubkeyS)} - } - - // decode the power - power, err := strconv.ParseInt(powerS, 10, 64) - if err != nil { - return types.ResponseDeliverTx{ - Code: code.CodeTypeEncodingError, - Log: fmt.Sprintf("Power (%s) is not an int", powerS)} - } - - // update - return app.updateValidator(types.UpdateValidator(pubkey, power, "")) -} - -// add, update, or remove a validator -func (app *PersistentKVStoreApplication) updateValidator(v types.ValidatorUpdate) types.ResponseDeliverTx { - pubkey, err := cryptoenc.PubKeyFromProto(v.PubKey) - if err != nil { - panic(fmt.Errorf("can't decode public key: %w", err)) - } - key := []byte("val:" + string(pubkey.Bytes())) - - if v.Power == 0 { - // remove validator - hasKey, err := app.app.state.db.Has(key) - if err != nil { - panic(err) - } - if !hasKey { - pubStr := base64.StdEncoding.EncodeToString(pubkey.Bytes()) - return types.ResponseDeliverTx{ - Code: code.CodeTypeUnauthorized, - Log: fmt.Sprintf("Cannot remove non-existent validator %s", pubStr)} - } - if err = app.app.state.db.Delete(key); err != nil { - panic(err) - } - delete(app.valAddrToPubKeyMap, string(pubkey.Address())) - } else { - // add or update validator - value := bytes.NewBuffer(make([]byte, 0)) - if err := types.WriteMessage(&v, value); err != nil { - return types.ResponseDeliverTx{ - Code: code.CodeTypeEncodingError, - Log: fmt.Sprintf("Error encoding validator: %v", err)} - } - if err = app.app.state.db.Set(key, value.Bytes()); err != nil { - panic(err) - } - app.valAddrToPubKeyMap[string(pubkey.Address())] = v.PubKey - } - - // we only update the changes array if we successfully updated the tree - app.ValUpdates = append(app.ValUpdates, v) - - return types.ResponseDeliverTx{Code: code.CodeTypeOK} -} - -// ----------------------------- - -const ( - PreparePrefix = "prepare" - ReplacePrefix = "replace" -) - -func isPrepareTx(tx []byte) bool { return bytes.HasPrefix(tx, []byte(PreparePrefix)) } - -func isReplacedTx(tx []byte) bool { - return bytes.HasPrefix(tx, []byte(ReplacePrefix)) -} - -// execPrepareTx is noop. tx data is considered as placeholder -// and is substitute at the PrepareProposal. -func (app *PersistentKVStoreApplication) execPrepareTx(tx []byte) types.ResponseDeliverTx { - // noop - return types.ResponseDeliverTx{} -} - -// substPrepareTx substitutes all the transactions prefixed with 'prepare' in the -// proposal for transactions with the prefix stripped. -func (app *PersistentKVStoreApplication) substPrepareTx(blockData [][]byte, maxTxBytes int64) [][]byte { - txs := make([][]byte, 0, len(blockData)) - var totalBytes int64 - for _, tx := range blockData { - txMod := tx - if isPrepareTx(tx) { - txMod = bytes.Replace(tx, []byte(PreparePrefix), []byte(ReplacePrefix), 1) - } - totalBytes += int64(len(txMod)) - if totalBytes > maxTxBytes { - break - } - txs = append(txs, txMod) - } - return txs -} diff --git a/abci/server/grpc_server.go b/abci/server/grpc_server.go index 503f0b64f..086f8fe78 100644 --- a/abci/server/grpc_server.go +++ b/abci/server/grpc_server.go @@ -1,6 +1,7 @@ package server import ( + "context" "net" "google.golang.org/grpc" @@ -18,11 +19,11 @@ type GRPCServer struct { listener net.Listener server *grpc.Server - app types.ABCIApplicationServer + app types.Application } // NewGRPCServer returns a new gRPC ABCI server -func NewGRPCServer(protoAddr string, app types.ABCIApplicationServer) service.Service { +func NewGRPCServer(protoAddr string, app types.Application) service.Service { proto, addr := tmnet.ProtocolAndAddress(protoAddr) s := &GRPCServer{ proto: proto, @@ -44,7 +45,7 @@ func (s *GRPCServer) OnStart() error { s.listener = ln s.server = grpc.NewServer() - types.RegisterABCIApplicationServer(s.server, s.app) + types.RegisterABCIServer(s.server, &gRPCApplication{s.app}) s.Logger.Info("Listening", "proto", s.proto, "addr", s.addr) go func() { @@ -59,3 +60,18 @@ func (s *GRPCServer) OnStart() error { func (s *GRPCServer) OnStop() { s.server.Stop() } + +//------------------------------------------------------- + +// gRPCApplication is a gRPC shim for Application +type gRPCApplication struct { + types.Application +} + +func (app *gRPCApplication) Echo(_ context.Context, req *types.RequestEcho) (*types.ResponseEcho, error) { + return &types.ResponseEcho{Message: req.Message}, nil +} + +func (app *gRPCApplication) Flush(_ context.Context, req *types.RequestFlush) (*types.ResponseFlush, error) { + return &types.ResponseFlush{}, nil +} diff --git a/abci/server/server.go b/abci/server/server.go index 4b70545b2..b6715d9d1 100644 --- a/abci/server/server.go +++ b/abci/server/server.go @@ -14,6 +14,8 @@ import ( "github.com/tendermint/tendermint/libs/service" ) +// NewServer is a utility function for out of process applications to set up either a socket or +// grpc server that can listen to requests from the equivalent Tendermint client func NewServer(protoAddr, transport string, app types.Application) (service.Service, error) { var s service.Service var err error @@ -21,7 +23,7 @@ func NewServer(protoAddr, transport string, app types.Application) (service.Serv case "socket": s = NewSocketServer(protoAddr, app) case "grpc": - s = NewGRPCServer(protoAddr, types.NewGRPCApplication(app)) + s = NewGRPCServer(protoAddr, app) default: err = fmt.Errorf("unknown server type %s", transport) } diff --git a/abci/server/socket_server.go b/abci/server/socket_server.go index 5da8bf5ba..1053e0d7f 100644 --- a/abci/server/socket_server.go +++ b/abci/server/socket_server.go @@ -2,6 +2,8 @@ package server import ( "bufio" + "context" + "errors" "fmt" "io" "net" @@ -15,8 +17,11 @@ import ( tmsync "github.com/tendermint/tendermint/libs/sync" ) -// var maxNumberConnections = 2 - +// SocketServer is the server-side implementation of the TSP (Tendermint Socket Protocol) +// for out-of-process go applications. Note, in the case of an application written in golang, +// the developer may also run both Tendermint and the application within the same process. +// +// The socket server deliver type SocketServer struct { service.BaseService isLoggerSet bool @@ -33,6 +38,9 @@ type SocketServer struct { app types.Application } +const responseBufferSize = 1000 + +// NewSocketServer creates a server from a golang-based out-of-process application. func NewSocketServer(protoAddr string, app types.Application) service.Service { proto, addr := tmnet.ProtocolAndAddress(protoAddr) s := &SocketServer{ @@ -120,8 +128,8 @@ func (s *SocketServer) acceptConnectionsRoutine() { connID := s.addConn(conn) - closeConn := make(chan error, 2) // Push to signal connection closed - responses := make(chan *types.Response, 1000) // A channel to buffer responses + closeConn := make(chan error, 2) // Push to signal connection closed + responses := make(chan *types.Response, responseBufferSize) // A channel to buffer responses // Read requests from conn and deal with them go s.handleRequests(closeConn, conn, responses) @@ -157,7 +165,9 @@ func (s *SocketServer) handleRequests(closeConn chan error, conn io.Reader, resp var bufReader = bufio.NewReader(conn) defer func() { - // make sure to recover from any app-related panics to allow proper socket cleanup + // make sure to recover from any app-related panics to allow proper socket cleanup. + // In the case of a panic, we do not notify the client by passing an exception so + // presume that the client is still running and retying to connect r := recover() if r != nil { const size = 64 << 10 @@ -186,61 +196,100 @@ func (s *SocketServer) handleRequests(closeConn chan error, conn io.Reader, resp } s.appMtx.Lock() count++ - s.handleRequest(req, responses) + resp, err := s.handleRequest(context.TODO(), req) + if err != nil { + // any error either from the application or because of an unknown request + // throws an exception back to the client. This will stop the server and + // should also halt the client. + responses <- types.ToResponseException(err.Error()) + } else { + responses <- resp + } s.appMtx.Unlock() } } -func (s *SocketServer) handleRequest(req *types.Request, responses chan<- *types.Response) { +// handleRequests takes a request and calls the application passing the returned +func (s *SocketServer) handleRequest(ctx context.Context, req *types.Request) (*types.Response, error) { switch r := req.Value.(type) { case *types.Request_Echo: - responses <- types.ToResponseEcho(r.Echo.Message) + return types.ToResponseEcho(r.Echo.Message), nil case *types.Request_Flush: - responses <- types.ToResponseFlush() + return types.ToResponseFlush(), nil case *types.Request_Info: - res := s.app.Info(*r.Info) - responses <- types.ToResponseInfo(res) - case *types.Request_DeliverTx: - res := s.app.DeliverTx(*r.DeliverTx) - responses <- types.ToResponseDeliverTx(res) + res, err := s.app.Info(ctx, r.Info) + if err != nil { + return nil, err + } + return types.ToResponseInfo(res), nil case *types.Request_CheckTx: - res := s.app.CheckTx(*r.CheckTx) - responses <- types.ToResponseCheckTx(res) + res, err := s.app.CheckTx(ctx, r.CheckTx) + if err != nil { + return nil, err + } + return types.ToResponseCheckTx(res), nil case *types.Request_Commit: - res := s.app.Commit() - responses <- types.ToResponseCommit(res) + res, err := s.app.Commit(ctx, r.Commit) + if err != nil { + return nil, err + } + return types.ToResponseCommit(res), nil case *types.Request_Query: - res := s.app.Query(*r.Query) - responses <- types.ToResponseQuery(res) + res, err := s.app.Query(ctx, r.Query) + if err != nil { + return nil, err + } + return types.ToResponseQuery(res), nil case *types.Request_InitChain: - res := s.app.InitChain(*r.InitChain) - responses <- types.ToResponseInitChain(res) - case *types.Request_BeginBlock: - res := s.app.BeginBlock(*r.BeginBlock) - responses <- types.ToResponseBeginBlock(res) - case *types.Request_EndBlock: - res := s.app.EndBlock(*r.EndBlock) - responses <- types.ToResponseEndBlock(res) + res, err := s.app.InitChain(ctx, r.InitChain) + if err != nil { + return nil, err + } + return types.ToResponseInitChain(res), nil + case *types.Request_FinalizeBlock: + res, err := s.app.FinalizeBlock(ctx, r.FinalizeBlock) + if err != nil { + return nil, err + } + return types.ToResponseFinalizeBlock(res), nil case *types.Request_ListSnapshots: - res := s.app.ListSnapshots(*r.ListSnapshots) - responses <- types.ToResponseListSnapshots(res) + res, err := s.app.ListSnapshots(ctx, r.ListSnapshots) + if err != nil { + return nil, err + } + return types.ToResponseListSnapshots(res), nil case *types.Request_OfferSnapshot: - res := s.app.OfferSnapshot(*r.OfferSnapshot) - responses <- types.ToResponseOfferSnapshot(res) + res, err := s.app.OfferSnapshot(ctx, r.OfferSnapshot) + if err != nil { + return nil, err + } + return types.ToResponseOfferSnapshot(res), nil case *types.Request_PrepareProposal: - res := s.app.PrepareProposal(*r.PrepareProposal) - responses <- types.ToResponsePrepareProposal(res) + res, err := s.app.PrepareProposal(ctx, r.PrepareProposal) + if err != nil { + return nil, err + } + return types.ToResponsePrepareProposal(res), nil case *types.Request_ProcessProposal: - res := s.app.ProcessProposal(*r.ProcessProposal) - responses <- types.ToResponseProcessProposal(res) + res, err := s.app.ProcessProposal(ctx, r.ProcessProposal) + if err != nil { + return nil, err + } + return types.ToResponseProcessProposal(res), nil case *types.Request_LoadSnapshotChunk: - res := s.app.LoadSnapshotChunk(*r.LoadSnapshotChunk) - responses <- types.ToResponseLoadSnapshotChunk(res) + res, err := s.app.LoadSnapshotChunk(ctx, r.LoadSnapshotChunk) + if err != nil { + return nil, err + } + return types.ToResponseLoadSnapshotChunk(res), nil case *types.Request_ApplySnapshotChunk: - res := s.app.ApplySnapshotChunk(*r.ApplySnapshotChunk) - responses <- types.ToResponseApplySnapshotChunk(res) + res, err := s.app.ApplySnapshotChunk(ctx, r.ApplySnapshotChunk) + if err != nil { + return nil, err + } + return types.ToResponseApplySnapshotChunk(res), nil default: - responses <- types.ToResponseException("Unknown request") + return nil, fmt.Errorf("unknown request from client: %T", req) } } @@ -262,6 +311,13 @@ func (s *SocketServer) handleResponses(closeConn chan error, conn io.Writer, res return } } + + // If the application has responded with an exception, the server returns the error + // back to the client and closes the connection. The receiving Tendermint client should + // log the error and gracefully terminate + if e, ok := res.Value.(*types.Response_Exception); ok { + closeConn <- errors.New(e.Exception.Error) + } count++ } } diff --git a/abci/tests/client_server_test.go b/abci/tests/client_server_test.go index e975f47f5..4d654c6d0 100644 --- a/abci/tests/client_server_test.go +++ b/abci/tests/client_server_test.go @@ -11,20 +11,29 @@ import ( ) func TestClientServerNoAddrPrefix(t *testing.T) { + t.Helper() + addr := "localhost:26658" transport := "socket" - app := kvstore.NewApplication() + app := kvstore.NewInMemoryApplication() server, err := abciserver.NewServer(addr, transport, app) assert.NoError(t, err, "expected no error on NewServer") err = server.Start() assert.NoError(t, err, "expected no error on server.Start") - defer func() { _ = server.Stop() }() + t.Cleanup(func() { + if err := server.Stop(); err != nil { + t.Error(err) + } + }) client, err := abciclient.NewClient(addr, transport, true) assert.NoError(t, err, "expected no error on NewClient") err = client.Start() assert.NoError(t, err, "expected no error on client.Start") - - _ = client.Stop() + t.Cleanup(func() { + if err := client.Stop(); err != nil { + t.Error(err) + } + }) } diff --git a/abci/tests/server/client.go b/abci/tests/server/client.go index 76d315216..bc4687b4e 100644 --- a/abci/tests/server/client.go +++ b/abci/tests/server/client.go @@ -2,6 +2,7 @@ package testsuite import ( "bytes" + "context" "errors" "fmt" @@ -10,7 +11,7 @@ import ( tmrand "github.com/tendermint/tendermint/libs/rand" ) -func InitChain(client abcicli.Client) error { +func InitChain(ctx context.Context, client abcicli.Client) error { total := 10 vals := make([]types.ValidatorUpdate, total) for i := 0; i < total; i++ { @@ -18,7 +19,7 @@ func InitChain(client abcicli.Client) error { power := tmrand.Int() vals[i] = types.UpdateValidator(pubkey, int64(power), "") } - _, err := client.InitChainSync(types.RequestInitChain{ + _, err := client.InitChain(ctx, &types.RequestInitChain{ Validators: vals, }) if err != nil { @@ -29,44 +30,46 @@ func InitChain(client abcicli.Client) error { return nil } -func Commit(client abcicli.Client, hashExp []byte) error { - res, err := client.CommitSync() - data := res.Data +func Commit(ctx context.Context, client abcicli.Client) error { + _, err := client.Commit(ctx, &types.RequestCommit{}) if err != nil { fmt.Println("Failed test: Commit") fmt.Printf("error while committing: %v\n", err) return err } - if !bytes.Equal(data, hashExp) { - fmt.Println("Failed test: Commit") - fmt.Printf("Commit hash was unexpected. Got %X expected %X\n", data, hashExp) - return errors.New("commitTx failed") - } fmt.Println("Passed test: Commit") return nil } -func DeliverTx(client abcicli.Client, txBytes []byte, codeExp uint32, dataExp []byte) error { - res, _ := client.DeliverTxSync(types.RequestDeliverTx{Tx: txBytes}) - code, data, log := res.Code, res.Data, res.Log - if code != codeExp { - fmt.Println("Failed test: DeliverTx") - fmt.Printf("DeliverTx response code was unexpected. Got %v expected %v. Log: %v\n", - code, codeExp, log) - return errors.New("deliverTx error") +func FinalizeBlock(ctx context.Context, client abcicli.Client, txBytes [][]byte, codeExp []uint32, dataExp []byte, hashExp []byte) error { + res, _ := client.FinalizeBlock(ctx, &types.RequestFinalizeBlock{Txs: txBytes}) + appHash := res.AgreedAppData + for i, tx := range res.TxResults { + code, data, log := tx.Code, tx.Data, tx.Log + if code != codeExp[i] { + fmt.Println("Failed test: FinalizeBlock") + fmt.Printf("FinalizeBlock response code was unexpected. Got %v expected %v. Log: %v\n", + code, codeExp, log) + return errors.New("FinalizeBlock error") + } + if !bytes.Equal(data, dataExp) { + fmt.Println("Failed test: FinalizeBlock") + fmt.Printf("FinalizeBlock response data was unexpected. Got %X expected %X\n", + data, dataExp) + return errors.New("FinalizeBlock error") + } } - if !bytes.Equal(data, dataExp) { - fmt.Println("Failed test: DeliverTx") - fmt.Printf("DeliverTx response data was unexpected. Got %X expected %X\n", - data, dataExp) - return errors.New("deliverTx error") + if !bytes.Equal(appHash, hashExp) { + fmt.Println("Failed test: FinalizeBlock") + fmt.Printf("Application hash was unexpected. Got %X expected %X\n", appHash, hashExp) + return errors.New("FinalizeBlock error") } - fmt.Println("Passed test: DeliverTx") + fmt.Println("Passed test: FinalizeBlock") return nil } -func PrepareProposal(client abcicli.Client, txBytes [][]byte, txExpected [][]byte, dataExp []byte) error { - res, _ := client.PrepareProposalSync(types.RequestPrepareProposal{Txs: txBytes}) +func PrepareProposal(ctx context.Context, client abcicli.Client, txBytes [][]byte, txExpected [][]byte, dataExp []byte) error { + res, _ := client.PrepareProposal(ctx, &types.RequestPrepareProposal{Txs: txBytes}) for i, tx := range res.Txs { if !bytes.Equal(tx, txExpected[i]) { fmt.Println("Failed test: PrepareProposal") @@ -79,8 +82,8 @@ func PrepareProposal(client abcicli.Client, txBytes [][]byte, txExpected [][]byt return nil } -func ProcessProposal(client abcicli.Client, txBytes [][]byte, statusExp types.ResponseProcessProposal_ProposalStatus) error { - res, _ := client.ProcessProposalSync(types.RequestProcessProposal{Txs: txBytes}) +func ProcessProposal(ctx context.Context, client abcicli.Client, txBytes [][]byte, statusExp types.ResponseProcessProposal_ProposalStatus) error { + res, _ := client.ProcessProposal(ctx, &types.RequestProcessProposal{Txs: txBytes}) if res.Status != statusExp { fmt.Println("Failed test: ProcessProposal") fmt.Printf("ProcessProposal response status was unexpected. Got %v expected %v.", @@ -91,8 +94,8 @@ func ProcessProposal(client abcicli.Client, txBytes [][]byte, statusExp types.Re return nil } -func CheckTx(client abcicli.Client, txBytes []byte, codeExp uint32, dataExp []byte) error { - res, _ := client.CheckTxSync(types.RequestCheckTx{Tx: txBytes}) +func CheckTx(ctx context.Context, client abcicli.Client, txBytes []byte, codeExp uint32, dataExp []byte) error { + 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/abci/tests/test_cli/ex1.abci b/abci/tests/test_cli/ex1.abci index e772593cc..4faa8057f 100644 --- a/abci/tests/test_cli/ex1.abci +++ b/abci/tests/test_cli/ex1.abci @@ -1,18 +1,12 @@ echo hello info -prepare_proposal "abc" -process_proposal "abc" +prepare_proposal "abc=123" +process_proposal "abc=123" +finalize_block "abc=123" commit -deliver_tx "abc" info -commit query "abc" -deliver_tx "def=xyz" +finalize_block "def=xyz" "ghi=123" commit query "def" -prepare_proposal "preparedef" -process_proposal "replacedef" -process_proposal "preparedef" -prepare_proposal -process_proposal -commit + diff --git a/abci/tests/test_cli/ex1.abci.out b/abci/tests/test_cli/ex1.abci.out index dbc818855..f26b63856 100644 --- a/abci/tests/test_cli/ex1.abci.out +++ b/abci/tests/test_cli/ex1.abci.out @@ -8,19 +8,20 @@ -> data: {"size":0} -> data.hex: 0x7B2273697A65223A307D -> prepare_proposal "abc" +> prepare_proposal "abc=123" -> code: OK --> log: Succeeded. Tx: abc +-> log: Succeeded. Tx: abc=123 -> process_proposal "abc" +> process_proposal "abc=123" -> code: OK -> status: ACCEPT -> commit +> finalize_block "abc=123" -> code: OK --> data.hex: 0x0000000000000000 +-> code: OK +-> data.hex: 0x0200000000000000 -> deliver_tx "abc" +> commit -> code: OK > info @@ -28,54 +29,30 @@ -> data: {"size":1} -> data.hex: 0x7B2273697A65223A317D -> commit --> code: OK --> data.hex: 0x0200000000000000 - > query "abc" -> code: OK -> log: exists --> height: 2 +-> height: 0 -> key: abc -> key.hex: 616263 --> value: abc --> value.hex: 616263 +-> value: 123 +-> value.hex: 313233 -> deliver_tx "def=xyz" +> finalize_block "def=xyz" "ghi=123" -> code: OK +-> code: OK +-> code: OK +-> data.hex: 0x0600000000000000 > commit -> code: OK --> data.hex: 0x0400000000000000 > query "def" -> code: OK -> log: exists --> height: 3 +-> height: 0 -> key: def -> key.hex: 646566 -> value: xyz -> value.hex: 78797A -> prepare_proposal "preparedef" --> code: OK --> log: Succeeded. Tx: replacedef - -> process_proposal "replacedef" --> code: OK --> status: ACCEPT - -> process_proposal "preparedef" --> code: OK --> status: REJECT - -> prepare_proposal - -> process_proposal --> code: OK --> status: ACCEPT - -> commit --> code: OK --> data.hex: 0x0400000000000000 - diff --git a/abci/tests/test_cli/ex2.abci b/abci/tests/test_cli/ex2.abci index 965ca842c..275f73bea 100644 --- a/abci/tests/test_cli/ex2.abci +++ b/abci/tests/test_cli/ex2.abci @@ -1,7 +1,9 @@ -check_tx 0x00 -check_tx 0xff -deliver_tx 0x00 -check_tx 0x00 -deliver_tx 0x01 -deliver_tx 0x04 +check_tx "abc" +check_tx "def=567" +finalize_block "def=567" +commit +finalize_block "hello=world" +commit +finalize_block "first=second" +commit info diff --git a/abci/tests/test_cli/ex2.abci.out b/abci/tests/test_cli/ex2.abci.out index a2f03ed6c..ea24ce920 100644 --- a/abci/tests/test_cli/ex2.abci.out +++ b/abci/tests/test_cli/ex2.abci.out @@ -1,19 +1,31 @@ -> check_tx 0x00 +> check_tx "abc" +-> code: 2 + +> check_tx "def=567" -> code: OK -> check_tx 0xff +> finalize_block "def=567" +-> code: OK +-> code: OK +-> data.hex: 0x0200000000000000 + +> commit -> code: OK -> deliver_tx 0x00 +> finalize_block "hello=world" +-> code: OK +-> code: OK +-> data.hex: 0x0400000000000000 + +> commit -> code: OK -> check_tx 0x00 +> finalize_block "first=second" -> code: OK - -> deliver_tx 0x01 -> code: OK +-> data.hex: 0x0600000000000000 -> deliver_tx 0x04 +> commit -> code: OK > info diff --git a/abci/types/application.go b/abci/types/application.go index 0913ea463..b08862647 100644 --- a/abci/types/application.go +++ b/abci/types/application.go @@ -1,37 +1,33 @@ package types -import ( - context "golang.org/x/net/context" -) +import "context" //go:generate ../../scripts/mockery_generate.sh Application // Application is an interface that enables any finite, deterministic state machine // to be driven by a blockchain-based replication engine via the ABCI. -// All methods take a RequestXxx argument and return a ResponseXxx argument, -// except CheckTx/DeliverTx, which take `tx []byte`, and `Commit`, which takes nothing. type Application interface { // Info/Query Connection - Info(RequestInfo) ResponseInfo // Return application info - Query(RequestQuery) ResponseQuery // Query for state + Info(context.Context, *RequestInfo) (*ResponseInfo, error) // Return application info + Query(context.Context, *RequestQuery) (*ResponseQuery, error) // Query for state // Mempool Connection - CheckTx(RequestCheckTx) ResponseCheckTx // Validate a tx for the mempool + CheckTx(context.Context, *RequestCheckTx) (*ResponseCheckTx, error) // Validate a tx for the mempool // Consensus Connection - InitChain(RequestInitChain) ResponseInitChain // Initialize blockchain w validators/other info from TendermintCore - PrepareProposal(RequestPrepareProposal) ResponsePrepareProposal - ProcessProposal(RequestProcessProposal) ResponseProcessProposal - BeginBlock(RequestBeginBlock) ResponseBeginBlock // Signals the beginning of a block - DeliverTx(RequestDeliverTx) ResponseDeliverTx // Deliver a tx for full processing - EndBlock(RequestEndBlock) ResponseEndBlock // Signals the end of a block, returns changes to the validator set - Commit() ResponseCommit // Commit the state and return the application Merkle root hash + InitChain(context.Context, *RequestInitChain) (*ResponseInitChain, error) // Initialize blockchain w validators/other info from TendermintCore + PrepareProposal(context.Context, *RequestPrepareProposal) (*ResponsePrepareProposal, error) + ProcessProposal(context.Context, *RequestProcessProposal) (*ResponseProcessProposal, error) + // Deliver the decided block with its txs to the Application + FinalizeBlock(context.Context, *RequestFinalizeBlock) (*ResponseFinalizeBlock, error) + // Commit the state and return the application Merkle root hash + Commit(context.Context, *RequestCommit) (*ResponseCommit, error) // State Sync Connection - ListSnapshots(RequestListSnapshots) ResponseListSnapshots // List available snapshots - OfferSnapshot(RequestOfferSnapshot) ResponseOfferSnapshot // Offer a snapshot to the application - LoadSnapshotChunk(RequestLoadSnapshotChunk) ResponseLoadSnapshotChunk // Load a snapshot chunk - ApplySnapshotChunk(RequestApplySnapshotChunk) ResponseApplySnapshotChunk // Apply a shapshot chunk + ListSnapshots(context.Context, *RequestListSnapshots) (*ResponseListSnapshots, error) // List available snapshots + OfferSnapshot(context.Context, *RequestOfferSnapshot) (*ResponseOfferSnapshot, error) // Offer a snapshot to the application + LoadSnapshotChunk(context.Context, *RequestLoadSnapshotChunk) (*ResponseLoadSnapshotChunk, error) // Load a snapshot chunk + ApplySnapshotChunk(context.Context, *RequestApplySnapshotChunk) (*ResponseApplySnapshotChunk, error) // Apply a shapshot chunk } //------------------------------------------------------- @@ -39,62 +35,49 @@ type Application interface { var _ Application = (*BaseApplication)(nil) -type BaseApplication struct { -} +type BaseApplication struct{} func NewBaseApplication() *BaseApplication { return &BaseApplication{} } -func (BaseApplication) Info(req RequestInfo) ResponseInfo { - return ResponseInfo{} +func (BaseApplication) Info(_ context.Context, req *RequestInfo) (*ResponseInfo, error) { + return &ResponseInfo{}, nil } -func (BaseApplication) DeliverTx(req RequestDeliverTx) ResponseDeliverTx { - return ResponseDeliverTx{Code: CodeTypeOK} +func (BaseApplication) CheckTx(_ context.Context, req *RequestCheckTx) (*ResponseCheckTx, error) { + return &ResponseCheckTx{Code: CodeTypeOK}, nil } -func (BaseApplication) CheckTx(req RequestCheckTx) ResponseCheckTx { - return ResponseCheckTx{Code: CodeTypeOK} +func (BaseApplication) Commit(_ context.Context, req *RequestCommit) (*ResponseCommit, error) { + return &ResponseCommit{}, nil } -func (BaseApplication) Commit() ResponseCommit { - return ResponseCommit{} +func (BaseApplication) Query(_ context.Context, req *RequestQuery) (*ResponseQuery, error) { + return &ResponseQuery{Code: CodeTypeOK}, nil } -func (BaseApplication) Query(req RequestQuery) ResponseQuery { - return ResponseQuery{Code: CodeTypeOK} +func (BaseApplication) InitChain(_ context.Context, req *RequestInitChain) (*ResponseInitChain, error) { + return &ResponseInitChain{}, nil } -func (BaseApplication) InitChain(req RequestInitChain) ResponseInitChain { - return ResponseInitChain{} +func (BaseApplication) ListSnapshots(_ context.Context, req *RequestListSnapshots) (*ResponseListSnapshots, error) { + return &ResponseListSnapshots{}, nil } -func (BaseApplication) BeginBlock(req RequestBeginBlock) ResponseBeginBlock { - return ResponseBeginBlock{} +func (BaseApplication) OfferSnapshot(_ context.Context, req *RequestOfferSnapshot) (*ResponseOfferSnapshot, error) { + return &ResponseOfferSnapshot{}, nil } -func (BaseApplication) EndBlock(req RequestEndBlock) ResponseEndBlock { - return ResponseEndBlock{} +func (BaseApplication) LoadSnapshotChunk(_ context.Context, _ *RequestLoadSnapshotChunk) (*ResponseLoadSnapshotChunk, error) { + return &ResponseLoadSnapshotChunk{}, nil } -func (BaseApplication) ListSnapshots(req RequestListSnapshots) ResponseListSnapshots { - return ResponseListSnapshots{} +func (BaseApplication) ApplySnapshotChunk(_ context.Context, req *RequestApplySnapshotChunk) (*ResponseApplySnapshotChunk, error) { + return &ResponseApplySnapshotChunk{}, nil } -func (BaseApplication) OfferSnapshot(req RequestOfferSnapshot) ResponseOfferSnapshot { - return ResponseOfferSnapshot{} -} - -func (BaseApplication) LoadSnapshotChunk(req RequestLoadSnapshotChunk) ResponseLoadSnapshotChunk { - return ResponseLoadSnapshotChunk{} -} - -func (BaseApplication) ApplySnapshotChunk(req RequestApplySnapshotChunk) ResponseApplySnapshotChunk { - return ResponseApplySnapshotChunk{} -} - -func (BaseApplication) PrepareProposal(req RequestPrepareProposal) ResponsePrepareProposal { +func (BaseApplication) PrepareProposal(_ context.Context, req *RequestPrepareProposal) (*ResponsePrepareProposal, error) { txs := make([][]byte, 0, len(req.Txs)) var totalBytes int64 for _, tx := range req.Txs { @@ -104,105 +87,19 @@ func (BaseApplication) PrepareProposal(req RequestPrepareProposal) ResponsePrepa } txs = append(txs, tx) } - return ResponsePrepareProposal{Txs: txs} + return &ResponsePrepareProposal{Txs: txs}, nil } -func (BaseApplication) ProcessProposal(req RequestProcessProposal) ResponseProcessProposal { - return ResponseProcessProposal{ - Status: ResponseProcessProposal_ACCEPT} +func (BaseApplication) ProcessProposal(_ context.Context, req *RequestProcessProposal) (*ResponseProcessProposal, error) { + return &ResponseProcessProposal{Status: ResponseProcessProposal_ACCEPT}, nil } -//------------------------------------------------------- - -// GRPCApplication is a GRPC wrapper for Application -type GRPCApplication struct { - app Application -} - -func NewGRPCApplication(app Application) *GRPCApplication { - return &GRPCApplication{app} -} - -func (app *GRPCApplication) Echo(ctx context.Context, req *RequestEcho) (*ResponseEcho, error) { - return &ResponseEcho{Message: req.Message}, nil -} - -func (app *GRPCApplication) Flush(ctx context.Context, req *RequestFlush) (*ResponseFlush, error) { - return &ResponseFlush{}, nil -} - -func (app *GRPCApplication) Info(ctx context.Context, req *RequestInfo) (*ResponseInfo, error) { - res := app.app.Info(*req) - return &res, nil -} - -func (app *GRPCApplication) DeliverTx(ctx context.Context, req *RequestDeliverTx) (*ResponseDeliverTx, error) { - res := app.app.DeliverTx(*req) - return &res, nil -} - -func (app *GRPCApplication) CheckTx(ctx context.Context, req *RequestCheckTx) (*ResponseCheckTx, error) { - res := app.app.CheckTx(*req) - return &res, nil -} - -func (app *GRPCApplication) Query(ctx context.Context, req *RequestQuery) (*ResponseQuery, error) { - res := app.app.Query(*req) - return &res, nil -} - -func (app *GRPCApplication) Commit(ctx context.Context, req *RequestCommit) (*ResponseCommit, error) { - res := app.app.Commit() - return &res, nil -} - -func (app *GRPCApplication) InitChain(ctx context.Context, req *RequestInitChain) (*ResponseInitChain, error) { - res := app.app.InitChain(*req) - return &res, nil -} - -func (app *GRPCApplication) BeginBlock(ctx context.Context, req *RequestBeginBlock) (*ResponseBeginBlock, error) { - res := app.app.BeginBlock(*req) - return &res, nil -} - -func (app *GRPCApplication) EndBlock(ctx context.Context, req *RequestEndBlock) (*ResponseEndBlock, error) { - res := app.app.EndBlock(*req) - return &res, nil -} - -func (app *GRPCApplication) ListSnapshots( - ctx context.Context, req *RequestListSnapshots) (*ResponseListSnapshots, error) { - res := app.app.ListSnapshots(*req) - return &res, nil -} - -func (app *GRPCApplication) OfferSnapshot( - ctx context.Context, req *RequestOfferSnapshot) (*ResponseOfferSnapshot, error) { - res := app.app.OfferSnapshot(*req) - return &res, nil -} - -func (app *GRPCApplication) LoadSnapshotChunk( - ctx context.Context, req *RequestLoadSnapshotChunk) (*ResponseLoadSnapshotChunk, error) { - res := app.app.LoadSnapshotChunk(*req) - return &res, nil -} - -func (app *GRPCApplication) ApplySnapshotChunk( - ctx context.Context, req *RequestApplySnapshotChunk) (*ResponseApplySnapshotChunk, error) { - res := app.app.ApplySnapshotChunk(*req) - return &res, nil -} - -func (app *GRPCApplication) PrepareProposal( - ctx context.Context, req *RequestPrepareProposal) (*ResponsePrepareProposal, error) { - res := app.app.PrepareProposal(*req) - return &res, nil -} - -func (app *GRPCApplication) ProcessProposal( - ctx context.Context, req *RequestProcessProposal) (*ResponseProcessProposal, error) { - res := app.app.ProcessProposal(*req) - return &res, nil +func (BaseApplication) FinalizeBlock(_ context.Context, req *RequestFinalizeBlock) (*ResponseFinalizeBlock, error) { + txs := make([]*ExecTxResult, len(req.Txs)) + for i := range req.Txs { + txs[i] = &ExecTxResult{Code: CodeTypeOK} + } + return &ResponseFinalizeBlock{ + TxResults: txs, + }, nil } diff --git a/abci/types/messages.go b/abci/types/messages.go index 92a9616c5..fb6348de8 100644 --- a/abci/types/messages.go +++ b/abci/types/messages.go @@ -15,11 +15,7 @@ const ( func WriteMessage(msg proto.Message, w io.Writer) error { protoWriter := protoio.NewDelimitedWriter(w) _, err := protoWriter.WriteMsg(msg) - if err != nil { - return err - } - - return nil + return err } // ReadMessage reads a varint length-delimited protobuf message. @@ -42,21 +38,15 @@ func ToRequestFlush() *Request { } } -func ToRequestInfo(req RequestInfo) *Request { +func ToRequestInfo(req *RequestInfo) *Request { return &Request{ - Value: &Request_Info{&req}, + Value: &Request_Info{req}, } } -func ToRequestDeliverTx(req RequestDeliverTx) *Request { +func ToRequestCheckTx(req *RequestCheckTx) *Request { return &Request{ - Value: &Request_DeliverTx{&req}, - } -} - -func ToRequestCheckTx(req RequestCheckTx) *Request { - return &Request{ - Value: &Request_CheckTx{&req}, + Value: &Request_CheckTx{req}, } } @@ -66,63 +56,57 @@ func ToRequestCommit() *Request { } } -func ToRequestQuery(req RequestQuery) *Request { +func ToRequestQuery(req *RequestQuery) *Request { return &Request{ - Value: &Request_Query{&req}, + Value: &Request_Query{req}, } } -func ToRequestInitChain(req RequestInitChain) *Request { +func ToRequestInitChain(req *RequestInitChain) *Request { return &Request{ - Value: &Request_InitChain{&req}, + Value: &Request_InitChain{req}, } } -func ToRequestBeginBlock(req RequestBeginBlock) *Request { +func ToRequestListSnapshots(req *RequestListSnapshots) *Request { return &Request{ - Value: &Request_BeginBlock{&req}, + Value: &Request_ListSnapshots{req}, } } -func ToRequestEndBlock(req RequestEndBlock) *Request { +func ToRequestOfferSnapshot(req *RequestOfferSnapshot) *Request { return &Request{ - Value: &Request_EndBlock{&req}, + Value: &Request_OfferSnapshot{req}, } } -func ToRequestListSnapshots(req RequestListSnapshots) *Request { +func ToRequestLoadSnapshotChunk(req *RequestLoadSnapshotChunk) *Request { return &Request{ - Value: &Request_ListSnapshots{&req}, + Value: &Request_LoadSnapshotChunk{req}, } } -func ToRequestOfferSnapshot(req RequestOfferSnapshot) *Request { +func ToRequestApplySnapshotChunk(req *RequestApplySnapshotChunk) *Request { return &Request{ - Value: &Request_OfferSnapshot{&req}, + Value: &Request_ApplySnapshotChunk{req}, } } -func ToRequestLoadSnapshotChunk(req RequestLoadSnapshotChunk) *Request { +func ToRequestPrepareProposal(req *RequestPrepareProposal) *Request { return &Request{ - Value: &Request_LoadSnapshotChunk{&req}, + Value: &Request_PrepareProposal{req}, } } -func ToRequestApplySnapshotChunk(req RequestApplySnapshotChunk) *Request { +func ToRequestProcessProposal(req *RequestProcessProposal) *Request { return &Request{ - Value: &Request_ApplySnapshotChunk{&req}, + Value: &Request_ProcessProposal{req}, } } -func ToRequestPrepareProposal(req RequestPrepareProposal) *Request { +func ToRequestFinalizeBlock(req *RequestFinalizeBlock) *Request { return &Request{ - Value: &Request_PrepareProposal{&req}, - } -} - -func ToRequestProcessProposal(req RequestProcessProposal) *Request { - return &Request{ - Value: &Request_ProcessProposal{&req}, + Value: &Request_FinalizeBlock{req}, } } @@ -146,86 +130,74 @@ func ToResponseFlush() *Response { } } -func ToResponseInfo(res ResponseInfo) *Response { +func ToResponseInfo(res *ResponseInfo) *Response { return &Response{ - Value: &Response_Info{&res}, + Value: &Response_Info{res}, } } -func ToResponseDeliverTx(res ResponseDeliverTx) *Response { +func ToResponseCheckTx(res *ResponseCheckTx) *Response { return &Response{ - Value: &Response_DeliverTx{&res}, + Value: &Response_CheckTx{res}, } } -func ToResponseCheckTx(res ResponseCheckTx) *Response { +func ToResponseCommit(res *ResponseCommit) *Response { return &Response{ - Value: &Response_CheckTx{&res}, + Value: &Response_Commit{res}, } } -func ToResponseCommit(res ResponseCommit) *Response { +func ToResponseQuery(res *ResponseQuery) *Response { return &Response{ - Value: &Response_Commit{&res}, + Value: &Response_Query{res}, } } -func ToResponseQuery(res ResponseQuery) *Response { +func ToResponseInitChain(res *ResponseInitChain) *Response { return &Response{ - Value: &Response_Query{&res}, + Value: &Response_InitChain{res}, } } -func ToResponseInitChain(res ResponseInitChain) *Response { +func ToResponseListSnapshots(res *ResponseListSnapshots) *Response { return &Response{ - Value: &Response_InitChain{&res}, + Value: &Response_ListSnapshots{res}, } } -func ToResponseBeginBlock(res ResponseBeginBlock) *Response { +func ToResponseOfferSnapshot(res *ResponseOfferSnapshot) *Response { return &Response{ - Value: &Response_BeginBlock{&res}, + Value: &Response_OfferSnapshot{res}, } } -func ToResponseEndBlock(res ResponseEndBlock) *Response { +func ToResponseLoadSnapshotChunk(res *ResponseLoadSnapshotChunk) *Response { return &Response{ - Value: &Response_EndBlock{&res}, + Value: &Response_LoadSnapshotChunk{res}, } } -func ToResponseListSnapshots(res ResponseListSnapshots) *Response { +func ToResponseApplySnapshotChunk(res *ResponseApplySnapshotChunk) *Response { return &Response{ - Value: &Response_ListSnapshots{&res}, + Value: &Response_ApplySnapshotChunk{res}, } } -func ToResponseOfferSnapshot(res ResponseOfferSnapshot) *Response { +func ToResponsePrepareProposal(res *ResponsePrepareProposal) *Response { return &Response{ - Value: &Response_OfferSnapshot{&res}, + Value: &Response_PrepareProposal{res}, } } -func ToResponseLoadSnapshotChunk(res ResponseLoadSnapshotChunk) *Response { +func ToResponseProcessProposal(res *ResponseProcessProposal) *Response { return &Response{ - Value: &Response_LoadSnapshotChunk{&res}, + Value: &Response_ProcessProposal{res}, } } -func ToResponseApplySnapshotChunk(res ResponseApplySnapshotChunk) *Response { +func ToResponseFinalizeBlock(res *ResponseFinalizeBlock) *Response { return &Response{ - Value: &Response_ApplySnapshotChunk{&res}, - } -} - -func ToResponsePrepareProposal(res ResponsePrepareProposal) *Response { - return &Response{ - Value: &Response_PrepareProposal{&res}, - } -} - -func ToResponseProcessProposal(res ResponseProcessProposal) *Response { - return &Response{ - Value: &Response_ProcessProposal{&res}, + Value: &Response_FinalizeBlock{res}, } } diff --git a/abci/types/messages_test.go b/abci/types/messages_test.go index 17613769f..3ebfe380c 100644 --- a/abci/types/messages_test.go +++ b/abci/types/messages_test.go @@ -13,8 +13,8 @@ import ( ) func TestMarshalJSON(t *testing.T) { - b, err := json.Marshal(&ResponseDeliverTx{}) - assert.Nil(t, err) + b, err := json.Marshal(&ExecTxResult{Code: 1}) + assert.NoError(t, err) // include empty fields. assert.True(t, strings.Contains(string(b), "code")) r1 := ResponseCheckTx{ diff --git a/abci/types/mocks/application.go b/abci/types/mocks/application.go index 75f573a84..a39d1f2e6 100644 --- a/abci/types/mocks/application.go +++ b/abci/types/mocks/application.go @@ -3,6 +3,8 @@ package mocks import ( + context "context" + mock "github.com/stretchr/testify/mock" types "github.com/tendermint/tendermint/abci/types" ) @@ -12,200 +14,280 @@ type Application struct { mock.Mock } -// ApplySnapshotChunk provides a mock function with given fields: _a0 -func (_m *Application) ApplySnapshotChunk(_a0 types.RequestApplySnapshotChunk) types.ResponseApplySnapshotChunk { - ret := _m.Called(_a0) +// ApplySnapshotChunk provides a mock function with given fields: _a0, _a1 +func (_m *Application) ApplySnapshotChunk(_a0 context.Context, _a1 *types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { + ret := _m.Called(_a0, _a1) - var r0 types.ResponseApplySnapshotChunk - if rf, ok := ret.Get(0).(func(types.RequestApplySnapshotChunk) types.ResponseApplySnapshotChunk); ok { - r0 = rf(_a0) + var r0 *types.ResponseApplySnapshotChunk + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestApplySnapshotChunk) *types.ResponseApplySnapshotChunk); ok { + r0 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(types.ResponseApplySnapshotChunk) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseApplySnapshotChunk) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestApplySnapshotChunk) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// BeginBlock provides a mock function with given fields: _a0 -func (_m *Application) BeginBlock(_a0 types.RequestBeginBlock) types.ResponseBeginBlock { - ret := _m.Called(_a0) +// CheckTx provides a mock function with given fields: _a0, _a1 +func (_m *Application) CheckTx(_a0 context.Context, _a1 *types.RequestCheckTx) (*types.ResponseCheckTx, error) { + ret := _m.Called(_a0, _a1) - var r0 types.ResponseBeginBlock - if rf, ok := ret.Get(0).(func(types.RequestBeginBlock) types.ResponseBeginBlock); ok { - r0 = rf(_a0) + var r0 *types.ResponseCheckTx + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestCheckTx) *types.ResponseCheckTx); ok { + r0 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(types.ResponseBeginBlock) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseCheckTx) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestCheckTx) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// CheckTx provides a mock function with given fields: _a0 -func (_m *Application) CheckTx(_a0 types.RequestCheckTx) types.ResponseCheckTx { - ret := _m.Called(_a0) +// Commit provides a mock function with given fields: _a0, _a1 +func (_m *Application) Commit(_a0 context.Context, _a1 *types.RequestCommit) (*types.ResponseCommit, error) { + ret := _m.Called(_a0, _a1) - var r0 types.ResponseCheckTx - if rf, ok := ret.Get(0).(func(types.RequestCheckTx) types.ResponseCheckTx); ok { - r0 = rf(_a0) + var r0 *types.ResponseCommit + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestCommit) *types.ResponseCommit); ok { + r0 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(types.ResponseCheckTx) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseCommit) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestCommit) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// Commit provides a mock function with given fields: -func (_m *Application) Commit() types.ResponseCommit { - ret := _m.Called() +// FinalizeBlock provides a mock function with given fields: _a0, _a1 +func (_m *Application) FinalizeBlock(_a0 context.Context, _a1 *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { + ret := _m.Called(_a0, _a1) - var r0 types.ResponseCommit - if rf, ok := ret.Get(0).(func() types.ResponseCommit); ok { - r0 = rf() + var r0 *types.ResponseFinalizeBlock + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestFinalizeBlock) *types.ResponseFinalizeBlock); ok { + r0 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(types.ResponseCommit) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseFinalizeBlock) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestFinalizeBlock) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// DeliverTx provides a mock function with given fields: _a0 -func (_m *Application) DeliverTx(_a0 types.RequestDeliverTx) types.ResponseDeliverTx { - ret := _m.Called(_a0) +// Info provides a mock function with given fields: _a0, _a1 +func (_m *Application) Info(_a0 context.Context, _a1 *types.RequestInfo) (*types.ResponseInfo, error) { + ret := _m.Called(_a0, _a1) - var r0 types.ResponseDeliverTx - if rf, ok := ret.Get(0).(func(types.RequestDeliverTx) types.ResponseDeliverTx); ok { - r0 = rf(_a0) + var r0 *types.ResponseInfo + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestInfo) *types.ResponseInfo); ok { + r0 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(types.ResponseDeliverTx) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseInfo) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestInfo) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// EndBlock provides a mock function with given fields: _a0 -func (_m *Application) EndBlock(_a0 types.RequestEndBlock) types.ResponseEndBlock { - ret := _m.Called(_a0) +// InitChain provides a mock function with given fields: _a0, _a1 +func (_m *Application) InitChain(_a0 context.Context, _a1 *types.RequestInitChain) (*types.ResponseInitChain, error) { + ret := _m.Called(_a0, _a1) - var r0 types.ResponseEndBlock - if rf, ok := ret.Get(0).(func(types.RequestEndBlock) types.ResponseEndBlock); ok { - r0 = rf(_a0) + var r0 *types.ResponseInitChain + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestInitChain) *types.ResponseInitChain); ok { + r0 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(types.ResponseEndBlock) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseInitChain) + } } - return r0 + 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 } -// Info provides a mock function with given fields: _a0 -func (_m *Application) Info(_a0 types.RequestInfo) types.ResponseInfo { - ret := _m.Called(_a0) +// ListSnapshots provides a mock function with given fields: _a0, _a1 +func (_m *Application) ListSnapshots(_a0 context.Context, _a1 *types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { + ret := _m.Called(_a0, _a1) - var r0 types.ResponseInfo - if rf, ok := ret.Get(0).(func(types.RequestInfo) types.ResponseInfo); ok { - r0 = rf(_a0) + var r0 *types.ResponseListSnapshots + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestListSnapshots) *types.ResponseListSnapshots); ok { + r0 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(types.ResponseInfo) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseListSnapshots) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestListSnapshots) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// InitChain provides a mock function with given fields: _a0 -func (_m *Application) InitChain(_a0 types.RequestInitChain) types.ResponseInitChain { - ret := _m.Called(_a0) +// LoadSnapshotChunk provides a mock function with given fields: _a0, _a1 +func (_m *Application) LoadSnapshotChunk(_a0 context.Context, _a1 *types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { + ret := _m.Called(_a0, _a1) - var r0 types.ResponseInitChain - if rf, ok := ret.Get(0).(func(types.RequestInitChain) types.ResponseInitChain); ok { - r0 = rf(_a0) + var r0 *types.ResponseLoadSnapshotChunk + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestLoadSnapshotChunk) *types.ResponseLoadSnapshotChunk); ok { + r0 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(types.ResponseInitChain) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseLoadSnapshotChunk) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestLoadSnapshotChunk) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// ListSnapshots provides a mock function with given fields: _a0 -func (_m *Application) ListSnapshots(_a0 types.RequestListSnapshots) types.ResponseListSnapshots { - ret := _m.Called(_a0) +// OfferSnapshot provides a mock function with given fields: _a0, _a1 +func (_m *Application) OfferSnapshot(_a0 context.Context, _a1 *types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { + ret := _m.Called(_a0, _a1) - var r0 types.ResponseListSnapshots - if rf, ok := ret.Get(0).(func(types.RequestListSnapshots) types.ResponseListSnapshots); ok { - r0 = rf(_a0) + var r0 *types.ResponseOfferSnapshot + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestOfferSnapshot) *types.ResponseOfferSnapshot); ok { + r0 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(types.ResponseListSnapshots) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseOfferSnapshot) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestOfferSnapshot) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// LoadSnapshotChunk provides a mock function with given fields: _a0 -func (_m *Application) LoadSnapshotChunk(_a0 types.RequestLoadSnapshotChunk) types.ResponseLoadSnapshotChunk { - ret := _m.Called(_a0) +// PrepareProposal provides a mock function with given fields: _a0, _a1 +func (_m *Application) PrepareProposal(_a0 context.Context, _a1 *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { + ret := _m.Called(_a0, _a1) - var r0 types.ResponseLoadSnapshotChunk - if rf, ok := ret.Get(0).(func(types.RequestLoadSnapshotChunk) types.ResponseLoadSnapshotChunk); ok { - r0 = rf(_a0) + var r0 *types.ResponsePrepareProposal + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestPrepareProposal) *types.ResponsePrepareProposal); ok { + r0 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(types.ResponseLoadSnapshotChunk) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponsePrepareProposal) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestPrepareProposal) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// OfferSnapshot provides a mock function with given fields: _a0 -func (_m *Application) OfferSnapshot(_a0 types.RequestOfferSnapshot) types.ResponseOfferSnapshot { - ret := _m.Called(_a0) +// ProcessProposal provides a mock function with given fields: _a0, _a1 +func (_m *Application) ProcessProposal(_a0 context.Context, _a1 *types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { + ret := _m.Called(_a0, _a1) - var r0 types.ResponseOfferSnapshot - if rf, ok := ret.Get(0).(func(types.RequestOfferSnapshot) types.ResponseOfferSnapshot); ok { - r0 = rf(_a0) + var r0 *types.ResponseProcessProposal + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestProcessProposal) *types.ResponseProcessProposal); ok { + r0 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(types.ResponseOfferSnapshot) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseProcessProposal) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestProcessProposal) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// PrepareProposal provides a mock function with given fields: _a0 -func (_m *Application) PrepareProposal(_a0 types.RequestPrepareProposal) types.ResponsePrepareProposal { - ret := _m.Called(_a0) +// Query provides a mock function with given fields: _a0, _a1 +func (_m *Application) Query(_a0 context.Context, _a1 *types.RequestQuery) (*types.ResponseQuery, error) { + ret := _m.Called(_a0, _a1) - var r0 types.ResponsePrepareProposal - if rf, ok := ret.Get(0).(func(types.RequestPrepareProposal) types.ResponsePrepareProposal); ok { - r0 = rf(_a0) + var r0 *types.ResponseQuery + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestQuery) *types.ResponseQuery); ok { + r0 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(types.ResponsePrepareProposal) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseQuery) + } } - return r0 -} - -// ProcessProposal provides a mock function with given fields: _a0 -func (_m *Application) ProcessProposal(_a0 types.RequestProcessProposal) types.ResponseProcessProposal { - ret := _m.Called(_a0) - - var r0 types.ResponseProcessProposal - if rf, ok := ret.Get(0).(func(types.RequestProcessProposal) types.ResponseProcessProposal); ok { - r0 = rf(_a0) + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestQuery) error); ok { + r1 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(types.ResponseProcessProposal) + r1 = ret.Error(1) } - return r0 -} - -// Query provides a mock function with given fields: _a0 -func (_m *Application) Query(_a0 types.RequestQuery) types.ResponseQuery { - ret := _m.Called(_a0) - - var r0 types.ResponseQuery - if rf, ok := ret.Get(0).(func(types.RequestQuery) types.ResponseQuery); ok { - r0 = rf(_a0) - } else { - r0 = ret.Get(0).(types.ResponseQuery) - } - - return r0 + return r0, r1 } type mockConstructorTestingTNewApplication interface { diff --git a/abci/types/mocks/base.go b/abci/types/mocks/base.go deleted file mode 100644 index d0a33ebb0..000000000 --- a/abci/types/mocks/base.go +++ /dev/null @@ -1,187 +0,0 @@ -package mocks - -import ( - types "github.com/tendermint/tendermint/abci/types" -) - -// BaseMock provides a wrapper around the generated Application mock and a BaseApplication. -// BaseMock first tries to use the mock's implementation of the method. -// If no functionality was provided for the mock by the user, BaseMock dispatches -// to the BaseApplication and uses its functionality. -// BaseMock allows users to provide mocked functionality for only the methods that matter -// for their test while avoiding a panic if the code calls Application methods that are -// not relevant to the test. -type BaseMock struct { - base *types.BaseApplication - *Application -} - -func NewBaseMock() BaseMock { - return BaseMock{ - base: types.NewBaseApplication(), - Application: new(Application), - } -} - -// Info/Query Connection -// Return application info -func (m BaseMock) Info(input types.RequestInfo) types.ResponseInfo { - var ret types.ResponseInfo - defer func() { - if r := recover(); r != nil { - ret = m.base.Info(input) - } - }() - ret = m.Application.Info(input) - return ret -} - -func (m BaseMock) Query(input types.RequestQuery) types.ResponseQuery { - var ret types.ResponseQuery - defer func() { - if r := recover(); r != nil { - ret = m.base.Query(input) - } - }() - ret = m.Application.Query(input) - return ret -} - -// Mempool Connection -// Validate a tx for the mempool -func (m BaseMock) CheckTx(input types.RequestCheckTx) types.ResponseCheckTx { - var ret types.ResponseCheckTx - defer func() { - if r := recover(); r != nil { - ret = m.base.CheckTx(input) - } - }() - ret = m.Application.CheckTx(input) - return ret -} - -// Consensus Connection -// Initialize blockchain w validators/other info from TendermintCore -func (m BaseMock) InitChain(input types.RequestInitChain) types.ResponseInitChain { - var ret types.ResponseInitChain - defer func() { - if r := recover(); r != nil { - ret = m.base.InitChain(input) - } - }() - ret = m.Application.InitChain(input) - return ret -} - -func (m BaseMock) PrepareProposal(input types.RequestPrepareProposal) types.ResponsePrepareProposal { - var ret types.ResponsePrepareProposal - defer func() { - if r := recover(); r != nil { - ret = m.base.PrepareProposal(input) - } - }() - ret = m.Application.PrepareProposal(input) - return ret -} - -func (m BaseMock) ProcessProposal(input types.RequestProcessProposal) types.ResponseProcessProposal { - var ret types.ResponseProcessProposal - defer func() { - if r := recover(); r != nil { - ret = m.base.ProcessProposal(input) - } - }() - ret = m.Application.ProcessProposal(input) - return ret -} - -// Commit the state and return the application Merkle root hash -func (m BaseMock) Commit() types.ResponseCommit { - var ret types.ResponseCommit - defer func() { - if r := recover(); r != nil { - ret = m.base.Commit() - } - }() - ret = m.Application.Commit() - return ret -} - -// State Sync Connection -// List available snapshots -func (m BaseMock) ListSnapshots(input types.RequestListSnapshots) types.ResponseListSnapshots { - var ret types.ResponseListSnapshots - defer func() { - if r := recover(); r != nil { - ret = m.base.ListSnapshots(input) - } - }() - ret = m.Application.ListSnapshots(input) - return ret -} - -func (m BaseMock) OfferSnapshot(input types.RequestOfferSnapshot) types.ResponseOfferSnapshot { - var ret types.ResponseOfferSnapshot - defer func() { - if r := recover(); r != nil { - ret = m.base.OfferSnapshot(input) - } - }() - ret = m.Application.OfferSnapshot(input) - return ret -} - -func (m BaseMock) LoadSnapshotChunk(input types.RequestLoadSnapshotChunk) types.ResponseLoadSnapshotChunk { - var ret types.ResponseLoadSnapshotChunk - defer func() { - if r := recover(); r != nil { - ret = m.base.LoadSnapshotChunk(input) - } - }() - ret = m.Application.LoadSnapshotChunk(input) - return ret -} - -func (m BaseMock) ApplySnapshotChunk(input types.RequestApplySnapshotChunk) types.ResponseApplySnapshotChunk { - var ret types.ResponseApplySnapshotChunk - defer func() { - if r := recover(); r != nil { - ret = m.base.ApplySnapshotChunk(input) - } - }() - ret = m.Application.ApplySnapshotChunk(input) - return ret -} - -func (m BaseMock) BeginBlock(input types.RequestBeginBlock) types.ResponseBeginBlock { - var ret types.ResponseBeginBlock - defer func() { - if r := recover(); r != nil { - ret = m.base.BeginBlock(input) - } - }() - ret = m.Application.BeginBlock(input) - return ret -} - -func (m BaseMock) DeliverTx(input types.RequestDeliverTx) types.ResponseDeliverTx { - var ret types.ResponseDeliverTx - defer func() { - if r := recover(); r != nil { - ret = m.base.DeliverTx(input) - } - }() - ret = m.Application.DeliverTx(input) - return ret -} - -func (m BaseMock) EndBlock(input types.RequestEndBlock) types.ResponseEndBlock { - var ret types.ResponseEndBlock - defer func() { - if r := recover(); r != nil { - ret = m.base.EndBlock(input) - } - }() - ret = m.Application.EndBlock(input) - return ret -} diff --git a/abci/types/types.go b/abci/types/types.go index 4b42d0e56..414319bac 100644 --- a/abci/types/types.go +++ b/abci/types/types.go @@ -22,12 +22,12 @@ func (r ResponseCheckTx) IsErr() bool { } // IsOK returns true if Code is OK. -func (r ResponseDeliverTx) IsOK() bool { +func (r ExecTxResult) IsOK() bool { return r.Code == CodeTypeOK } // IsErr returns true if Code is something other than OK. -func (r ResponseDeliverTx) IsErr() bool { +func (r ExecTxResult) IsErr() bool { return r.Code != CodeTypeOK } @@ -72,12 +72,12 @@ func (r *ResponseCheckTx) UnmarshalJSON(b []byte) error { return jsonpbUnmarshaller.Unmarshal(reader, r) } -func (r *ResponseDeliverTx) MarshalJSON() ([]byte, error) { +func (r *ExecTxResult) MarshalJSON() ([]byte, error) { s, err := jsonpbMarshaller.MarshalToString(r) return []byte(s), err } -func (r *ResponseDeliverTx) UnmarshalJSON(b []byte) error { +func (r *ExecTxResult) UnmarshalJSON(b []byte) error { reader := bytes.NewBuffer(b) return jsonpbUnmarshaller.Unmarshal(reader, r) } @@ -124,7 +124,35 @@ type jsonRoundTripper interface { var _ jsonRoundTripper = (*ResponseCommit)(nil) var _ jsonRoundTripper = (*ResponseQuery)(nil) -var _ jsonRoundTripper = (*ResponseDeliverTx)(nil) +var _ jsonRoundTripper = (*ExecTxResult)(nil) var _ jsonRoundTripper = (*ResponseCheckTx)(nil) var _ jsonRoundTripper = (*EventAttribute)(nil) + +// deterministicExecTxResult constructs a copy of response that omits +// non-deterministic fields. The input response is not modified. +func deterministicExecTxResult(response *ExecTxResult) *ExecTxResult { + return &ExecTxResult{ + Code: response.Code, + Data: response.Data, + GasWanted: response.GasWanted, + GasUsed: response.GasUsed, + } +} + +// MarshalTxResults encodes the the TxResults as a list of byte +// slices. It strips off the non-deterministic pieces of the TxResults +// so that the resulting data can be used for hash comparisons and used +// in Merkle proofs. +func MarshalTxResults(r []*ExecTxResult) ([][]byte, error) { + s := make([][]byte, len(r)) + for i, e := range r { + d := deterministicExecTxResult(e) + b, err := d.Marshal() + if err != nil { + return nil, err + } + s[i] = b + } + return s, nil +} diff --git a/abci/types/types.pb.go b/abci/types/types.pb.go index da8ac16aa..6bf451e76 100644 --- a/abci/types/types.pb.go +++ b/abci/types/types.pb.go @@ -121,7 +121,7 @@ func (x ResponseOfferSnapshot_Result) String() string { } func (ResponseOfferSnapshot_Result) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{30, 0} + return fileDescriptor_252557cfdd89a31a, []int{25, 0} } type ResponseApplySnapshotChunk_Result int32 @@ -158,7 +158,7 @@ func (x ResponseApplySnapshotChunk_Result) String() string { } func (ResponseApplySnapshotChunk_Result) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{32, 0} + return fileDescriptor_252557cfdd89a31a, []int{27, 0} } type ResponseProcessProposal_ProposalStatus int32 @@ -186,7 +186,7 @@ func (x ResponseProcessProposal_ProposalStatus) String() string { } func (ResponseProcessProposal_ProposalStatus) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{34, 0} + return fileDescriptor_252557cfdd89a31a, []int{29, 0} } type Request struct { @@ -196,10 +196,7 @@ type Request struct { // *Request_Info // *Request_InitChain // *Request_Query - // *Request_BeginBlock // *Request_CheckTx - // *Request_DeliverTx - // *Request_EndBlock // *Request_Commit // *Request_ListSnapshots // *Request_OfferSnapshot @@ -207,6 +204,7 @@ type Request struct { // *Request_ApplySnapshotChunk // *Request_PrepareProposal // *Request_ProcessProposal + // *Request_FinalizeBlock Value isRequest_Value `protobuf_oneof:"value"` } @@ -264,18 +262,9 @@ type Request_InitChain struct { type Request_Query struct { Query *RequestQuery `protobuf:"bytes,6,opt,name=query,proto3,oneof" json:"query,omitempty"` } -type Request_BeginBlock struct { - BeginBlock *RequestBeginBlock `protobuf:"bytes,7,opt,name=begin_block,json=beginBlock,proto3,oneof" json:"begin_block,omitempty"` -} type Request_CheckTx struct { CheckTx *RequestCheckTx `protobuf:"bytes,8,opt,name=check_tx,json=checkTx,proto3,oneof" json:"check_tx,omitempty"` } -type Request_DeliverTx struct { - DeliverTx *RequestDeliverTx `protobuf:"bytes,9,opt,name=deliver_tx,json=deliverTx,proto3,oneof" json:"deliver_tx,omitempty"` -} -type Request_EndBlock struct { - EndBlock *RequestEndBlock `protobuf:"bytes,10,opt,name=end_block,json=endBlock,proto3,oneof" json:"end_block,omitempty"` -} type Request_Commit struct { Commit *RequestCommit `protobuf:"bytes,11,opt,name=commit,proto3,oneof" json:"commit,omitempty"` } @@ -297,16 +286,16 @@ type Request_PrepareProposal struct { type Request_ProcessProposal struct { ProcessProposal *RequestProcessProposal `protobuf:"bytes,17,opt,name=process_proposal,json=processProposal,proto3,oneof" json:"process_proposal,omitempty"` } +type Request_FinalizeBlock struct { + FinalizeBlock *RequestFinalizeBlock `protobuf:"bytes,20,opt,name=finalize_block,json=finalizeBlock,proto3,oneof" json:"finalize_block,omitempty"` +} func (*Request_Echo) isRequest_Value() {} func (*Request_Flush) isRequest_Value() {} func (*Request_Info) isRequest_Value() {} func (*Request_InitChain) isRequest_Value() {} func (*Request_Query) isRequest_Value() {} -func (*Request_BeginBlock) isRequest_Value() {} func (*Request_CheckTx) isRequest_Value() {} -func (*Request_DeliverTx) isRequest_Value() {} -func (*Request_EndBlock) isRequest_Value() {} func (*Request_Commit) isRequest_Value() {} func (*Request_ListSnapshots) isRequest_Value() {} func (*Request_OfferSnapshot) isRequest_Value() {} @@ -314,6 +303,7 @@ func (*Request_LoadSnapshotChunk) isRequest_Value() {} func (*Request_ApplySnapshotChunk) isRequest_Value() {} func (*Request_PrepareProposal) isRequest_Value() {} func (*Request_ProcessProposal) isRequest_Value() {} +func (*Request_FinalizeBlock) isRequest_Value() {} func (m *Request) GetValue() isRequest_Value { if m != nil { @@ -357,13 +347,6 @@ func (m *Request) GetQuery() *RequestQuery { return nil } -func (m *Request) GetBeginBlock() *RequestBeginBlock { - if x, ok := m.GetValue().(*Request_BeginBlock); ok { - return x.BeginBlock - } - return nil -} - func (m *Request) GetCheckTx() *RequestCheckTx { if x, ok := m.GetValue().(*Request_CheckTx); ok { return x.CheckTx @@ -371,20 +354,6 @@ func (m *Request) GetCheckTx() *RequestCheckTx { return nil } -func (m *Request) GetDeliverTx() *RequestDeliverTx { - if x, ok := m.GetValue().(*Request_DeliverTx); ok { - return x.DeliverTx - } - return nil -} - -func (m *Request) GetEndBlock() *RequestEndBlock { - if x, ok := m.GetValue().(*Request_EndBlock); ok { - return x.EndBlock - } - return nil -} - func (m *Request) GetCommit() *RequestCommit { if x, ok := m.GetValue().(*Request_Commit); ok { return x.Commit @@ -434,6 +403,13 @@ func (m *Request) GetProcessProposal() *RequestProcessProposal { return nil } +func (m *Request) GetFinalizeBlock() *RequestFinalizeBlock { + if x, ok := m.GetValue().(*Request_FinalizeBlock); ok { + return x.FinalizeBlock + } + return nil +} + // XXX_OneofWrappers is for the internal use of the proto package. func (*Request) XXX_OneofWrappers() []interface{} { return []interface{}{ @@ -442,10 +418,7 @@ func (*Request) XXX_OneofWrappers() []interface{} { (*Request_Info)(nil), (*Request_InitChain)(nil), (*Request_Query)(nil), - (*Request_BeginBlock)(nil), (*Request_CheckTx)(nil), - (*Request_DeliverTx)(nil), - (*Request_EndBlock)(nil), (*Request_Commit)(nil), (*Request_ListSnapshots)(nil), (*Request_OfferSnapshot)(nil), @@ -453,6 +426,7 @@ func (*Request) XXX_OneofWrappers() []interface{} { (*Request_ApplySnapshotChunk)(nil), (*Request_PrepareProposal)(nil), (*Request_ProcessProposal)(nil), + (*Request_FinalizeBlock)(nil), } } @@ -756,74 +730,6 @@ func (m *RequestQuery) GetProve() bool { return false } -type RequestBeginBlock struct { - Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` - Header types1.Header `protobuf:"bytes,2,opt,name=header,proto3" json:"header"` - LastCommitInfo CommitInfo `protobuf:"bytes,3,opt,name=last_commit_info,json=lastCommitInfo,proto3" json:"last_commit_info"` - ByzantineValidators []Misbehavior `protobuf:"bytes,4,rep,name=byzantine_validators,json=byzantineValidators,proto3" json:"byzantine_validators"` -} - -func (m *RequestBeginBlock) Reset() { *m = RequestBeginBlock{} } -func (m *RequestBeginBlock) String() string { return proto.CompactTextString(m) } -func (*RequestBeginBlock) ProtoMessage() {} -func (*RequestBeginBlock) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{6} -} -func (m *RequestBeginBlock) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *RequestBeginBlock) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_RequestBeginBlock.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *RequestBeginBlock) XXX_Merge(src proto.Message) { - xxx_messageInfo_RequestBeginBlock.Merge(m, src) -} -func (m *RequestBeginBlock) XXX_Size() int { - return m.Size() -} -func (m *RequestBeginBlock) XXX_DiscardUnknown() { - xxx_messageInfo_RequestBeginBlock.DiscardUnknown(m) -} - -var xxx_messageInfo_RequestBeginBlock proto.InternalMessageInfo - -func (m *RequestBeginBlock) GetHash() []byte { - if m != nil { - return m.Hash - } - return nil -} - -func (m *RequestBeginBlock) GetHeader() types1.Header { - if m != nil { - return m.Header - } - return types1.Header{} -} - -func (m *RequestBeginBlock) GetLastCommitInfo() CommitInfo { - if m != nil { - return m.LastCommitInfo - } - return CommitInfo{} -} - -func (m *RequestBeginBlock) GetByzantineValidators() []Misbehavior { - if m != nil { - return m.ByzantineValidators - } - return nil -} - type RequestCheckTx struct { Tx []byte `protobuf:"bytes,1,opt,name=tx,proto3" json:"tx,omitempty"` Type CheckTxType `protobuf:"varint,2,opt,name=type,proto3,enum=tendermint.abci.CheckTxType" json:"type,omitempty"` @@ -833,7 +739,7 @@ func (m *RequestCheckTx) Reset() { *m = RequestCheckTx{} } func (m *RequestCheckTx) String() string { return proto.CompactTextString(m) } func (*RequestCheckTx) ProtoMessage() {} func (*RequestCheckTx) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{7} + return fileDescriptor_252557cfdd89a31a, []int{6} } func (m *RequestCheckTx) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -876,94 +782,6 @@ func (m *RequestCheckTx) GetType() CheckTxType { return CheckTxType_New } -type RequestDeliverTx struct { - Tx []byte `protobuf:"bytes,1,opt,name=tx,proto3" json:"tx,omitempty"` -} - -func (m *RequestDeliverTx) Reset() { *m = RequestDeliverTx{} } -func (m *RequestDeliverTx) String() string { return proto.CompactTextString(m) } -func (*RequestDeliverTx) ProtoMessage() {} -func (*RequestDeliverTx) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{8} -} -func (m *RequestDeliverTx) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *RequestDeliverTx) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_RequestDeliverTx.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *RequestDeliverTx) XXX_Merge(src proto.Message) { - xxx_messageInfo_RequestDeliverTx.Merge(m, src) -} -func (m *RequestDeliverTx) XXX_Size() int { - return m.Size() -} -func (m *RequestDeliverTx) XXX_DiscardUnknown() { - xxx_messageInfo_RequestDeliverTx.DiscardUnknown(m) -} - -var xxx_messageInfo_RequestDeliverTx proto.InternalMessageInfo - -func (m *RequestDeliverTx) GetTx() []byte { - if m != nil { - return m.Tx - } - return nil -} - -type RequestEndBlock struct { - Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"` -} - -func (m *RequestEndBlock) Reset() { *m = RequestEndBlock{} } -func (m *RequestEndBlock) String() string { return proto.CompactTextString(m) } -func (*RequestEndBlock) ProtoMessage() {} -func (*RequestEndBlock) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{9} -} -func (m *RequestEndBlock) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *RequestEndBlock) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_RequestEndBlock.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *RequestEndBlock) XXX_Merge(src proto.Message) { - xxx_messageInfo_RequestEndBlock.Merge(m, src) -} -func (m *RequestEndBlock) XXX_Size() int { - return m.Size() -} -func (m *RequestEndBlock) XXX_DiscardUnknown() { - xxx_messageInfo_RequestEndBlock.DiscardUnknown(m) -} - -var xxx_messageInfo_RequestEndBlock proto.InternalMessageInfo - -func (m *RequestEndBlock) GetHeight() int64 { - if m != nil { - return m.Height - } - return 0 -} - type RequestCommit struct { } @@ -971,7 +789,7 @@ func (m *RequestCommit) Reset() { *m = RequestCommit{} } func (m *RequestCommit) String() string { return proto.CompactTextString(m) } func (*RequestCommit) ProtoMessage() {} func (*RequestCommit) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{10} + return fileDescriptor_252557cfdd89a31a, []int{7} } func (m *RequestCommit) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1008,7 +826,7 @@ func (m *RequestListSnapshots) Reset() { *m = RequestListSnapshots{} } func (m *RequestListSnapshots) String() string { return proto.CompactTextString(m) } func (*RequestListSnapshots) ProtoMessage() {} func (*RequestListSnapshots) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{11} + return fileDescriptor_252557cfdd89a31a, []int{8} } func (m *RequestListSnapshots) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1047,7 +865,7 @@ func (m *RequestOfferSnapshot) Reset() { *m = RequestOfferSnapshot{} } func (m *RequestOfferSnapshot) String() string { return proto.CompactTextString(m) } func (*RequestOfferSnapshot) ProtoMessage() {} func (*RequestOfferSnapshot) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{12} + return fileDescriptor_252557cfdd89a31a, []int{9} } func (m *RequestOfferSnapshot) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1101,7 +919,7 @@ func (m *RequestLoadSnapshotChunk) Reset() { *m = RequestLoadSnapshotChu func (m *RequestLoadSnapshotChunk) String() string { return proto.CompactTextString(m) } func (*RequestLoadSnapshotChunk) ProtoMessage() {} func (*RequestLoadSnapshotChunk) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{13} + return fileDescriptor_252557cfdd89a31a, []int{10} } func (m *RequestLoadSnapshotChunk) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1162,7 +980,7 @@ func (m *RequestApplySnapshotChunk) Reset() { *m = RequestApplySnapshotC func (m *RequestApplySnapshotChunk) String() string { return proto.CompactTextString(m) } func (*RequestApplySnapshotChunk) ProtoMessage() {} func (*RequestApplySnapshotChunk) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{14} + return fileDescriptor_252557cfdd89a31a, []int{11} } func (m *RequestApplySnapshotChunk) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1231,7 +1049,7 @@ func (m *RequestPrepareProposal) Reset() { *m = RequestPrepareProposal{} func (m *RequestPrepareProposal) String() string { return proto.CompactTextString(m) } func (*RequestPrepareProposal) ProtoMessage() {} func (*RequestPrepareProposal) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{15} + return fileDescriptor_252557cfdd89a31a, []int{12} } func (m *RequestPrepareProposal) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1333,7 +1151,7 @@ func (m *RequestProcessProposal) Reset() { *m = RequestProcessProposal{} func (m *RequestProcessProposal) String() string { return proto.CompactTextString(m) } func (*RequestProcessProposal) ProtoMessage() {} func (*RequestProcessProposal) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{16} + return fileDescriptor_252557cfdd89a31a, []int{13} } func (m *RequestProcessProposal) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1418,6 +1236,108 @@ func (m *RequestProcessProposal) GetProposerAddress() []byte { return nil } +type RequestFinalizeBlock struct { + Txs [][]byte `protobuf:"bytes,1,rep,name=txs,proto3" json:"txs,omitempty"` + DecidedLastCommit CommitInfo `protobuf:"bytes,2,opt,name=decided_last_commit,json=decidedLastCommit,proto3" json:"decided_last_commit"` + Misbehavior []Misbehavior `protobuf:"bytes,3,rep,name=misbehavior,proto3" json:"misbehavior"` + // hash is the merkle root hash of the fields of the decided block. + Hash []byte `protobuf:"bytes,4,opt,name=hash,proto3" json:"hash,omitempty"` + Height int64 `protobuf:"varint,5,opt,name=height,proto3" json:"height,omitempty"` + Time time.Time `protobuf:"bytes,6,opt,name=time,proto3,stdtime" json:"time"` + NextValidatorsHash []byte `protobuf:"bytes,7,opt,name=next_validators_hash,json=nextValidatorsHash,proto3" json:"next_validators_hash,omitempty"` + // proposer_address is the address of the public key of the original proposer of the block. + ProposerAddress []byte `protobuf:"bytes,8,opt,name=proposer_address,json=proposerAddress,proto3" json:"proposer_address,omitempty"` +} + +func (m *RequestFinalizeBlock) Reset() { *m = RequestFinalizeBlock{} } +func (m *RequestFinalizeBlock) String() string { return proto.CompactTextString(m) } +func (*RequestFinalizeBlock) ProtoMessage() {} +func (*RequestFinalizeBlock) Descriptor() ([]byte, []int) { + return fileDescriptor_252557cfdd89a31a, []int{14} +} +func (m *RequestFinalizeBlock) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RequestFinalizeBlock) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RequestFinalizeBlock.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RequestFinalizeBlock) XXX_Merge(src proto.Message) { + xxx_messageInfo_RequestFinalizeBlock.Merge(m, src) +} +func (m *RequestFinalizeBlock) XXX_Size() int { + return m.Size() +} +func (m *RequestFinalizeBlock) XXX_DiscardUnknown() { + xxx_messageInfo_RequestFinalizeBlock.DiscardUnknown(m) +} + +var xxx_messageInfo_RequestFinalizeBlock proto.InternalMessageInfo + +func (m *RequestFinalizeBlock) GetTxs() [][]byte { + if m != nil { + return m.Txs + } + return nil +} + +func (m *RequestFinalizeBlock) GetDecidedLastCommit() CommitInfo { + if m != nil { + return m.DecidedLastCommit + } + return CommitInfo{} +} + +func (m *RequestFinalizeBlock) GetMisbehavior() []Misbehavior { + if m != nil { + return m.Misbehavior + } + return nil +} + +func (m *RequestFinalizeBlock) GetHash() []byte { + if m != nil { + return m.Hash + } + return nil +} + +func (m *RequestFinalizeBlock) GetHeight() int64 { + if m != nil { + return m.Height + } + return 0 +} + +func (m *RequestFinalizeBlock) GetTime() time.Time { + if m != nil { + return m.Time + } + return time.Time{} +} + +func (m *RequestFinalizeBlock) GetNextValidatorsHash() []byte { + if m != nil { + return m.NextValidatorsHash + } + return nil +} + +func (m *RequestFinalizeBlock) GetProposerAddress() []byte { + if m != nil { + return m.ProposerAddress + } + return nil +} + type Response struct { // Types that are valid to be assigned to Value: // @@ -1427,10 +1347,7 @@ type Response struct { // *Response_Info // *Response_InitChain // *Response_Query - // *Response_BeginBlock // *Response_CheckTx - // *Response_DeliverTx - // *Response_EndBlock // *Response_Commit // *Response_ListSnapshots // *Response_OfferSnapshot @@ -1438,6 +1355,7 @@ type Response struct { // *Response_ApplySnapshotChunk // *Response_PrepareProposal // *Response_ProcessProposal + // *Response_FinalizeBlock Value isResponse_Value `protobuf_oneof:"value"` } @@ -1445,7 +1363,7 @@ func (m *Response) Reset() { *m = Response{} } func (m *Response) String() string { return proto.CompactTextString(m) } func (*Response) ProtoMessage() {} func (*Response) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{17} + return fileDescriptor_252557cfdd89a31a, []int{15} } func (m *Response) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1498,18 +1416,9 @@ type Response_InitChain struct { type Response_Query struct { Query *ResponseQuery `protobuf:"bytes,7,opt,name=query,proto3,oneof" json:"query,omitempty"` } -type Response_BeginBlock struct { - BeginBlock *ResponseBeginBlock `protobuf:"bytes,8,opt,name=begin_block,json=beginBlock,proto3,oneof" json:"begin_block,omitempty"` -} type Response_CheckTx struct { CheckTx *ResponseCheckTx `protobuf:"bytes,9,opt,name=check_tx,json=checkTx,proto3,oneof" json:"check_tx,omitempty"` } -type Response_DeliverTx struct { - DeliverTx *ResponseDeliverTx `protobuf:"bytes,10,opt,name=deliver_tx,json=deliverTx,proto3,oneof" json:"deliver_tx,omitempty"` -} -type Response_EndBlock struct { - EndBlock *ResponseEndBlock `protobuf:"bytes,11,opt,name=end_block,json=endBlock,proto3,oneof" json:"end_block,omitempty"` -} type Response_Commit struct { Commit *ResponseCommit `protobuf:"bytes,12,opt,name=commit,proto3,oneof" json:"commit,omitempty"` } @@ -1531,6 +1440,9 @@ type Response_PrepareProposal struct { type Response_ProcessProposal struct { ProcessProposal *ResponseProcessProposal `protobuf:"bytes,18,opt,name=process_proposal,json=processProposal,proto3,oneof" json:"process_proposal,omitempty"` } +type Response_FinalizeBlock struct { + FinalizeBlock *ResponseFinalizeBlock `protobuf:"bytes,21,opt,name=finalize_block,json=finalizeBlock,proto3,oneof" json:"finalize_block,omitempty"` +} func (*Response_Exception) isResponse_Value() {} func (*Response_Echo) isResponse_Value() {} @@ -1538,10 +1450,7 @@ func (*Response_Flush) isResponse_Value() {} func (*Response_Info) isResponse_Value() {} func (*Response_InitChain) isResponse_Value() {} func (*Response_Query) isResponse_Value() {} -func (*Response_BeginBlock) isResponse_Value() {} func (*Response_CheckTx) isResponse_Value() {} -func (*Response_DeliverTx) isResponse_Value() {} -func (*Response_EndBlock) isResponse_Value() {} func (*Response_Commit) isResponse_Value() {} func (*Response_ListSnapshots) isResponse_Value() {} func (*Response_OfferSnapshot) isResponse_Value() {} @@ -1549,6 +1458,7 @@ func (*Response_LoadSnapshotChunk) isResponse_Value() {} func (*Response_ApplySnapshotChunk) isResponse_Value() {} func (*Response_PrepareProposal) isResponse_Value() {} func (*Response_ProcessProposal) isResponse_Value() {} +func (*Response_FinalizeBlock) isResponse_Value() {} func (m *Response) GetValue() isResponse_Value { if m != nil { @@ -1599,13 +1509,6 @@ func (m *Response) GetQuery() *ResponseQuery { return nil } -func (m *Response) GetBeginBlock() *ResponseBeginBlock { - if x, ok := m.GetValue().(*Response_BeginBlock); ok { - return x.BeginBlock - } - return nil -} - func (m *Response) GetCheckTx() *ResponseCheckTx { if x, ok := m.GetValue().(*Response_CheckTx); ok { return x.CheckTx @@ -1613,20 +1516,6 @@ func (m *Response) GetCheckTx() *ResponseCheckTx { return nil } -func (m *Response) GetDeliverTx() *ResponseDeliverTx { - if x, ok := m.GetValue().(*Response_DeliverTx); ok { - return x.DeliverTx - } - return nil -} - -func (m *Response) GetEndBlock() *ResponseEndBlock { - if x, ok := m.GetValue().(*Response_EndBlock); ok { - return x.EndBlock - } - return nil -} - func (m *Response) GetCommit() *ResponseCommit { if x, ok := m.GetValue().(*Response_Commit); ok { return x.Commit @@ -1676,6 +1565,13 @@ func (m *Response) GetProcessProposal() *ResponseProcessProposal { return nil } +func (m *Response) GetFinalizeBlock() *ResponseFinalizeBlock { + if x, ok := m.GetValue().(*Response_FinalizeBlock); ok { + return x.FinalizeBlock + } + return nil +} + // XXX_OneofWrappers is for the internal use of the proto package. func (*Response) XXX_OneofWrappers() []interface{} { return []interface{}{ @@ -1685,10 +1581,7 @@ func (*Response) XXX_OneofWrappers() []interface{} { (*Response_Info)(nil), (*Response_InitChain)(nil), (*Response_Query)(nil), - (*Response_BeginBlock)(nil), (*Response_CheckTx)(nil), - (*Response_DeliverTx)(nil), - (*Response_EndBlock)(nil), (*Response_Commit)(nil), (*Response_ListSnapshots)(nil), (*Response_OfferSnapshot)(nil), @@ -1696,6 +1589,7 @@ func (*Response) XXX_OneofWrappers() []interface{} { (*Response_ApplySnapshotChunk)(nil), (*Response_PrepareProposal)(nil), (*Response_ProcessProposal)(nil), + (*Response_FinalizeBlock)(nil), } } @@ -1708,7 +1602,7 @@ func (m *ResponseException) Reset() { *m = ResponseException{} } func (m *ResponseException) String() string { return proto.CompactTextString(m) } func (*ResponseException) ProtoMessage() {} func (*ResponseException) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{18} + return fileDescriptor_252557cfdd89a31a, []int{16} } func (m *ResponseException) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1752,7 +1646,7 @@ func (m *ResponseEcho) Reset() { *m = ResponseEcho{} } func (m *ResponseEcho) String() string { return proto.CompactTextString(m) } func (*ResponseEcho) ProtoMessage() {} func (*ResponseEcho) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{19} + return fileDescriptor_252557cfdd89a31a, []int{17} } func (m *ResponseEcho) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1795,7 +1689,7 @@ func (m *ResponseFlush) Reset() { *m = ResponseFlush{} } func (m *ResponseFlush) String() string { return proto.CompactTextString(m) } func (*ResponseFlush) ProtoMessage() {} func (*ResponseFlush) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{20} + return fileDescriptor_252557cfdd89a31a, []int{18} } func (m *ResponseFlush) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1836,7 +1730,7 @@ func (m *ResponseInfo) Reset() { *m = ResponseInfo{} } func (m *ResponseInfo) String() string { return proto.CompactTextString(m) } func (*ResponseInfo) ProtoMessage() {} func (*ResponseInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{21} + return fileDescriptor_252557cfdd89a31a, []int{19} } func (m *ResponseInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1910,7 +1804,7 @@ func (m *ResponseInitChain) Reset() { *m = ResponseInitChain{} } func (m *ResponseInitChain) String() string { return proto.CompactTextString(m) } func (*ResponseInitChain) ProtoMessage() {} func (*ResponseInitChain) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{22} + return fileDescriptor_252557cfdd89a31a, []int{20} } func (m *ResponseInitChain) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1977,7 +1871,7 @@ func (m *ResponseQuery) Reset() { *m = ResponseQuery{} } func (m *ResponseQuery) String() string { return proto.CompactTextString(m) } func (*ResponseQuery) ProtoMessage() {} func (*ResponseQuery) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{23} + return fileDescriptor_252557cfdd89a31a, []int{21} } func (m *ResponseQuery) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2069,50 +1963,6 @@ func (m *ResponseQuery) GetCodespace() string { return "" } -type ResponseBeginBlock struct { - Events []Event `protobuf:"bytes,1,rep,name=events,proto3" json:"events,omitempty"` -} - -func (m *ResponseBeginBlock) Reset() { *m = ResponseBeginBlock{} } -func (m *ResponseBeginBlock) String() string { return proto.CompactTextString(m) } -func (*ResponseBeginBlock) ProtoMessage() {} -func (*ResponseBeginBlock) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{24} -} -func (m *ResponseBeginBlock) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ResponseBeginBlock) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ResponseBeginBlock.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *ResponseBeginBlock) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResponseBeginBlock.Merge(m, src) -} -func (m *ResponseBeginBlock) XXX_Size() int { - return m.Size() -} -func (m *ResponseBeginBlock) XXX_DiscardUnknown() { - xxx_messageInfo_ResponseBeginBlock.DiscardUnknown(m) -} - -var xxx_messageInfo_ResponseBeginBlock proto.InternalMessageInfo - -func (m *ResponseBeginBlock) GetEvents() []Event { - if m != nil { - return m.Events - } - return nil -} - type ResponseCheckTx struct { Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` @@ -2133,7 +1983,7 @@ func (m *ResponseCheckTx) Reset() { *m = ResponseCheckTx{} } func (m *ResponseCheckTx) String() string { return proto.CompactTextString(m) } func (*ResponseCheckTx) ProtoMessage() {} func (*ResponseCheckTx) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{25} + return fileDescriptor_252557cfdd89a31a, []int{22} } func (m *ResponseCheckTx) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2239,177 +2089,15 @@ func (m *ResponseCheckTx) GetMempoolError() string { return "" } -type ResponseDeliverTx struct { - Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` - Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` - Log string `protobuf:"bytes,3,opt,name=log,proto3" json:"log,omitempty"` - Info string `protobuf:"bytes,4,opt,name=info,proto3" json:"info,omitempty"` - GasWanted int64 `protobuf:"varint,5,opt,name=gas_wanted,proto3" json:"gas_wanted,omitempty"` - GasUsed int64 `protobuf:"varint,6,opt,name=gas_used,proto3" json:"gas_used,omitempty"` - Events []Event `protobuf:"bytes,7,rep,name=events,proto3" json:"events,omitempty"` - Codespace string `protobuf:"bytes,8,opt,name=codespace,proto3" json:"codespace,omitempty"` -} - -func (m *ResponseDeliverTx) Reset() { *m = ResponseDeliverTx{} } -func (m *ResponseDeliverTx) String() string { return proto.CompactTextString(m) } -func (*ResponseDeliverTx) ProtoMessage() {} -func (*ResponseDeliverTx) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{26} -} -func (m *ResponseDeliverTx) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ResponseDeliverTx) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ResponseDeliverTx.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *ResponseDeliverTx) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResponseDeliverTx.Merge(m, src) -} -func (m *ResponseDeliverTx) XXX_Size() int { - return m.Size() -} -func (m *ResponseDeliverTx) XXX_DiscardUnknown() { - xxx_messageInfo_ResponseDeliverTx.DiscardUnknown(m) -} - -var xxx_messageInfo_ResponseDeliverTx proto.InternalMessageInfo - -func (m *ResponseDeliverTx) GetCode() uint32 { - if m != nil { - return m.Code - } - return 0 -} - -func (m *ResponseDeliverTx) GetData() []byte { - if m != nil { - return m.Data - } - return nil -} - -func (m *ResponseDeliverTx) GetLog() string { - if m != nil { - return m.Log - } - return "" -} - -func (m *ResponseDeliverTx) GetInfo() string { - if m != nil { - return m.Info - } - return "" -} - -func (m *ResponseDeliverTx) GetGasWanted() int64 { - if m != nil { - return m.GasWanted - } - return 0 -} - -func (m *ResponseDeliverTx) GetGasUsed() int64 { - if m != nil { - return m.GasUsed - } - return 0 -} - -func (m *ResponseDeliverTx) GetEvents() []Event { - if m != nil { - return m.Events - } - return nil -} - -func (m *ResponseDeliverTx) GetCodespace() string { - if m != nil { - return m.Codespace - } - return "" -} - -type ResponseEndBlock struct { - ValidatorUpdates []ValidatorUpdate `protobuf:"bytes,1,rep,name=validator_updates,json=validatorUpdates,proto3" json:"validator_updates"` - ConsensusParamUpdates *types1.ConsensusParams `protobuf:"bytes,2,opt,name=consensus_param_updates,json=consensusParamUpdates,proto3" json:"consensus_param_updates,omitempty"` - Events []Event `protobuf:"bytes,3,rep,name=events,proto3" json:"events,omitempty"` -} - -func (m *ResponseEndBlock) Reset() { *m = ResponseEndBlock{} } -func (m *ResponseEndBlock) String() string { return proto.CompactTextString(m) } -func (*ResponseEndBlock) ProtoMessage() {} -func (*ResponseEndBlock) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{27} -} -func (m *ResponseEndBlock) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ResponseEndBlock) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ResponseEndBlock.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *ResponseEndBlock) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResponseEndBlock.Merge(m, src) -} -func (m *ResponseEndBlock) XXX_Size() int { - return m.Size() -} -func (m *ResponseEndBlock) XXX_DiscardUnknown() { - xxx_messageInfo_ResponseEndBlock.DiscardUnknown(m) -} - -var xxx_messageInfo_ResponseEndBlock proto.InternalMessageInfo - -func (m *ResponseEndBlock) GetValidatorUpdates() []ValidatorUpdate { - if m != nil { - return m.ValidatorUpdates - } - return nil -} - -func (m *ResponseEndBlock) GetConsensusParamUpdates() *types1.ConsensusParams { - if m != nil { - return m.ConsensusParamUpdates - } - return nil -} - -func (m *ResponseEndBlock) GetEvents() []Event { - if m != nil { - return m.Events - } - return nil -} - type ResponseCommit struct { - // reserve 1 - Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` - RetainHeight int64 `protobuf:"varint,3,opt,name=retain_height,json=retainHeight,proto3" json:"retain_height,omitempty"` + RetainHeight int64 `protobuf:"varint,3,opt,name=retain_height,json=retainHeight,proto3" json:"retain_height,omitempty"` } func (m *ResponseCommit) Reset() { *m = ResponseCommit{} } func (m *ResponseCommit) String() string { return proto.CompactTextString(m) } func (*ResponseCommit) ProtoMessage() {} func (*ResponseCommit) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{28} + return fileDescriptor_252557cfdd89a31a, []int{23} } func (m *ResponseCommit) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2438,13 +2126,6 @@ func (m *ResponseCommit) XXX_DiscardUnknown() { var xxx_messageInfo_ResponseCommit proto.InternalMessageInfo -func (m *ResponseCommit) GetData() []byte { - if m != nil { - return m.Data - } - return nil -} - func (m *ResponseCommit) GetRetainHeight() int64 { if m != nil { return m.RetainHeight @@ -2460,7 +2141,7 @@ func (m *ResponseListSnapshots) Reset() { *m = ResponseListSnapshots{} } func (m *ResponseListSnapshots) String() string { return proto.CompactTextString(m) } func (*ResponseListSnapshots) ProtoMessage() {} func (*ResponseListSnapshots) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{29} + return fileDescriptor_252557cfdd89a31a, []int{24} } func (m *ResponseListSnapshots) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2504,7 +2185,7 @@ func (m *ResponseOfferSnapshot) Reset() { *m = ResponseOfferSnapshot{} } func (m *ResponseOfferSnapshot) String() string { return proto.CompactTextString(m) } func (*ResponseOfferSnapshot) ProtoMessage() {} func (*ResponseOfferSnapshot) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{30} + return fileDescriptor_252557cfdd89a31a, []int{25} } func (m *ResponseOfferSnapshot) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2548,7 +2229,7 @@ func (m *ResponseLoadSnapshotChunk) Reset() { *m = ResponseLoadSnapshotC func (m *ResponseLoadSnapshotChunk) String() string { return proto.CompactTextString(m) } func (*ResponseLoadSnapshotChunk) ProtoMessage() {} func (*ResponseLoadSnapshotChunk) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{31} + return fileDescriptor_252557cfdd89a31a, []int{26} } func (m *ResponseLoadSnapshotChunk) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2594,7 +2275,7 @@ func (m *ResponseApplySnapshotChunk) Reset() { *m = ResponseApplySnapsho func (m *ResponseApplySnapshotChunk) String() string { return proto.CompactTextString(m) } func (*ResponseApplySnapshotChunk) ProtoMessage() {} func (*ResponseApplySnapshotChunk) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{32} + return fileDescriptor_252557cfdd89a31a, []int{27} } func (m *ResponseApplySnapshotChunk) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2652,7 +2333,7 @@ func (m *ResponsePrepareProposal) Reset() { *m = ResponsePrepareProposal func (m *ResponsePrepareProposal) String() string { return proto.CompactTextString(m) } func (*ResponsePrepareProposal) ProtoMessage() {} func (*ResponsePrepareProposal) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{33} + return fileDescriptor_252557cfdd89a31a, []int{28} } func (m *ResponsePrepareProposal) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2696,7 +2377,7 @@ func (m *ResponseProcessProposal) Reset() { *m = ResponseProcessProposal func (m *ResponseProcessProposal) String() string { return proto.CompactTextString(m) } func (*ResponseProcessProposal) ProtoMessage() {} func (*ResponseProcessProposal) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{34} + return fileDescriptor_252557cfdd89a31a, []int{29} } func (m *ResponseProcessProposal) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2732,6 +2413,89 @@ func (m *ResponseProcessProposal) GetStatus() ResponseProcessProposal_ProposalSt return ResponseProcessProposal_UNKNOWN } +type ResponseFinalizeBlock struct { + // set of block events emmitted as part of executing the block + Events []Event `protobuf:"bytes,1,rep,name=events,proto3" json:"events,omitempty"` + // the result of executing each transaction including the events + // the particular transction emitted. This should match the order + // of the transactions delivered in the block itself + TxResults []*ExecTxResult `protobuf:"bytes,2,rep,name=tx_results,json=txResults,proto3" json:"tx_results,omitempty"` + // a list of updates to the validator set. These will reflect the validator set at current height + 2. + ValidatorUpdates []ValidatorUpdate `protobuf:"bytes,3,rep,name=validator_updates,json=validatorUpdates,proto3" json:"validator_updates"` + // updates to the consensus params, if any. + ConsensusParamUpdates *types1.ConsensusParams `protobuf:"bytes,4,opt,name=consensus_param_updates,json=consensusParamUpdates,proto3" json:"consensus_param_updates,omitempty"` + // agreed_app_data is the bytes that all nodes reach consensus upon in the following height. It is often the hash of the applications' state which can be used to confirm that execution of the transactions was deterministic. + AgreedAppData []byte `protobuf:"bytes,5,opt,name=agreed_app_data,json=agreedAppData,proto3" json:"agreed_app_data,omitempty"` +} + +func (m *ResponseFinalizeBlock) Reset() { *m = ResponseFinalizeBlock{} } +func (m *ResponseFinalizeBlock) String() string { return proto.CompactTextString(m) } +func (*ResponseFinalizeBlock) ProtoMessage() {} +func (*ResponseFinalizeBlock) Descriptor() ([]byte, []int) { + return fileDescriptor_252557cfdd89a31a, []int{30} +} +func (m *ResponseFinalizeBlock) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResponseFinalizeBlock) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ResponseFinalizeBlock.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ResponseFinalizeBlock) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResponseFinalizeBlock.Merge(m, src) +} +func (m *ResponseFinalizeBlock) XXX_Size() int { + return m.Size() +} +func (m *ResponseFinalizeBlock) XXX_DiscardUnknown() { + xxx_messageInfo_ResponseFinalizeBlock.DiscardUnknown(m) +} + +var xxx_messageInfo_ResponseFinalizeBlock proto.InternalMessageInfo + +func (m *ResponseFinalizeBlock) GetEvents() []Event { + if m != nil { + return m.Events + } + return nil +} + +func (m *ResponseFinalizeBlock) GetTxResults() []*ExecTxResult { + if m != nil { + return m.TxResults + } + return nil +} + +func (m *ResponseFinalizeBlock) GetValidatorUpdates() []ValidatorUpdate { + if m != nil { + return m.ValidatorUpdates + } + return nil +} + +func (m *ResponseFinalizeBlock) GetConsensusParamUpdates() *types1.ConsensusParams { + if m != nil { + return m.ConsensusParamUpdates + } + return nil +} + +func (m *ResponseFinalizeBlock) GetAgreedAppData() []byte { + if m != nil { + return m.AgreedAppData + } + return nil +} + type CommitInfo struct { Round int32 `protobuf:"varint,1,opt,name=round,proto3" json:"round,omitempty"` Votes []VoteInfo `protobuf:"bytes,2,rep,name=votes,proto3" json:"votes"` @@ -2741,7 +2505,7 @@ func (m *CommitInfo) Reset() { *m = CommitInfo{} } func (m *CommitInfo) String() string { return proto.CompactTextString(m) } func (*CommitInfo) ProtoMessage() {} func (*CommitInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{35} + return fileDescriptor_252557cfdd89a31a, []int{31} } func (m *CommitInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2796,7 +2560,7 @@ func (m *ExtendedCommitInfo) Reset() { *m = ExtendedCommitInfo{} } func (m *ExtendedCommitInfo) String() string { return proto.CompactTextString(m) } func (*ExtendedCommitInfo) ProtoMessage() {} func (*ExtendedCommitInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{36} + return fileDescriptor_252557cfdd89a31a, []int{32} } func (m *ExtendedCommitInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2851,7 +2615,7 @@ func (m *Event) Reset() { *m = Event{} } func (m *Event) String() string { return proto.CompactTextString(m) } func (*Event) ProtoMessage() {} func (*Event) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{37} + return fileDescriptor_252557cfdd89a31a, []int{33} } func (m *Event) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2905,7 +2669,7 @@ func (m *EventAttribute) Reset() { *m = EventAttribute{} } func (m *EventAttribute) String() string { return proto.CompactTextString(m) } func (*EventAttribute) ProtoMessage() {} func (*EventAttribute) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{38} + return fileDescriptor_252557cfdd89a31a, []int{34} } func (m *EventAttribute) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2955,21 +2719,124 @@ func (m *EventAttribute) GetIndex() bool { return false } +// ExecTxResult contains results of executing one individual transaction. +// +// * Its structure is equivalent to #ResponseDeliverTx which will be deprecated/deleted +type ExecTxResult struct { + Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` + Log string `protobuf:"bytes,3,opt,name=log,proto3" json:"log,omitempty"` + Info string `protobuf:"bytes,4,opt,name=info,proto3" json:"info,omitempty"` + GasWanted int64 `protobuf:"varint,5,opt,name=gas_wanted,json=gasWanted,proto3" json:"gas_wanted,omitempty"` + GasUsed int64 `protobuf:"varint,6,opt,name=gas_used,json=gasUsed,proto3" json:"gas_used,omitempty"` + Events []Event `protobuf:"bytes,7,rep,name=events,proto3" json:"events,omitempty"` + Codespace string `protobuf:"bytes,8,opt,name=codespace,proto3" json:"codespace,omitempty"` +} + +func (m *ExecTxResult) Reset() { *m = ExecTxResult{} } +func (m *ExecTxResult) String() string { return proto.CompactTextString(m) } +func (*ExecTxResult) ProtoMessage() {} +func (*ExecTxResult) Descriptor() ([]byte, []int) { + return fileDescriptor_252557cfdd89a31a, []int{35} +} +func (m *ExecTxResult) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ExecTxResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ExecTxResult.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ExecTxResult) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecTxResult.Merge(m, src) +} +func (m *ExecTxResult) XXX_Size() int { + return m.Size() +} +func (m *ExecTxResult) XXX_DiscardUnknown() { + xxx_messageInfo_ExecTxResult.DiscardUnknown(m) +} + +var xxx_messageInfo_ExecTxResult proto.InternalMessageInfo + +func (m *ExecTxResult) GetCode() uint32 { + if m != nil { + return m.Code + } + return 0 +} + +func (m *ExecTxResult) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +func (m *ExecTxResult) GetLog() string { + if m != nil { + return m.Log + } + return "" +} + +func (m *ExecTxResult) GetInfo() string { + if m != nil { + return m.Info + } + return "" +} + +func (m *ExecTxResult) GetGasWanted() int64 { + if m != nil { + return m.GasWanted + } + return 0 +} + +func (m *ExecTxResult) GetGasUsed() int64 { + if m != nil { + return m.GasUsed + } + return 0 +} + +func (m *ExecTxResult) GetEvents() []Event { + if m != nil { + return m.Events + } + return nil +} + +func (m *ExecTxResult) GetCodespace() string { + if m != nil { + return m.Codespace + } + return "" +} + // TxResult contains results of executing the transaction. // // One usage is indexing transaction results. type TxResult struct { - Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"` - Index uint32 `protobuf:"varint,2,opt,name=index,proto3" json:"index,omitempty"` - Tx []byte `protobuf:"bytes,3,opt,name=tx,proto3" json:"tx,omitempty"` - Result ResponseDeliverTx `protobuf:"bytes,4,opt,name=result,proto3" json:"result"` + Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"` + Index uint32 `protobuf:"varint,2,opt,name=index,proto3" json:"index,omitempty"` + Tx []byte `protobuf:"bytes,3,opt,name=tx,proto3" json:"tx,omitempty"` + Result ExecTxResult `protobuf:"bytes,4,opt,name=result,proto3" json:"result"` } func (m *TxResult) Reset() { *m = TxResult{} } func (m *TxResult) String() string { return proto.CompactTextString(m) } func (*TxResult) ProtoMessage() {} func (*TxResult) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{39} + return fileDescriptor_252557cfdd89a31a, []int{36} } func (m *TxResult) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3019,11 +2886,11 @@ func (m *TxResult) GetTx() []byte { return nil } -func (m *TxResult) GetResult() ResponseDeliverTx { +func (m *TxResult) GetResult() ExecTxResult { if m != nil { return m.Result } - return ResponseDeliverTx{} + return ExecTxResult{} } // Validator @@ -3037,7 +2904,7 @@ func (m *Validator) Reset() { *m = Validator{} } func (m *Validator) String() string { return proto.CompactTextString(m) } func (*Validator) ProtoMessage() {} func (*Validator) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{40} + return fileDescriptor_252557cfdd89a31a, []int{37} } func (m *Validator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3090,7 +2957,7 @@ func (m *ValidatorUpdate) Reset() { *m = ValidatorUpdate{} } func (m *ValidatorUpdate) String() string { return proto.CompactTextString(m) } func (*ValidatorUpdate) ProtoMessage() {} func (*ValidatorUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{41} + return fileDescriptor_252557cfdd89a31a, []int{38} } func (m *ValidatorUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3143,7 +3010,7 @@ func (m *VoteInfo) Reset() { *m = VoteInfo{} } func (m *VoteInfo) String() string { return proto.CompactTextString(m) } func (*VoteInfo) ProtoMessage() {} func (*VoteInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{42} + return fileDescriptor_252557cfdd89a31a, []int{39} } func (m *VoteInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3196,7 +3063,7 @@ func (m *ExtendedVoteInfo) Reset() { *m = ExtendedVoteInfo{} } func (m *ExtendedVoteInfo) String() string { return proto.CompactTextString(m) } func (*ExtendedVoteInfo) ProtoMessage() {} func (*ExtendedVoteInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{43} + return fileDescriptor_252557cfdd89a31a, []int{40} } func (m *ExtendedVoteInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3264,7 +3131,7 @@ func (m *Misbehavior) Reset() { *m = Misbehavior{} } func (m *Misbehavior) String() string { return proto.CompactTextString(m) } func (*Misbehavior) ProtoMessage() {} func (*Misbehavior) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{44} + return fileDescriptor_252557cfdd89a31a, []int{41} } func (m *Misbehavior) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3340,7 +3207,7 @@ func (m *Snapshot) Reset() { *m = Snapshot{} } func (m *Snapshot) String() string { return proto.CompactTextString(m) } func (*Snapshot) ProtoMessage() {} func (*Snapshot) Descriptor() ([]byte, []int) { - return fileDescriptor_252557cfdd89a31a, []int{45} + return fileDescriptor_252557cfdd89a31a, []int{42} } func (m *Snapshot) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3416,10 +3283,7 @@ func init() { proto.RegisterType((*RequestInfo)(nil), "tendermint.abci.RequestInfo") proto.RegisterType((*RequestInitChain)(nil), "tendermint.abci.RequestInitChain") proto.RegisterType((*RequestQuery)(nil), "tendermint.abci.RequestQuery") - proto.RegisterType((*RequestBeginBlock)(nil), "tendermint.abci.RequestBeginBlock") proto.RegisterType((*RequestCheckTx)(nil), "tendermint.abci.RequestCheckTx") - proto.RegisterType((*RequestDeliverTx)(nil), "tendermint.abci.RequestDeliverTx") - proto.RegisterType((*RequestEndBlock)(nil), "tendermint.abci.RequestEndBlock") proto.RegisterType((*RequestCommit)(nil), "tendermint.abci.RequestCommit") proto.RegisterType((*RequestListSnapshots)(nil), "tendermint.abci.RequestListSnapshots") proto.RegisterType((*RequestOfferSnapshot)(nil), "tendermint.abci.RequestOfferSnapshot") @@ -3427,6 +3291,7 @@ func init() { proto.RegisterType((*RequestApplySnapshotChunk)(nil), "tendermint.abci.RequestApplySnapshotChunk") proto.RegisterType((*RequestPrepareProposal)(nil), "tendermint.abci.RequestPrepareProposal") proto.RegisterType((*RequestProcessProposal)(nil), "tendermint.abci.RequestProcessProposal") + proto.RegisterType((*RequestFinalizeBlock)(nil), "tendermint.abci.RequestFinalizeBlock") proto.RegisterType((*Response)(nil), "tendermint.abci.Response") proto.RegisterType((*ResponseException)(nil), "tendermint.abci.ResponseException") proto.RegisterType((*ResponseEcho)(nil), "tendermint.abci.ResponseEcho") @@ -3434,10 +3299,7 @@ func init() { proto.RegisterType((*ResponseInfo)(nil), "tendermint.abci.ResponseInfo") proto.RegisterType((*ResponseInitChain)(nil), "tendermint.abci.ResponseInitChain") proto.RegisterType((*ResponseQuery)(nil), "tendermint.abci.ResponseQuery") - proto.RegisterType((*ResponseBeginBlock)(nil), "tendermint.abci.ResponseBeginBlock") proto.RegisterType((*ResponseCheckTx)(nil), "tendermint.abci.ResponseCheckTx") - proto.RegisterType((*ResponseDeliverTx)(nil), "tendermint.abci.ResponseDeliverTx") - proto.RegisterType((*ResponseEndBlock)(nil), "tendermint.abci.ResponseEndBlock") proto.RegisterType((*ResponseCommit)(nil), "tendermint.abci.ResponseCommit") proto.RegisterType((*ResponseListSnapshots)(nil), "tendermint.abci.ResponseListSnapshots") proto.RegisterType((*ResponseOfferSnapshot)(nil), "tendermint.abci.ResponseOfferSnapshot") @@ -3445,10 +3307,12 @@ func init() { proto.RegisterType((*ResponseApplySnapshotChunk)(nil), "tendermint.abci.ResponseApplySnapshotChunk") proto.RegisterType((*ResponsePrepareProposal)(nil), "tendermint.abci.ResponsePrepareProposal") proto.RegisterType((*ResponseProcessProposal)(nil), "tendermint.abci.ResponseProcessProposal") + proto.RegisterType((*ResponseFinalizeBlock)(nil), "tendermint.abci.ResponseFinalizeBlock") proto.RegisterType((*CommitInfo)(nil), "tendermint.abci.CommitInfo") proto.RegisterType((*ExtendedCommitInfo)(nil), "tendermint.abci.ExtendedCommitInfo") proto.RegisterType((*Event)(nil), "tendermint.abci.Event") proto.RegisterType((*EventAttribute)(nil), "tendermint.abci.EventAttribute") + proto.RegisterType((*ExecTxResult)(nil), "tendermint.abci.ExecTxResult") proto.RegisterType((*TxResult)(nil), "tendermint.abci.TxResult") proto.RegisterType((*Validator)(nil), "tendermint.abci.Validator") proto.RegisterType((*ValidatorUpdate)(nil), "tendermint.abci.ValidatorUpdate") @@ -3461,195 +3325,192 @@ func init() { func init() { proto.RegisterFile("tendermint/abci/types.proto", fileDescriptor_252557cfdd89a31a) } var fileDescriptor_252557cfdd89a31a = []byte{ - // 3006 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x5a, 0x3b, 0x73, 0x23, 0xc7, - 0xf1, 0xc7, 0xfb, 0xd1, 0x78, 0x2d, 0xe7, 0xa8, 0x13, 0x0e, 0x3a, 0x91, 0xa7, 0xbd, 0x92, 0x74, - 0x77, 0x92, 0x48, 0xfd, 0xa9, 0xff, 0xe9, 0x51, 0xb2, 0x6c, 0x11, 0x38, 0x9c, 0x41, 0x91, 0x22, - 0xe9, 0x25, 0x78, 0x2a, 0xf9, 0x71, 0xab, 0x05, 0x76, 0x48, 0xac, 0x0e, 0xd8, 0x5d, 0xed, 0x0e, - 0x28, 0x50, 0xa1, 0x55, 0xae, 0x72, 0xa9, 0x1c, 0x28, 0x54, 0xa2, 0xc0, 0x81, 0xbf, 0x83, 0x23, - 0x47, 0x0e, 0x14, 0x38, 0x50, 0xe0, 0xc0, 0x81, 0x4b, 0x76, 0x49, 0x99, 0xbf, 0x80, 0x03, 0x07, - 0x76, 0xcd, 0x63, 0x5f, 0x00, 0x96, 0x00, 0x25, 0x97, 0xab, 0x5c, 0xce, 0x66, 0x7a, 0xbb, 0x7b, - 0x66, 0x7a, 0x66, 0xba, 0xfb, 0xd7, 0x3b, 0xf0, 0x04, 0xc1, 0xa6, 0x8e, 0x9d, 0x91, 0x61, 0x92, - 0x4d, 0xad, 0xd7, 0x37, 0x36, 0xc9, 0xb9, 0x8d, 0xdd, 0x0d, 0xdb, 0xb1, 0x88, 0x85, 0x6a, 0xc1, - 0xc7, 0x0d, 0xfa, 0xb1, 0xf1, 0x64, 0x88, 0xbb, 0xef, 0x9c, 0xdb, 0xc4, 0xda, 0xb4, 0x1d, 0xcb, - 0x3a, 0xe1, 0xfc, 0x8d, 0xeb, 0xa1, 0xcf, 0x4c, 0x4f, 0x58, 0x5b, 0xe4, 0xab, 0x10, 0x7e, 0x84, - 0xcf, 0xbd, 0xaf, 0x4f, 0xce, 0xc8, 0xda, 0x9a, 0xa3, 0x8d, 0xbc, 0xcf, 0xeb, 0xa7, 0x96, 0x75, - 0x3a, 0xc4, 0x9b, 0xac, 0xd7, 0x1b, 0x9f, 0x6c, 0x12, 0x63, 0x84, 0x5d, 0xa2, 0x8d, 0x6c, 0xc1, - 0xb0, 0x7a, 0x6a, 0x9d, 0x5a, 0xac, 0xb9, 0x49, 0x5b, 0x9c, 0x2a, 0xff, 0xb3, 0x00, 0x79, 0x05, - 0x7f, 0x30, 0xc6, 0x2e, 0x41, 0x5b, 0x90, 0xc1, 0xfd, 0x81, 0x55, 0x4f, 0xde, 0x48, 0xde, 0x2a, - 0x6d, 0x5d, 0xdf, 0x98, 0x5a, 0xdc, 0x86, 0xe0, 0x6b, 0xf7, 0x07, 0x56, 0x27, 0xa1, 0x30, 0x5e, - 0x74, 0x17, 0xb2, 0x27, 0xc3, 0xb1, 0x3b, 0xa8, 0xa7, 0x98, 0xd0, 0x93, 0x71, 0x42, 0xf7, 0x29, - 0x53, 0x27, 0xa1, 0x70, 0x6e, 0x3a, 0x94, 0x61, 0x9e, 0x58, 0xf5, 0xf4, 0xc5, 0x43, 0xed, 0x98, - 0x27, 0x6c, 0x28, 0xca, 0x8b, 0x9a, 0x00, 0x86, 0x69, 0x10, 0xb5, 0x3f, 0xd0, 0x0c, 0xb3, 0x9e, - 0x65, 0x92, 0x4f, 0xc5, 0x4b, 0x1a, 0xa4, 0x45, 0x19, 0x3b, 0x09, 0xa5, 0x68, 0x78, 0x1d, 0x3a, - 0xdd, 0x0f, 0xc6, 0xd8, 0x39, 0xaf, 0xe7, 0x2e, 0x9e, 0xee, 0x8f, 0x28, 0x13, 0x9d, 0x2e, 0xe3, - 0x46, 0x6d, 0x28, 0xf5, 0xf0, 0xa9, 0x61, 0xaa, 0xbd, 0xa1, 0xd5, 0x7f, 0x54, 0xcf, 0x33, 0x61, - 0x39, 0x4e, 0xb8, 0x49, 0x59, 0x9b, 0x94, 0xb3, 0x93, 0x50, 0xa0, 0xe7, 0xf7, 0xd0, 0xf7, 0xa0, - 0xd0, 0x1f, 0xe0, 0xfe, 0x23, 0x95, 0x4c, 0xea, 0x05, 0xa6, 0x63, 0x3d, 0x4e, 0x47, 0x8b, 0xf2, - 0x75, 0x27, 0x9d, 0x84, 0x92, 0xef, 0xf3, 0x26, 0x5d, 0xbf, 0x8e, 0x87, 0xc6, 0x19, 0x76, 0xa8, - 0x7c, 0xf1, 0xe2, 0xf5, 0xdf, 0xe3, 0x9c, 0x4c, 0x43, 0x51, 0xf7, 0x3a, 0xe8, 0x07, 0x50, 0xc4, - 0xa6, 0x2e, 0x96, 0x01, 0x4c, 0xc5, 0x8d, 0xd8, 0x7d, 0x36, 0x75, 0x6f, 0x11, 0x05, 0x2c, 0xda, - 0xe8, 0x55, 0xc8, 0xf5, 0xad, 0xd1, 0xc8, 0x20, 0xf5, 0x12, 0x93, 0x5e, 0x8b, 0x5d, 0x00, 0xe3, - 0xea, 0x24, 0x14, 0xc1, 0x8f, 0xf6, 0xa1, 0x3a, 0x34, 0x5c, 0xa2, 0xba, 0xa6, 0x66, 0xbb, 0x03, - 0x8b, 0xb8, 0xf5, 0x32, 0xd3, 0xf0, 0x74, 0x9c, 0x86, 0x3d, 0xc3, 0x25, 0x47, 0x1e, 0x73, 0x27, - 0xa1, 0x54, 0x86, 0x61, 0x02, 0xd5, 0x67, 0x9d, 0x9c, 0x60, 0xc7, 0x57, 0x58, 0xaf, 0x5c, 0xac, - 0xef, 0x80, 0x72, 0x7b, 0xf2, 0x54, 0x9f, 0x15, 0x26, 0xa0, 0x9f, 0xc0, 0x95, 0xa1, 0xa5, 0xe9, - 0xbe, 0x3a, 0xb5, 0x3f, 0x18, 0x9b, 0x8f, 0xea, 0x55, 0xa6, 0xf4, 0x76, 0xec, 0x24, 0x2d, 0x4d, - 0xf7, 0x54, 0xb4, 0xa8, 0x40, 0x27, 0xa1, 0xac, 0x0c, 0xa7, 0x89, 0xe8, 0x21, 0xac, 0x6a, 0xb6, - 0x3d, 0x3c, 0x9f, 0xd6, 0x5e, 0x63, 0xda, 0xef, 0xc4, 0x69, 0xdf, 0xa6, 0x32, 0xd3, 0xea, 0x91, - 0x36, 0x43, 0x45, 0x5d, 0x90, 0x6c, 0x07, 0xdb, 0x9a, 0x83, 0x55, 0xdb, 0xb1, 0x6c, 0xcb, 0xd5, - 0x86, 0x75, 0x89, 0xe9, 0x7e, 0x36, 0x4e, 0xf7, 0x21, 0xe7, 0x3f, 0x14, 0xec, 0x9d, 0x84, 0x52, - 0xb3, 0xa3, 0x24, 0xae, 0xd5, 0xea, 0x63, 0xd7, 0x0d, 0xb4, 0xae, 0x2c, 0xd2, 0xca, 0xf8, 0xa3, - 0x5a, 0x23, 0xa4, 0x66, 0x1e, 0xb2, 0x67, 0xda, 0x70, 0x8c, 0xdf, 0xca, 0x14, 0x32, 0x52, 0x56, - 0x7e, 0x16, 0x4a, 0x21, 0xc7, 0x82, 0xea, 0x90, 0x1f, 0x61, 0xd7, 0xd5, 0x4e, 0x31, 0xf3, 0x43, - 0x45, 0xc5, 0xeb, 0xca, 0x55, 0x28, 0x87, 0x9d, 0x89, 0xfc, 0x69, 0xd2, 0x97, 0xa4, 0x7e, 0x82, - 0x4a, 0x9e, 0x61, 0xc7, 0x35, 0x2c, 0xd3, 0x93, 0x14, 0x5d, 0x74, 0x13, 0x2a, 0xec, 0xc4, 0xab, - 0xde, 0x77, 0xea, 0xac, 0x32, 0x4a, 0x99, 0x11, 0x1f, 0x08, 0xa6, 0x75, 0x28, 0xd9, 0x5b, 0xb6, - 0xcf, 0x92, 0x66, 0x2c, 0x60, 0x6f, 0xd9, 0x1e, 0xc3, 0x53, 0x50, 0xa6, 0x2b, 0xf5, 0x39, 0x32, - 0x6c, 0x90, 0x12, 0xa5, 0x09, 0x16, 0xf9, 0x0f, 0x29, 0x90, 0xa6, 0x1d, 0x10, 0x7a, 0x15, 0x32, - 0xd4, 0x17, 0x0b, 0xb7, 0xda, 0xd8, 0xe0, 0x8e, 0x7a, 0xc3, 0x73, 0xd4, 0x1b, 0x5d, 0xcf, 0x51, - 0x37, 0x0b, 0x5f, 0x7c, 0xb5, 0x9e, 0xf8, 0xf4, 0x2f, 0xeb, 0x49, 0x85, 0x49, 0xa0, 0x6b, 0xd4, - 0x5f, 0x68, 0x86, 0xa9, 0x1a, 0x3a, 0x9b, 0x72, 0x91, 0x3a, 0x03, 0xcd, 0x30, 0x77, 0x74, 0xb4, - 0x07, 0x52, 0xdf, 0x32, 0x5d, 0x6c, 0xba, 0x63, 0x57, 0xe5, 0x81, 0x40, 0x38, 0xd3, 0x88, 0x4b, - 0xe0, 0xe1, 0xa5, 0xe5, 0x71, 0x1e, 0x32, 0x46, 0xa5, 0xd6, 0x8f, 0x12, 0xd0, 0x7d, 0x80, 0x33, - 0x6d, 0x68, 0xe8, 0x1a, 0xb1, 0x1c, 0xb7, 0x9e, 0xb9, 0x91, 0x9e, 0xeb, 0x17, 0x1e, 0x78, 0x2c, - 0xc7, 0xb6, 0xae, 0x11, 0xdc, 0xcc, 0xd0, 0xe9, 0x2a, 0x21, 0x49, 0xf4, 0x0c, 0xd4, 0x34, 0xdb, - 0x56, 0x5d, 0xa2, 0x11, 0xac, 0xf6, 0xce, 0x09, 0x76, 0x99, 0x9f, 0x2e, 0x2b, 0x15, 0xcd, 0xb6, - 0x8f, 0x28, 0xb5, 0x49, 0x89, 0xe8, 0x69, 0xa8, 0x52, 0x9f, 0x6c, 0x68, 0x43, 0x75, 0x80, 0x8d, - 0xd3, 0x01, 0x61, 0xfe, 0x38, 0xad, 0x54, 0x04, 0xb5, 0xc3, 0x88, 0xb2, 0xee, 0xef, 0x38, 0xf3, - 0xc7, 0x08, 0x41, 0x46, 0xd7, 0x88, 0xc6, 0x2c, 0x59, 0x56, 0x58, 0x9b, 0xd2, 0x6c, 0x8d, 0x0c, - 0x84, 0x7d, 0x58, 0x1b, 0x5d, 0x85, 0x9c, 0x50, 0x9b, 0x66, 0x6a, 0x45, 0x0f, 0xad, 0x42, 0xd6, - 0x76, 0xac, 0x33, 0xcc, 0xb6, 0xae, 0xa0, 0xf0, 0x8e, 0xfc, 0x71, 0x0a, 0x56, 0x66, 0x3c, 0x37, - 0xd5, 0x3b, 0xd0, 0xdc, 0x81, 0x37, 0x16, 0x6d, 0xa3, 0x97, 0xa9, 0x5e, 0x4d, 0xc7, 0x8e, 0x88, - 0x76, 0xf5, 0x59, 0x53, 0x77, 0xd8, 0x77, 0x61, 0x1a, 0xc1, 0x8d, 0x76, 0x41, 0x1a, 0x6a, 0x2e, - 0x51, 0xb9, 0x27, 0x54, 0x43, 0x91, 0xef, 0x89, 0x19, 0x23, 0x73, 0xbf, 0x49, 0x0f, 0xb4, 0x50, - 0x52, 0xa5, 0xa2, 0x01, 0x15, 0x1d, 0xc3, 0x6a, 0xef, 0xfc, 0x23, 0xcd, 0x24, 0x86, 0x89, 0xd5, - 0x99, 0x5d, 0x9b, 0x0d, 0xa5, 0x6f, 0x1b, 0x6e, 0x0f, 0x0f, 0xb4, 0x33, 0xc3, 0xf2, 0xa6, 0x75, - 0xc5, 0x97, 0xf7, 0x77, 0xd4, 0x95, 0x15, 0xa8, 0x46, 0x43, 0x0f, 0xaa, 0x42, 0x8a, 0x4c, 0xc4, - 0xfa, 0x53, 0x64, 0x82, 0x5e, 0x84, 0x0c, 0x5d, 0x23, 0x5b, 0x7b, 0x75, 0xce, 0x40, 0x42, 0xae, - 0x7b, 0x6e, 0x63, 0x85, 0x71, 0xca, 0xb2, 0x7f, 0x1b, 0xfc, 0x70, 0x34, 0xad, 0x55, 0xbe, 0x0d, - 0xb5, 0xa9, 0x78, 0x13, 0xda, 0xbe, 0x64, 0x78, 0xfb, 0xe4, 0x1a, 0x54, 0x22, 0xc1, 0x45, 0xbe, - 0x0a, 0xab, 0xf3, 0x62, 0x85, 0x3c, 0xf0, 0xe9, 0x11, 0x9f, 0x8f, 0xee, 0x42, 0xc1, 0x0f, 0x16, - 0xfc, 0x36, 0x5e, 0x9b, 0x59, 0x85, 0xc7, 0xac, 0xf8, 0xac, 0xf4, 0x1a, 0xd2, 0x53, 0xcd, 0x8e, - 0x43, 0x8a, 0x4d, 0x3c, 0xaf, 0xd9, 0x76, 0x47, 0x73, 0x07, 0xf2, 0x7b, 0x50, 0x8f, 0x0b, 0x04, - 0x53, 0xcb, 0xc8, 0xf8, 0xa7, 0xf0, 0x2a, 0xe4, 0x4e, 0x2c, 0x67, 0xa4, 0x11, 0xa6, 0xac, 0xa2, - 0x88, 0x1e, 0x3d, 0x9d, 0x3c, 0x28, 0xa4, 0x19, 0x99, 0x77, 0x64, 0x15, 0xae, 0xc5, 0x06, 0x03, - 0x2a, 0x62, 0x98, 0x3a, 0xe6, 0xf6, 0xac, 0x28, 0xbc, 0x13, 0x28, 0xe2, 0x93, 0xe5, 0x1d, 0x3a, - 0xac, 0xcb, 0xd6, 0xca, 0xf4, 0x17, 0x15, 0xd1, 0x93, 0x3f, 0x4b, 0xc3, 0xd5, 0xf9, 0x21, 0x01, - 0xdd, 0x80, 0xf2, 0x48, 0x9b, 0xa8, 0x64, 0x22, 0xee, 0x32, 0xdf, 0x0e, 0x18, 0x69, 0x93, 0xee, - 0x84, 0x5f, 0x64, 0x09, 0xd2, 0x64, 0xe2, 0xd6, 0x53, 0x37, 0xd2, 0xb7, 0xca, 0x0a, 0x6d, 0xa2, - 0x63, 0x58, 0x19, 0x5a, 0x7d, 0x6d, 0xa8, 0x86, 0x4e, 0xbc, 0x38, 0xec, 0x37, 0x67, 0x8c, 0xdd, - 0x9e, 0x30, 0x8a, 0x3e, 0x73, 0xe8, 0x6b, 0x4c, 0xc7, 0x9e, 0x7f, 0xf2, 0xd1, 0x3d, 0x28, 0x8d, - 0x82, 0x83, 0x7c, 0x89, 0xc3, 0x1e, 0x16, 0x0b, 0x6d, 0x49, 0x36, 0xe2, 0x18, 0x3c, 0x17, 0x9d, - 0xbb, 0xb4, 0x8b, 0x7e, 0x11, 0x56, 0x4d, 0x3c, 0x21, 0xa1, 0x8b, 0xc8, 0xcf, 0x49, 0x9e, 0x99, - 0x1e, 0xd1, 0x6f, 0xc1, 0x25, 0xa3, 0x47, 0x06, 0xdd, 0x66, 0x41, 0xd5, 0xb6, 0x5c, 0xec, 0xa8, - 0x9a, 0xae, 0x3b, 0xd8, 0x75, 0x59, 0x32, 0x58, 0x66, 0x91, 0x92, 0xd1, 0xb7, 0x39, 0x59, 0xfe, - 0x65, 0x78, 0x6b, 0x22, 0x41, 0xd4, 0x33, 0x7c, 0x32, 0x30, 0xfc, 0x11, 0xac, 0x0a, 0x79, 0x3d, - 0x62, 0xfb, 0xd4, 0xb2, 0x8e, 0x06, 0x79, 0xe2, 0xf1, 0x66, 0x4f, 0x7f, 0x3b, 0xb3, 0x7b, 0xbe, - 0x34, 0x13, 0xf2, 0xa5, 0xff, 0x65, 0x5b, 0xf1, 0xc7, 0x22, 0x14, 0x14, 0xec, 0xda, 0x34, 0x70, - 0xa2, 0x26, 0x14, 0xf1, 0xa4, 0x8f, 0x6d, 0xe2, 0xe5, 0x1a, 0xf3, 0xc1, 0x00, 0xe7, 0x6e, 0x7b, - 0x9c, 0x34, 0x13, 0xf7, 0xc5, 0xd0, 0x4b, 0x02, 0x6c, 0xc5, 0xe3, 0x26, 0x21, 0x1e, 0x46, 0x5b, - 0x2f, 0x7b, 0x68, 0x2b, 0x1d, 0x9b, 0x7c, 0x73, 0xa9, 0x29, 0xb8, 0xf5, 0x92, 0x80, 0x5b, 0x99, - 0x05, 0x83, 0x45, 0xf0, 0x56, 0x2b, 0x82, 0xb7, 0x72, 0x0b, 0x96, 0x19, 0x03, 0xb8, 0x5e, 0xf6, - 0x00, 0x57, 0x7e, 0xc1, 0x8c, 0xa7, 0x10, 0xd7, 0xfd, 0x28, 0xe2, 0x2a, 0xc4, 0x38, 0x10, 0x4f, - 0x3a, 0x16, 0x72, 0xbd, 0x11, 0x82, 0x5c, 0xc5, 0x58, 0xbc, 0xc3, 0x95, 0xcc, 0xc1, 0x5c, 0xad, - 0x08, 0xe6, 0x82, 0x05, 0x36, 0x88, 0x01, 0x5d, 0x6f, 0x86, 0x41, 0x57, 0x29, 0x16, 0xb7, 0x89, - 0xfd, 0x9e, 0x87, 0xba, 0x5e, 0xf3, 0x51, 0x57, 0x39, 0x16, 0x36, 0x8a, 0x35, 0x4c, 0xc3, 0xae, - 0x83, 0x19, 0xd8, 0xc5, 0x61, 0xd2, 0x33, 0xb1, 0x2a, 0x16, 0xe0, 0xae, 0x83, 0x19, 0xdc, 0x55, - 0x5d, 0xa0, 0x70, 0x01, 0xf0, 0xfa, 0xe9, 0x7c, 0xe0, 0x15, 0x0f, 0x8d, 0xc4, 0x34, 0x97, 0x43, - 0x5e, 0x6a, 0x0c, 0xf2, 0xe2, 0xe8, 0xe8, 0xb9, 0x58, 0xf5, 0x4b, 0x43, 0xaf, 0xe3, 0x39, 0xd0, - 0x8b, 0x83, 0xa4, 0x5b, 0xb1, 0xca, 0x97, 0xc0, 0x5e, 0xc7, 0x73, 0xb0, 0x17, 0x5a, 0xa8, 0xf6, - 0x32, 0xe0, 0x2b, 0x2b, 0xe5, 0xe4, 0xdb, 0x34, 0xf5, 0x9d, 0xf2, 0x53, 0x34, 0x7f, 0xc0, 0x8e, - 0x63, 0x39, 0x02, 0x46, 0xf1, 0x8e, 0x7c, 0x8b, 0x26, 0xe3, 0x81, 0x4f, 0xba, 0x00, 0xa8, 0xb1, - 0x3c, 0x2d, 0xe4, 0x87, 0xe4, 0xdf, 0x26, 0x03, 0x59, 0x96, 0xc3, 0x86, 0x13, 0xf9, 0xa2, 0x48, - 0xe4, 0x43, 0xf0, 0x2d, 0x15, 0x85, 0x6f, 0xeb, 0x50, 0xa2, 0xf9, 0xd7, 0x14, 0x32, 0xd3, 0x6c, - 0x1f, 0x99, 0xdd, 0x81, 0x15, 0x16, 0xf1, 0x38, 0xc8, 0x13, 0x61, 0x25, 0xc3, 0xc2, 0x4a, 0x8d, - 0x7e, 0xe0, 0x17, 0x8a, 0xc7, 0x97, 0x17, 0xe0, 0x4a, 0x88, 0xd7, 0xcf, 0xeb, 0x38, 0x4c, 0x91, - 0x7c, 0xee, 0x6d, 0x91, 0xe0, 0xfd, 0x3e, 0x19, 0x58, 0x28, 0x80, 0x74, 0xf3, 0xd0, 0x57, 0xf2, - 0xdf, 0x84, 0xbe, 0x52, 0xdf, 0x1a, 0x7d, 0x85, 0xf3, 0xd4, 0x74, 0x34, 0x4f, 0xfd, 0x7b, 0x32, - 0xd8, 0x13, 0x1f, 0x4b, 0xf5, 0x2d, 0x1d, 0x8b, 0xcc, 0x91, 0xb5, 0x69, 0x52, 0x31, 0xb4, 0x4e, - 0x45, 0x7e, 0x48, 0x9b, 0x94, 0xcb, 0x0f, 0x1c, 0x45, 0x11, 0x17, 0xfc, 0xa4, 0x93, 0x07, 0x6e, - 0x91, 0x74, 0x4a, 0x90, 0x7e, 0x84, 0x79, 0x5d, 0xad, 0xac, 0xd0, 0x26, 0xe5, 0x63, 0x47, 0x4d, - 0x04, 0x60, 0xde, 0x41, 0xaf, 0x42, 0x91, 0x55, 0x44, 0x55, 0xcb, 0x76, 0x85, 0x5b, 0x8f, 0xe4, - 0x26, 0xbc, 0xf0, 0xb9, 0x71, 0x48, 0x79, 0x0e, 0x6c, 0x57, 0x29, 0xd8, 0xa2, 0x15, 0xca, 0x18, - 0x8a, 0x91, 0x8c, 0xe1, 0x3a, 0x14, 0xe9, 0xec, 0x5d, 0x5b, 0xeb, 0x63, 0xe6, 0xa2, 0x8b, 0x4a, - 0x40, 0x90, 0x1f, 0x02, 0x9a, 0x0d, 0x12, 0xa8, 0x03, 0x39, 0x7c, 0x86, 0x4d, 0xc2, 0x33, 0xa8, - 0xd2, 0xd6, 0xd5, 0xd9, 0xd4, 0x94, 0x7e, 0x6e, 0xd6, 0xa9, 0x91, 0xff, 0xf6, 0xd5, 0xba, 0xc4, - 0xb9, 0x9f, 0xb7, 0x46, 0x06, 0xc1, 0x23, 0x9b, 0x9c, 0x2b, 0x42, 0x5e, 0xfe, 0x73, 0x8a, 0x02, - 0x98, 0x48, 0x00, 0x99, 0x6b, 0x5b, 0xef, 0xc8, 0xa7, 0x42, 0xd8, 0x75, 0x39, 0x7b, 0xaf, 0x01, - 0x9c, 0x6a, 0xae, 0xfa, 0xa1, 0x66, 0x12, 0xac, 0x0b, 0xa3, 0x87, 0x28, 0xa8, 0x01, 0x05, 0xda, - 0x1b, 0xbb, 0x58, 0x17, 0x30, 0xda, 0xef, 0x87, 0xd6, 0x99, 0xff, 0x6e, 0xeb, 0x8c, 0x5a, 0xb9, - 0x30, 0x65, 0xe5, 0x10, 0xb8, 0x28, 0x86, 0xc1, 0x05, 0x9d, 0x9b, 0xed, 0x18, 0x96, 0x63, 0x90, - 0x73, 0xb6, 0x35, 0x69, 0xc5, 0xef, 0xa3, 0x9b, 0x50, 0x19, 0xe1, 0x91, 0x6d, 0x59, 0x43, 0x95, - 0xbb, 0x9b, 0x12, 0x13, 0x2d, 0x0b, 0x62, 0x9b, 0x79, 0x9d, 0x5f, 0xa4, 0x82, 0xfb, 0x17, 0x80, - 0xc8, 0xff, 0x39, 0x03, 0xcb, 0xbf, 0x62, 0x95, 0xa5, 0x68, 0x8a, 0x80, 0x8e, 0x60, 0xc5, 0xbf, - 0xfe, 0xea, 0x98, 0xb9, 0x05, 0xef, 0x40, 0x2f, 0xeb, 0x3f, 0xa4, 0xb3, 0x28, 0xd9, 0x45, 0xef, - 0xc2, 0xe3, 0x53, 0xbe, 0xcd, 0x57, 0x9d, 0x5a, 0xd6, 0xc5, 0x3d, 0x16, 0x75, 0x71, 0x9e, 0xea, - 0xc0, 0x58, 0xe9, 0xef, 0x78, 0xeb, 0x76, 0xa0, 0x1a, 0xcd, 0x78, 0xe6, 0x6e, 0xff, 0x4d, 0xa8, - 0x38, 0x98, 0x68, 0x86, 0xa9, 0x46, 0xca, 0x41, 0x65, 0x4e, 0x14, 0x45, 0xa6, 0x43, 0x78, 0x6c, - 0x6e, 0xe6, 0x83, 0x5e, 0x81, 0x62, 0x90, 0x34, 0x71, 0xab, 0x5e, 0x50, 0x2e, 0x08, 0x78, 0xe5, - 0xdf, 0x25, 0x03, 0x95, 0xd1, 0x02, 0x44, 0x1b, 0x72, 0x0e, 0x76, 0xc7, 0x43, 0x5e, 0x12, 0xa8, - 0x6e, 0xbd, 0xb0, 0x5c, 0xce, 0x44, 0xa9, 0xe3, 0x21, 0x51, 0x84, 0xb0, 0xfc, 0x10, 0x72, 0x9c, - 0x82, 0x4a, 0x90, 0x3f, 0xde, 0xdf, 0xdd, 0x3f, 0x78, 0x67, 0x5f, 0x4a, 0x20, 0x80, 0xdc, 0x76, - 0xab, 0xd5, 0x3e, 0xec, 0x4a, 0x49, 0x54, 0x84, 0xec, 0x76, 0xf3, 0x40, 0xe9, 0x4a, 0x29, 0x4a, - 0x56, 0xda, 0x6f, 0xb5, 0x5b, 0x5d, 0x29, 0x8d, 0x56, 0xa0, 0xc2, 0xdb, 0xea, 0xfd, 0x03, 0xe5, - 0xed, 0xed, 0xae, 0x94, 0x09, 0x91, 0x8e, 0xda, 0xfb, 0xf7, 0xda, 0x8a, 0x94, 0x95, 0xff, 0x0f, - 0xae, 0xc5, 0x66, 0x59, 0x41, 0x75, 0x21, 0x19, 0xaa, 0x2e, 0xc8, 0x9f, 0xa5, 0xa0, 0x11, 0x9f, - 0x3a, 0xa1, 0xb7, 0xa6, 0x16, 0xbe, 0x75, 0x89, 0xbc, 0x6b, 0x6a, 0xf5, 0xe8, 0x69, 0xa8, 0x3a, - 0xf8, 0x04, 0x93, 0xfe, 0x80, 0xa7, 0x72, 0x3c, 0x64, 0x56, 0x94, 0x8a, 0xa0, 0x32, 0x21, 0x97, - 0xb3, 0xbd, 0x8f, 0xfb, 0x44, 0xe5, 0xbe, 0x88, 0x1f, 0xba, 0x22, 0x65, 0xa3, 0xd4, 0x23, 0x4e, - 0x94, 0xdf, 0xbb, 0x94, 0x2d, 0x8b, 0x90, 0x55, 0xda, 0x5d, 0xe5, 0x5d, 0x29, 0x8d, 0x10, 0x54, - 0x59, 0x53, 0x3d, 0xda, 0xdf, 0x3e, 0x3c, 0xea, 0x1c, 0x50, 0x5b, 0x5e, 0x81, 0x9a, 0x67, 0x4b, - 0x8f, 0x98, 0x95, 0x9f, 0x83, 0xc7, 0x63, 0xf2, 0xbe, 0x59, 0x14, 0x2f, 0xff, 0x3a, 0x19, 0xe6, - 0x8e, 0x62, 0xfe, 0x03, 0xc8, 0xb9, 0x44, 0x23, 0x63, 0x57, 0x18, 0xf1, 0x95, 0x65, 0x13, 0xc1, - 0x0d, 0xaf, 0x71, 0xc4, 0xc4, 0x15, 0xa1, 0x46, 0xbe, 0x0b, 0xd5, 0xe8, 0x97, 0x78, 0x1b, 0x04, - 0x87, 0x28, 0x25, 0xbf, 0x0b, 0x10, 0xaa, 0x47, 0xae, 0x42, 0xd6, 0xb1, 0xc6, 0xa6, 0xce, 0x26, - 0x95, 0x55, 0x78, 0x07, 0xdd, 0x85, 0xec, 0x99, 0xc5, 0x7d, 0xc6, 0xfc, 0x8b, 0xf3, 0xc0, 0x22, - 0x38, 0x54, 0x7c, 0xe0, 0xdc, 0xb2, 0x01, 0x68, 0xb6, 0x26, 0x14, 0x33, 0xc4, 0x1b, 0xd1, 0x21, - 0x9e, 0x8a, 0xad, 0x2e, 0xcd, 0x1f, 0xea, 0x23, 0xc8, 0x32, 0x6f, 0x43, 0x3d, 0x07, 0xab, 0x6b, - 0x8a, 0x64, 0x94, 0xb6, 0xd1, 0xcf, 0x00, 0x34, 0x42, 0x1c, 0xa3, 0x37, 0x0e, 0x06, 0x58, 0x9f, - 0xef, 0xad, 0xb6, 0x3d, 0xbe, 0xe6, 0x75, 0xe1, 0xb6, 0x56, 0x03, 0xd1, 0x90, 0xeb, 0x0a, 0x29, - 0x94, 0xf7, 0xa1, 0x1a, 0x95, 0xf5, 0xd2, 0x27, 0x3e, 0x87, 0x68, 0xfa, 0xc4, 0xb3, 0x61, 0x91, - 0x3e, 0xf9, 0xc9, 0x57, 0x9a, 0x97, 0xb0, 0x59, 0x47, 0xfe, 0x24, 0x09, 0x85, 0xee, 0x44, 0x9c, - 0xe3, 0x98, 0xf2, 0x69, 0x20, 0x9a, 0x0a, 0x17, 0x0b, 0x79, 0x3d, 0x36, 0xed, 0x57, 0x79, 0xdf, - 0xf4, 0x6f, 0x6a, 0x66, 0x59, 0xb4, 0xeb, 0x55, 0xbb, 0x85, 0x77, 0x7a, 0x1d, 0x8a, 0x7e, 0xac, - 0xa1, 0x59, 0xbd, 0x57, 0x59, 0x49, 0x8a, 0x94, 0x94, 0x77, 0x59, 0x31, 0xde, 0xfa, 0x50, 0x94, - 0x23, 0xd3, 0x0a, 0xef, 0xc8, 0x3a, 0xd4, 0xa6, 0x02, 0x15, 0x7a, 0x1d, 0xf2, 0xf6, 0xb8, 0xa7, - 0x7a, 0xe6, 0x99, 0xaa, 0x3f, 0x79, 0xf9, 0xe2, 0xb8, 0x37, 0x34, 0xfa, 0xbb, 0xf8, 0xdc, 0x9b, - 0x8c, 0x3d, 0xee, 0xed, 0x72, 0x2b, 0xf2, 0x51, 0x52, 0xe1, 0x51, 0xce, 0xa0, 0xe0, 0x1d, 0x0a, - 0xf4, 0x7d, 0x28, 0xfa, 0x31, 0xd0, 0xff, 0x47, 0x13, 0x1b, 0x3c, 0x85, 0xfa, 0x40, 0x84, 0x82, - 0x0f, 0xd7, 0x38, 0x35, 0xbd, 0xaa, 0x1b, 0x47, 0xf9, 0x29, 0xb6, 0x3b, 0x35, 0xfe, 0x61, 0xcf, - 0x03, 0x15, 0xf2, 0x6f, 0x92, 0x20, 0x4d, 0x9f, 0xca, 0xff, 0xe4, 0x04, 0xa8, 0x53, 0xa4, 0xa7, - 0x5f, 0xc5, 0x74, 0x12, 0x3e, 0x9a, 0x2a, 0x2b, 0x15, 0x4a, 0x6d, 0x7b, 0x44, 0xf9, 0xe3, 0x14, - 0x94, 0x42, 0x35, 0x3d, 0xf4, 0xff, 0xa1, 0x2b, 0x52, 0x9d, 0x93, 0x5b, 0x84, 0x78, 0x83, 0xf2, - 0x7f, 0x74, 0x61, 0xa9, 0xcb, 0x2f, 0x2c, 0xee, 0x37, 0x8e, 0x57, 0x22, 0xcc, 0x5c, 0xba, 0x44, - 0xf8, 0x3c, 0x20, 0x62, 0x11, 0x6d, 0xa8, 0x9e, 0x59, 0xc4, 0x30, 0x4f, 0x55, 0x7e, 0x34, 0x78, - 0xc6, 0x27, 0xb1, 0x2f, 0x0f, 0xd8, 0x87, 0x43, 0x76, 0x4a, 0x7e, 0x9e, 0x84, 0x82, 0x1f, 0xba, - 0x2f, 0x5b, 0xcd, 0xbf, 0x0a, 0x39, 0x11, 0x9d, 0x78, 0x39, 0x5f, 0xf4, 0xe6, 0xd6, 0x42, 0x1b, - 0x50, 0x18, 0x61, 0xa2, 0xb1, 0xfc, 0x85, 0x03, 0x51, 0xbf, 0x7f, 0xe7, 0x35, 0x28, 0x85, 0x7e, - 0xac, 0x50, 0x3f, 0xb1, 0xdf, 0x7e, 0x47, 0x4a, 0x34, 0xf2, 0x9f, 0x7c, 0x7e, 0x23, 0xbd, 0x8f, - 0x3f, 0xa4, 0x37, 0x4c, 0x69, 0xb7, 0x3a, 0xed, 0xd6, 0xae, 0x94, 0x6c, 0x94, 0x3e, 0xf9, 0xfc, - 0x46, 0x5e, 0xc1, 0xac, 0x7c, 0x75, 0x67, 0x17, 0x6a, 0x53, 0x1b, 0x13, 0xf5, 0xef, 0x08, 0xaa, - 0xf7, 0x8e, 0x0f, 0xf7, 0x76, 0x5a, 0xdb, 0xdd, 0xb6, 0xfa, 0xe0, 0xa0, 0xdb, 0x96, 0x92, 0xe8, - 0x71, 0xb8, 0xb2, 0xb7, 0xf3, 0xc3, 0x4e, 0x57, 0x6d, 0xed, 0xed, 0xb4, 0xf7, 0xbb, 0xea, 0x76, - 0xb7, 0xbb, 0xdd, 0xda, 0x95, 0x52, 0x5b, 0xff, 0x00, 0xa8, 0x6d, 0x37, 0x5b, 0x3b, 0x34, 0x3e, - 0x1b, 0x7d, 0x8d, 0x15, 0x0a, 0x5a, 0x90, 0x61, 0xa5, 0x80, 0x0b, 0x9f, 0x8a, 0x34, 0x2e, 0xae, - 0x6d, 0xa2, 0xfb, 0x90, 0x65, 0x55, 0x02, 0x74, 0xf1, 0xdb, 0x91, 0xc6, 0x82, 0x62, 0x27, 0x9d, - 0x0c, 0xbb, 0x4e, 0x17, 0x3e, 0x26, 0x69, 0x5c, 0x5c, 0xfb, 0x44, 0x0a, 0x14, 0x03, 0x94, 0xb1, - 0xf8, 0x71, 0x45, 0x63, 0x09, 0xef, 0x88, 0xf6, 0x20, 0xef, 0x01, 0xc3, 0x45, 0xcf, 0x3d, 0x1a, - 0x0b, 0x8b, 0x93, 0xd4, 0x5c, 0x1c, 0xc0, 0x5f, 0xfc, 0x76, 0xa5, 0xb1, 0xa0, 0xd2, 0x8a, 0x76, - 0x20, 0x27, 0x32, 0xe7, 0x05, 0x4f, 0x38, 0x1a, 0x8b, 0x8a, 0x8d, 0xd4, 0x68, 0x41, 0x69, 0x64, - 0xf1, 0x8b, 0x9c, 0xc6, 0x12, 0x45, 0x64, 0x74, 0x0c, 0x10, 0x82, 0xeb, 0x4b, 0x3c, 0xb5, 0x69, - 0x2c, 0x53, 0x1c, 0x46, 0x07, 0x50, 0xf0, 0xd1, 0xd3, 0xc2, 0x87, 0x2f, 0x8d, 0xc5, 0x55, 0x5a, - 0xf4, 0x10, 0x2a, 0x51, 0xd4, 0xb0, 0xdc, 0x73, 0x96, 0xc6, 0x92, 0xe5, 0x57, 0xaa, 0x3f, 0x0a, - 0x21, 0x96, 0x7b, 0xde, 0xd2, 0x58, 0xb2, 0x1a, 0x8b, 0xde, 0x87, 0x95, 0xd9, 0x14, 0x7f, 0xf9, - 0xd7, 0x2e, 0x8d, 0x4b, 0xd4, 0x67, 0xd1, 0x08, 0xd0, 0x1c, 0x68, 0x70, 0x89, 0xc7, 0x2f, 0x8d, - 0xcb, 0x94, 0x6b, 0x91, 0x0e, 0xb5, 0xe9, 0x7c, 0x7b, 0xd9, 0xc7, 0x30, 0x8d, 0xa5, 0x4b, 0xb7, - 0x7c, 0x94, 0x68, 0x9e, 0xbe, 0xec, 0xe3, 0x98, 0xc6, 0xd2, 0x95, 0xdc, 0x66, 0xfb, 0x8b, 0xaf, - 0xd7, 0x92, 0x5f, 0x7e, 0xbd, 0x96, 0xfc, 0xeb, 0xd7, 0x6b, 0xc9, 0x4f, 0xbf, 0x59, 0x4b, 0x7c, - 0xf9, 0xcd, 0x5a, 0xe2, 0x4f, 0xdf, 0xac, 0x25, 0x7e, 0xfc, 0xdc, 0xa9, 0x41, 0x06, 0xe3, 0xde, - 0x46, 0xdf, 0x1a, 0x6d, 0x86, 0x5f, 0x08, 0xce, 0x7b, 0xb5, 0xd8, 0xcb, 0xb1, 0x18, 0xf9, 0xd2, - 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0xb7, 0xe0, 0x79, 0x7a, 0xd5, 0x28, 0x00, 0x00, + // 2946 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5a, 0xcd, 0x73, 0x23, 0xc5, + 0x15, 0xd7, 0xe8, 0x5b, 0x4f, 0x5f, 0xe3, 0x5e, 0xb3, 0x68, 0xc5, 0xae, 0x6d, 0x86, 0x02, 0x96, + 0x05, 0x6c, 0x62, 0xb2, 0x7c, 0x14, 0x90, 0x2a, 0x59, 0xab, 0x8d, 0xd6, 0x6b, 0x6c, 0x33, 0x96, + 0x97, 0x22, 0x1f, 0x0c, 0x6d, 0xa9, 0x2d, 0x0d, 0x2b, 0x69, 0x86, 0x99, 0x96, 0x91, 0x39, 0xe6, + 0xa3, 0x2a, 0xc5, 0x89, 0x4b, 0xaa, 0xb8, 0x70, 0xc8, 0x21, 0xff, 0x43, 0x4e, 0x39, 0xe5, 0xc0, + 0x21, 0x07, 0x0e, 0x39, 0xe4, 0x90, 0x22, 0x29, 0xb8, 0xa4, 0xf2, 0x0f, 0x70, 0x4b, 0xa5, 0xfa, + 0x63, 0x46, 0x33, 0x92, 0xc6, 0x92, 0x09, 0x45, 0x55, 0xaa, 0x72, 0x9b, 0x7e, 0xf3, 0xde, 0xeb, + 0x9e, 0xd7, 0xaf, 0xdf, 0x7b, 0xbf, 0x37, 0x0d, 0x8f, 0x51, 0x32, 0xec, 0x10, 0x67, 0x60, 0x0e, + 0xe9, 0x16, 0x3e, 0x69, 0x9b, 0x5b, 0xf4, 0xdc, 0x26, 0xee, 0xa6, 0xed, 0x58, 0xd4, 0x42, 0xe5, + 0xc9, 0xcb, 0x4d, 0xf6, 0xb2, 0x7a, 0x23, 0xc0, 0xdd, 0x76, 0xce, 0x6d, 0x6a, 0x6d, 0xd9, 0x8e, + 0x65, 0x9d, 0x0a, 0xfe, 0xea, 0xf5, 0xd9, 0xd7, 0x0f, 0xc9, 0xb9, 0xd4, 0x16, 0x12, 0xe6, 0xb3, + 0x6c, 0xd9, 0xd8, 0xc1, 0x03, 0xef, 0xf5, 0x7a, 0xd7, 0xb2, 0xba, 0x7d, 0xb2, 0xc5, 0x47, 0x27, + 0xa3, 0xd3, 0x2d, 0x6a, 0x0e, 0x88, 0x4b, 0xf1, 0xc0, 0x96, 0x0c, 0xab, 0x5d, 0xab, 0x6b, 0xf1, + 0xc7, 0x2d, 0xf6, 0x24, 0xa8, 0xda, 0x6f, 0xb3, 0x90, 0xd1, 0xc9, 0x07, 0x23, 0xe2, 0x52, 0xb4, + 0x0d, 0x49, 0xd2, 0xee, 0x59, 0x15, 0x65, 0x43, 0xb9, 0x99, 0xdf, 0xbe, 0xbe, 0x39, 0xb5, 0xfc, + 0x4d, 0xc9, 0xd7, 0x68, 0xf7, 0xac, 0x66, 0x4c, 0xe7, 0xbc, 0xe8, 0x36, 0xa4, 0x4e, 0xfb, 0x23, + 0xb7, 0x57, 0x89, 0x73, 0xa1, 0x1b, 0x51, 0x42, 0x77, 0x19, 0x53, 0x33, 0xa6, 0x0b, 0x6e, 0x36, + 0x95, 0x39, 0x3c, 0xb5, 0x2a, 0x89, 0x8b, 0xa7, 0xba, 0x37, 0x3c, 0xe5, 0x53, 0x31, 0x5e, 0xb4, + 0x03, 0x60, 0x0e, 0x4d, 0x6a, 0xb4, 0x7b, 0xd8, 0x1c, 0x56, 0x52, 0x5c, 0xf2, 0xf1, 0x68, 0x49, + 0x93, 0xd6, 0x19, 0x63, 0x33, 0xa6, 0xe7, 0x4c, 0x6f, 0xc0, 0x96, 0xfb, 0xc1, 0x88, 0x38, 0xe7, + 0x95, 0xf4, 0xc5, 0xcb, 0x7d, 0x8b, 0x31, 0xb1, 0xe5, 0x72, 0x6e, 0xf4, 0x3a, 0x64, 0xdb, 0x3d, + 0xd2, 0x7e, 0x68, 0xd0, 0x71, 0x25, 0xcb, 0x25, 0xd7, 0xa3, 0x24, 0xeb, 0x8c, 0xaf, 0x35, 0x6e, + 0xc6, 0xf4, 0x4c, 0x5b, 0x3c, 0xa2, 0x57, 0x20, 0xdd, 0xb6, 0x06, 0x03, 0x93, 0x56, 0xf2, 0x5c, + 0x76, 0x2d, 0x52, 0x96, 0x73, 0x35, 0x63, 0xba, 0xe4, 0x47, 0xfb, 0x50, 0xea, 0x9b, 0x2e, 0x35, + 0xdc, 0x21, 0xb6, 0xdd, 0x9e, 0x45, 0xdd, 0x4a, 0x81, 0x6b, 0x78, 0x32, 0x4a, 0xc3, 0x9e, 0xe9, + 0xd2, 0x23, 0x8f, 0xb9, 0x19, 0xd3, 0x8b, 0xfd, 0x20, 0x81, 0xe9, 0xb3, 0x4e, 0x4f, 0x89, 0xe3, + 0x2b, 0xac, 0x14, 0x2f, 0xd6, 0x77, 0xc0, 0xb8, 0x3d, 0x79, 0xa6, 0xcf, 0x0a, 0x12, 0xd0, 0x4f, + 0xe1, 0x4a, 0xdf, 0xc2, 0x1d, 0x5f, 0x9d, 0xd1, 0xee, 0x8d, 0x86, 0x0f, 0x2b, 0x25, 0xae, 0xf4, + 0x99, 0xc8, 0x45, 0x5a, 0xb8, 0xe3, 0xa9, 0xa8, 0x33, 0x81, 0x66, 0x4c, 0x5f, 0xe9, 0x4f, 0x13, + 0xd1, 0xbb, 0xb0, 0x8a, 0x6d, 0xbb, 0x7f, 0x3e, 0xad, 0xbd, 0xcc, 0xb5, 0xdf, 0x8a, 0xd2, 0x5e, + 0x63, 0x32, 0xd3, 0xea, 0x11, 0x9e, 0xa1, 0xa2, 0x16, 0xa8, 0xb6, 0x43, 0x6c, 0xec, 0x10, 0xc3, + 0x76, 0x2c, 0xdb, 0x72, 0x71, 0xbf, 0xa2, 0x72, 0xdd, 0x4f, 0x47, 0xe9, 0x3e, 0x14, 0xfc, 0x87, + 0x92, 0xbd, 0x19, 0xd3, 0xcb, 0x76, 0x98, 0x24, 0xb4, 0x5a, 0x6d, 0xe2, 0xba, 0x13, 0xad, 0x2b, + 0x8b, 0xb4, 0x72, 0xfe, 0xb0, 0xd6, 0x10, 0x89, 0x6d, 0xdc, 0xa9, 0x39, 0xc4, 0x7d, 0xf3, 0x23, + 0x62, 0x9c, 0xf4, 0xad, 0xf6, 0xc3, 0xca, 0xea, 0xc5, 0x1b, 0x77, 0x57, 0x72, 0xef, 0x30, 0x66, + 0xb6, 0x71, 0xa7, 0x41, 0xc2, 0x4e, 0x06, 0x52, 0x67, 0xb8, 0x3f, 0x22, 0xbb, 0xc9, 0x6c, 0x52, + 0x4d, 0xed, 0x26, 0xb3, 0x19, 0x35, 0xbb, 0x9b, 0xcc, 0xe6, 0x54, 0xd8, 0x4d, 0x66, 0x41, 0xcd, + 0x6b, 0x4f, 0x43, 0x3e, 0x70, 0xdc, 0x51, 0x05, 0x32, 0x03, 0xe2, 0xba, 0xb8, 0x4b, 0x78, 0x74, + 0xc8, 0xe9, 0xde, 0x50, 0x2b, 0x41, 0x21, 0x78, 0xc4, 0xb5, 0x4f, 0x14, 0x5f, 0x92, 0x9d, 0x5e, + 0x26, 0x79, 0x46, 0x1c, 0xd7, 0xb4, 0x86, 0x9e, 0xa4, 0x1c, 0xa2, 0x27, 0xa0, 0xc8, 0x3f, 0xc5, + 0xf0, 0xde, 0xb3, 0x10, 0x92, 0xd4, 0x0b, 0x9c, 0xf8, 0x40, 0x32, 0xad, 0x43, 0xde, 0xde, 0xb6, + 0x7d, 0x96, 0x04, 0x67, 0x01, 0x7b, 0xdb, 0xf6, 0x18, 0x1e, 0x87, 0x02, 0xfb, 0x6e, 0x9f, 0x23, + 0xc9, 0x27, 0xc9, 0x33, 0x9a, 0x64, 0xd1, 0xfe, 0x1c, 0x07, 0x75, 0x3a, 0x2c, 0xa0, 0x57, 0x20, + 0xc9, 0x22, 0xa4, 0x0c, 0x76, 0xd5, 0x4d, 0x11, 0x3e, 0x37, 0xbd, 0xf0, 0xb9, 0xd9, 0xf2, 0xc2, + 0xe7, 0x4e, 0xf6, 0xf3, 0x2f, 0xd7, 0x63, 0x9f, 0xfc, 0x7d, 0x5d, 0xd1, 0xb9, 0x04, 0xba, 0xc6, + 0x82, 0x01, 0x36, 0x87, 0x86, 0xd9, 0xe1, 0x4b, 0xce, 0xb1, 0x93, 0x8e, 0xcd, 0xe1, 0xbd, 0x0e, + 0xda, 0x03, 0xb5, 0x6d, 0x0d, 0x5d, 0x32, 0x74, 0x47, 0xae, 0x21, 0xc2, 0xb3, 0x0c, 0x71, 0xa1, + 0x40, 0x25, 0x92, 0x44, 0xdd, 0xe3, 0x3c, 0xe4, 0x8c, 0x7a, 0xb9, 0x1d, 0x26, 0xa0, 0xbb, 0x00, + 0x67, 0xb8, 0x6f, 0x76, 0x30, 0xb5, 0x1c, 0xb7, 0x92, 0xdc, 0x48, 0xdc, 0xcc, 0x6f, 0x6f, 0xcc, + 0x6c, 0xf8, 0x03, 0x8f, 0xe5, 0xd8, 0xee, 0x60, 0x4a, 0x76, 0x92, 0x6c, 0xb9, 0x7a, 0x40, 0x12, + 0x3d, 0x05, 0x65, 0x6c, 0xdb, 0x86, 0x4b, 0x31, 0x25, 0xc6, 0xc9, 0x39, 0x25, 0x2e, 0x8f, 0x9e, + 0x05, 0xbd, 0x88, 0x6d, 0xfb, 0x88, 0x51, 0x77, 0x18, 0x11, 0x3d, 0x09, 0x25, 0x16, 0x29, 0x4d, + 0xdc, 0x37, 0x7a, 0xc4, 0xec, 0xf6, 0x28, 0x8f, 0x92, 0x09, 0xbd, 0x28, 0xa9, 0x4d, 0x4e, 0xd4, + 0x3a, 0xfe, 0x8e, 0xf3, 0x28, 0x89, 0x10, 0x24, 0x3b, 0x98, 0x62, 0x6e, 0xc9, 0x82, 0xce, 0x9f, + 0x19, 0xcd, 0xc6, 0xb4, 0x27, 0xed, 0xc3, 0x9f, 0xd1, 0x55, 0x48, 0x4b, 0xb5, 0x09, 0xae, 0x56, + 0x8e, 0xd0, 0x2a, 0xa4, 0x6c, 0xc7, 0x3a, 0x23, 0x7c, 0xeb, 0xb2, 0xba, 0x18, 0x68, 0x3a, 0x94, + 0xc2, 0x11, 0x15, 0x95, 0x20, 0x4e, 0xc7, 0x72, 0x96, 0x38, 0x1d, 0xa3, 0x17, 0x20, 0xc9, 0x0c, + 0xc9, 0xe7, 0x28, 0xcd, 0xc9, 0x21, 0x52, 0xae, 0x75, 0x6e, 0x13, 0x9d, 0x73, 0x6a, 0x65, 0x28, + 0x86, 0x22, 0xad, 0x76, 0x15, 0x56, 0xe7, 0x05, 0x4e, 0xad, 0xe7, 0xd3, 0x43, 0x01, 0x10, 0xdd, + 0x86, 0xac, 0x1f, 0x39, 0x85, 0xe3, 0x5c, 0x9b, 0x99, 0xd6, 0x63, 0xd6, 0x7d, 0x56, 0xe6, 0x31, + 0x6c, 0x03, 0x7a, 0x58, 0xe6, 0xc9, 0x82, 0x9e, 0xc1, 0xb6, 0xdd, 0xc4, 0x6e, 0x4f, 0x7b, 0x0f, + 0x2a, 0x51, 0x51, 0x31, 0x60, 0x30, 0x85, 0xbb, 0xbd, 0x67, 0xb0, 0xab, 0x90, 0x3e, 0xb5, 0x9c, + 0x01, 0xa6, 0x5c, 0x59, 0x51, 0x97, 0x23, 0x66, 0x48, 0x11, 0x21, 0x13, 0x9c, 0x2c, 0x06, 0x9a, + 0x01, 0xd7, 0x22, 0x23, 0x23, 0x13, 0x31, 0x87, 0x1d, 0x22, 0xcc, 0x5a, 0xd4, 0xc5, 0x60, 0xa2, + 0x48, 0x2c, 0x56, 0x0c, 0xd8, 0xb4, 0x2e, 0xff, 0x56, 0xae, 0x3f, 0xa7, 0xcb, 0x91, 0xf6, 0x69, + 0x02, 0xae, 0xce, 0x8f, 0x8f, 0x68, 0x03, 0x0a, 0x03, 0x3c, 0x36, 0xe8, 0x58, 0xba, 0x9d, 0xc2, + 0x37, 0x1e, 0x06, 0x78, 0xdc, 0x1a, 0x0b, 0x9f, 0x53, 0x21, 0x41, 0xc7, 0x6e, 0x25, 0xbe, 0x91, + 0xb8, 0x59, 0xd0, 0xd9, 0x23, 0x3a, 0x86, 0x95, 0xbe, 0xd5, 0xc6, 0x7d, 0xa3, 0x8f, 0x5d, 0x6a, + 0xc8, 0xc4, 0x29, 0x0e, 0xd1, 0x13, 0x33, 0xc6, 0x6e, 0x8c, 0x39, 0xa5, 0x23, 0xf6, 0x93, 0x05, + 0x1c, 0xe9, 0xff, 0x65, 0xae, 0x63, 0x0f, 0x7b, 0x5b, 0x8d, 0xee, 0x40, 0x7e, 0x60, 0xba, 0x27, + 0xa4, 0x87, 0xcf, 0x4c, 0xcb, 0x91, 0xa7, 0x69, 0xd6, 0x69, 0xde, 0x9c, 0xf0, 0x48, 0x4d, 0x41, + 0xb1, 0xc0, 0x96, 0xa4, 0x42, 0x3e, 0xec, 0x45, 0x93, 0xf4, 0xa5, 0xa3, 0xc9, 0x0b, 0xb0, 0x3a, + 0x24, 0x63, 0x6a, 0x4c, 0xce, 0xab, 0xf0, 0x93, 0x0c, 0x37, 0x3d, 0x62, 0xef, 0xfc, 0x13, 0xee, + 0x32, 0x97, 0x41, 0xcf, 0xf0, 0x0c, 0x63, 0x5b, 0x2e, 0x71, 0x0c, 0xdc, 0xe9, 0x38, 0xc4, 0x75, + 0x79, 0x51, 0x52, 0xe0, 0x69, 0x83, 0xd3, 0x6b, 0x82, 0xac, 0xfd, 0x26, 0xb8, 0x35, 0xe1, 0x8c, + 0x22, 0x0d, 0xaf, 0x4c, 0x0c, 0x7f, 0x04, 0xab, 0x52, 0xbe, 0x13, 0xb2, 0xbd, 0xa8, 0xec, 0x1e, + 0x9b, 0x3d, 0x5f, 0xd3, 0x36, 0x47, 0x9e, 0x78, 0xb4, 0xd9, 0x13, 0xdf, 0xce, 0xec, 0x08, 0x92, + 0xdc, 0x28, 0x49, 0x11, 0x62, 0xd8, 0xf3, 0xff, 0xda, 0x56, 0xfc, 0x2a, 0xe1, 0xc7, 0x94, 0x50, + 0x6e, 0x9e, 0xb3, 0x11, 0x6f, 0xc1, 0x95, 0x0e, 0x69, 0x9b, 0x9d, 0x6f, 0xbb, 0x0f, 0x2b, 0x52, + 0xfa, 0xff, 0xdb, 0x30, 0xbb, 0x0d, 0xff, 0xcc, 0x42, 0x56, 0x27, 0xae, 0xcd, 0x52, 0x2d, 0xda, + 0x81, 0x1c, 0x19, 0xb7, 0x89, 0x4d, 0xbd, 0xea, 0x24, 0xbf, 0xad, 0xcd, 0x29, 0xa8, 0x04, 0x77, + 0xc3, 0xe3, 0x64, 0x88, 0xc2, 0x17, 0x43, 0x2f, 0x4a, 0xd0, 0x14, 0x8d, 0x7f, 0xa4, 0x78, 0x10, + 0x35, 0xbd, 0xe4, 0xa1, 0xa6, 0x44, 0x24, 0x20, 0x10, 0x52, 0x53, 0xb0, 0xe9, 0x45, 0x09, 0x9b, + 0x92, 0x0b, 0x26, 0x0b, 0xe1, 0xa6, 0x7a, 0x08, 0x37, 0xa5, 0x17, 0x7c, 0x66, 0x04, 0x70, 0x7a, + 0xc9, 0x03, 0x4e, 0x99, 0x05, 0x2b, 0x9e, 0x42, 0x4e, 0x6f, 0x04, 0x90, 0x53, 0x8e, 0x8b, 0x6e, + 0x44, 0x8a, 0xce, 0x81, 0x4e, 0xaf, 0xfa, 0xd0, 0xa9, 0x10, 0x09, 0xbb, 0xa4, 0xf0, 0x34, 0x76, + 0x3a, 0x98, 0xc1, 0x4e, 0x02, 0xeb, 0x3c, 0x15, 0xa9, 0x62, 0x01, 0x78, 0x3a, 0x98, 0x01, 0x4f, + 0xa5, 0x05, 0x0a, 0x17, 0xa0, 0xa7, 0x9f, 0xcd, 0x47, 0x4f, 0xd1, 0xf8, 0x46, 0x2e, 0x73, 0x39, + 0xf8, 0x64, 0x44, 0xc0, 0x27, 0x01, 0x71, 0x9e, 0x8d, 0x54, 0xbf, 0x34, 0x7e, 0x3a, 0x9e, 0x83, + 0x9f, 0x04, 0xd2, 0xb9, 0x19, 0xa9, 0x7c, 0x09, 0x00, 0x75, 0x3c, 0x07, 0x40, 0xa1, 0x85, 0x6a, + 0x17, 0x22, 0xa8, 0x83, 0x19, 0x04, 0xf5, 0xc8, 0x82, 0xdd, 0x5b, 0x1e, 0x42, 0xa5, 0xd4, 0xf4, + 0x6e, 0x32, 0x9b, 0x55, 0x73, 0x02, 0x3c, 0xed, 0x26, 0xb3, 0x79, 0xb5, 0xa0, 0x3d, 0x03, 0x2b, + 0x33, 0xb1, 0x83, 0x95, 0x56, 0xc4, 0x71, 0x2c, 0x47, 0x82, 0x21, 0x31, 0xd0, 0x6e, 0xb2, 0x92, + 0x7a, 0x12, 0x27, 0x2e, 0x80, 0x5b, 0xbc, 0x84, 0x0d, 0xc4, 0x06, 0xed, 0x0f, 0xca, 0x44, 0x96, + 0x03, 0xae, 0x60, 0x39, 0x9e, 0x93, 0xe5, 0x78, 0x00, 0x84, 0xc5, 0xc3, 0x20, 0x6c, 0x1d, 0xf2, + 0xac, 0x34, 0x9d, 0xc2, 0x57, 0xd8, 0xf6, 0xf1, 0xd5, 0x2d, 0x58, 0xe1, 0x49, 0x48, 0x40, 0x35, + 0x19, 0xea, 0x93, 0x3c, 0xd4, 0x97, 0xd9, 0x0b, 0x61, 0x1d, 0x11, 0xf3, 0x9f, 0x87, 0x2b, 0x01, + 0x5e, 0xbf, 0xe4, 0x15, 0x60, 0x43, 0xf5, 0xb9, 0x6b, 0xb2, 0xf6, 0xfd, 0x93, 0x32, 0xb1, 0xd0, + 0x04, 0x98, 0xcd, 0xc3, 0x50, 0xca, 0x77, 0x84, 0xa1, 0xe2, 0xdf, 0x1a, 0x43, 0x05, 0x4b, 0xf8, + 0x44, 0xb8, 0x84, 0xff, 0x46, 0x99, 0xec, 0x89, 0x8f, 0x88, 0xda, 0x56, 0x87, 0xc8, 0xa2, 0x9a, + 0x3f, 0xb3, 0x34, 0xdf, 0xb7, 0xba, 0xb2, 0x74, 0x66, 0x8f, 0x8c, 0xcb, 0x0f, 0xe6, 0x39, 0x19, + 0xab, 0xfd, 0x7a, 0x5c, 0x24, 0x53, 0x59, 0x8f, 0xab, 0x90, 0x78, 0x48, 0x44, 0xcf, 0xaa, 0xa0, + 0xb3, 0x47, 0xc6, 0xc7, 0x9d, 0x4f, 0x26, 0x45, 0x31, 0x40, 0xaf, 0x40, 0x8e, 0xf7, 0x13, 0x0d, + 0xcb, 0x76, 0x65, 0x9f, 0x2a, 0x54, 0x2e, 0x88, 0xa6, 0xe2, 0xe6, 0x21, 0xe3, 0x39, 0xb0, 0x5d, + 0x3d, 0x6b, 0xcb, 0xa7, 0x40, 0x16, 0xcf, 0x85, 0xb2, 0xf8, 0x75, 0xc8, 0xb1, 0xd5, 0xbb, 0x36, + 0x6e, 0x93, 0x0a, 0xf0, 0x85, 0x4e, 0x08, 0xda, 0xdf, 0xe2, 0x50, 0x9e, 0x0a, 0xde, 0x73, 0xbf, + 0xdd, 0x73, 0xc9, 0x78, 0x00, 0x21, 0x2e, 0x67, 0x8f, 0x35, 0x80, 0x2e, 0x76, 0x8d, 0x0f, 0xf1, + 0x90, 0x92, 0x8e, 0x34, 0x4a, 0x80, 0x82, 0xaa, 0x90, 0x65, 0xa3, 0x91, 0x4b, 0x3a, 0x12, 0xac, + 0xfa, 0x63, 0xd4, 0x84, 0x34, 0x39, 0x23, 0x43, 0xea, 0x56, 0x32, 0x7c, 0xdb, 0xaf, 0xce, 0xa2, + 0x07, 0xf6, 0x7a, 0xa7, 0xc2, 0x36, 0xfb, 0x5f, 0x5f, 0xae, 0xab, 0x82, 0xfb, 0x39, 0x6b, 0x60, + 0x52, 0x32, 0xb0, 0xe9, 0xb9, 0x2e, 0xe5, 0xc3, 0x56, 0xc8, 0x4e, 0x59, 0x21, 0x80, 0x8b, 0x72, + 0x41, 0x5c, 0xc4, 0xd6, 0x66, 0x3b, 0xa6, 0xe5, 0x98, 0xf4, 0x9c, 0x9b, 0x2e, 0xa1, 0xfb, 0x63, + 0xf4, 0x04, 0x14, 0x07, 0x64, 0x60, 0x5b, 0x56, 0xdf, 0x10, 0xe1, 0x20, 0xcf, 0x45, 0x0b, 0x92, + 0xd8, 0xe0, 0x51, 0xa1, 0xc6, 0x20, 0x70, 0x30, 0xbb, 0x31, 0x31, 0x87, 0x50, 0x6c, 0x0e, 0x8d, + 0x10, 0x92, 0x2e, 0x08, 0xa2, 0x38, 0x85, 0xbb, 0xc9, 0xac, 0xa2, 0xc6, 0x77, 0x93, 0xd9, 0xb8, + 0x9a, 0xd0, 0x0e, 0xe1, 0x91, 0xb9, 0xd9, 0x0d, 0xbd, 0x0c, 0xb9, 0x49, 0x62, 0x54, 0xb8, 0x7d, + 0x2e, 0x80, 0xb2, 0x13, 0x5e, 0xed, 0x8f, 0xca, 0x44, 0x65, 0x18, 0x1c, 0x37, 0x20, 0xed, 0x10, + 0x77, 0xd4, 0x17, 0x70, 0xb5, 0xb4, 0xfd, 0xfc, 0x72, 0x79, 0x91, 0x51, 0x47, 0x7d, 0xaa, 0x4b, + 0x61, 0xed, 0x5d, 0x48, 0x0b, 0x0a, 0xca, 0x43, 0xe6, 0x78, 0xff, 0xfe, 0xfe, 0xc1, 0xdb, 0xfb, + 0x6a, 0x0c, 0x01, 0xa4, 0x6b, 0xf5, 0x7a, 0xe3, 0xb0, 0xa5, 0x2a, 0x28, 0x07, 0xa9, 0xda, 0xce, + 0x81, 0xde, 0x52, 0xe3, 0x8c, 0xac, 0x37, 0x76, 0x1b, 0xf5, 0x96, 0x9a, 0x40, 0x2b, 0x50, 0x14, + 0xcf, 0xc6, 0xdd, 0x03, 0xfd, 0xcd, 0x5a, 0x4b, 0x4d, 0x06, 0x48, 0x47, 0x8d, 0xfd, 0x3b, 0x0d, + 0x5d, 0x4d, 0x69, 0x3f, 0x60, 0x78, 0x38, 0x22, 0x93, 0x4e, 0x90, 0xaf, 0x12, 0x40, 0xbe, 0xda, + 0xa7, 0x71, 0xa8, 0x46, 0xa7, 0x47, 0xb4, 0x3b, 0xf5, 0xe1, 0xdb, 0x97, 0xc8, 0xad, 0x53, 0x5f, + 0x8f, 0x9e, 0x84, 0x92, 0x43, 0x4e, 0x09, 0x6d, 0xf7, 0x44, 0xba, 0x16, 0x31, 0xab, 0xa8, 0x17, + 0x25, 0x95, 0x0b, 0xb9, 0x82, 0xed, 0x7d, 0xd2, 0xa6, 0x86, 0x70, 0x36, 0x97, 0x97, 0xf4, 0x39, + 0xc6, 0xc6, 0xa8, 0x47, 0x82, 0xa8, 0xbd, 0x77, 0x29, 0x5b, 0xe6, 0x20, 0xa5, 0x37, 0x5a, 0xfa, + 0x3b, 0x6a, 0x02, 0x21, 0x28, 0xf1, 0x47, 0xe3, 0x68, 0xbf, 0x76, 0x78, 0xd4, 0x3c, 0x60, 0xb6, + 0xbc, 0x02, 0x65, 0xcf, 0x96, 0x1e, 0x31, 0xa5, 0x3d, 0x0b, 0x8f, 0x46, 0xe4, 0xf6, 0x59, 0x60, + 0xa3, 0xfd, 0x4e, 0x09, 0x72, 0x4f, 0xe7, 0xe7, 0xb4, 0x4b, 0x31, 0x1d, 0xb9, 0xd2, 0x88, 0x2f, + 0x2f, 0x9b, 0xec, 0x37, 0xbd, 0x87, 0x23, 0x2e, 0xae, 0x4b, 0x35, 0xda, 0x6d, 0x28, 0x85, 0xdf, + 0x44, 0xdb, 0x60, 0xe2, 0x44, 0x71, 0xed, 0x9b, 0xf8, 0xc4, 0xbf, 0xc3, 0x40, 0x6d, 0x12, 0x4f, + 0x94, 0xff, 0x32, 0x9e, 0xbc, 0x0e, 0x40, 0xc7, 0x86, 0xd8, 0x71, 0x2f, 0x29, 0xdd, 0x98, 0xd3, + 0xdb, 0x20, 0xed, 0xd6, 0x58, 0xfa, 0x47, 0x8e, 0xca, 0x27, 0x86, 0xd3, 0x57, 0xfc, 0xc4, 0x64, + 0x8c, 0x78, 0xc2, 0x72, 0x25, 0xa2, 0x5b, 0x36, 0xb3, 0xa9, 0x67, 0x61, 0xb2, 0x8b, 0xde, 0x81, + 0x47, 0xa7, 0xb2, 0xae, 0xaf, 0x3a, 0xb9, 0x6c, 0xf2, 0x7d, 0x24, 0x9c, 0x7c, 0x3d, 0xd5, 0x4f, + 0x41, 0x19, 0x77, 0x1d, 0x42, 0x3a, 0xbc, 0x22, 0xe0, 0x89, 0xc0, 0x6b, 0x3f, 0x72, 0x72, 0xcd, + 0xb6, 0xef, 0x60, 0x8a, 0xb5, 0x77, 0x00, 0x26, 0x50, 0x96, 0x9d, 0x44, 0xc7, 0x1a, 0x0d, 0x3b, + 0xdc, 0x1d, 0x52, 0xba, 0x18, 0xa0, 0xdb, 0x90, 0x3a, 0xb3, 0xd8, 0xa2, 0xe2, 0x11, 0x21, 0xeb, + 0x81, 0x45, 0x49, 0x00, 0x0a, 0x0b, 0x6e, 0xcd, 0x04, 0x34, 0xdb, 0x29, 0x8a, 0x98, 0xe2, 0x8d, + 0xf0, 0x14, 0x8f, 0x47, 0xf6, 0x9c, 0xe6, 0x4f, 0xf5, 0x11, 0xa4, 0xb8, 0x1b, 0xb0, 0x74, 0xc6, + 0xdb, 0x93, 0xb2, 0x0e, 0x63, 0xcf, 0xe8, 0xe7, 0x00, 0x98, 0x52, 0xc7, 0x3c, 0x19, 0x4d, 0x26, + 0x58, 0x9f, 0xef, 0x46, 0x35, 0x8f, 0x6f, 0xe7, 0xba, 0xf4, 0xa7, 0xd5, 0x89, 0x68, 0xc0, 0xa7, + 0x02, 0x0a, 0xb5, 0x7d, 0x28, 0x85, 0x65, 0xbd, 0xca, 0x41, 0xac, 0x21, 0x5c, 0x39, 0x88, 0x42, + 0x50, 0x56, 0x0e, 0x7e, 0xdd, 0x91, 0x10, 0x3d, 0x58, 0x3e, 0xd0, 0xfe, 0xad, 0x40, 0x21, 0xe8, + 0x85, 0xdf, 0x71, 0x72, 0xbf, 0x31, 0x27, 0xb9, 0xe7, 0xba, 0xd8, 0x7d, 0x5b, 0xe4, 0xf6, 0x6b, + 0x33, 0xb9, 0x3d, 0xd3, 0xc5, 0xee, 0xf1, 0xf7, 0x98, 0xda, 0xb5, 0x5f, 0x2b, 0x90, 0xf5, 0x3f, + 0x3e, 0xdc, 0x8e, 0x0d, 0xf5, 0xaf, 0x85, 0xed, 0xe2, 0xc1, 0x1e, 0xaa, 0xe8, 0x56, 0x27, 0xfc, + 0x6e, 0xf5, 0x6b, 0x7e, 0x92, 0x88, 0x02, 0xef, 0x41, 0x4b, 0x4b, 0x9f, 0xf2, 0x72, 0xe2, 0x6b, + 0x90, 0xf3, 0x0f, 0x32, 0x2b, 0xe6, 0xbd, 0x26, 0x87, 0x22, 0x2b, 0x51, 0x31, 0xe4, 0x9d, 0x74, + 0xeb, 0x43, 0xd9, 0xa0, 0x4d, 0xe8, 0x62, 0xa0, 0x75, 0xa0, 0x3c, 0x15, 0x05, 0xd0, 0x6b, 0x90, + 0xb1, 0x47, 0x27, 0x86, 0xe7, 0x1a, 0x53, 0xad, 0x20, 0xaf, 0x4c, 0x1c, 0x9d, 0xf4, 0xcd, 0xf6, + 0x7d, 0x72, 0xee, 0x2d, 0xc6, 0x1e, 0x9d, 0xdc, 0x17, 0x1e, 0x24, 0x66, 0x89, 0x07, 0x67, 0x39, + 0x83, 0xac, 0x77, 0x20, 0xd0, 0x8f, 0x20, 0xe7, 0x07, 0x18, 0xff, 0x07, 0x4b, 0x64, 0x64, 0x92, + 0xea, 0x27, 0x22, 0x0c, 0x73, 0xb8, 0x66, 0x77, 0xe8, 0xf5, 0xbf, 0x04, 0x5c, 0x8b, 0x73, 0xcf, + 0x2c, 0x8b, 0x17, 0x7b, 0x1e, 0x96, 0xd0, 0x7e, 0xaf, 0x80, 0x3a, 0x7d, 0x22, 0xbf, 0xcf, 0x05, + 0xb0, 0x54, 0xcc, 0x4e, 0xbe, 0x41, 0xd8, 0x22, 0x7c, 0x10, 0x55, 0xd0, 0x8b, 0x8c, 0xda, 0xf0, + 0x88, 0xda, 0x2f, 0xe3, 0x90, 0x0f, 0xb4, 0xd7, 0xd0, 0x0f, 0x03, 0xe1, 0xa1, 0x34, 0x27, 0x70, + 0x07, 0x78, 0x27, 0x7f, 0x30, 0xc2, 0x1f, 0x16, 0xbf, 0xfc, 0x87, 0x45, 0xfd, 0x83, 0xf1, 0xba, + 0x75, 0xc9, 0x4b, 0x77, 0xeb, 0x9e, 0x03, 0x44, 0x2d, 0x8a, 0xfb, 0xc6, 0x99, 0x45, 0xcd, 0x61, + 0xd7, 0x10, 0xae, 0x21, 0x0e, 0xb3, 0xca, 0xdf, 0x3c, 0xe0, 0x2f, 0x0e, 0xb9, 0x97, 0xfc, 0x42, + 0x81, 0xac, 0x5f, 0x30, 0x5e, 0xf6, 0xff, 0xc6, 0x55, 0x48, 0xcb, 0x9a, 0x48, 0xfc, 0xe0, 0x90, + 0xa3, 0xb9, 0x6d, 0xc9, 0x2a, 0x64, 0x07, 0x84, 0xe2, 0x40, 0xb6, 0xf1, 0xc7, 0xb7, 0x5e, 0x85, + 0x7c, 0xe0, 0xdf, 0x10, 0x0b, 0x56, 0xfb, 0x8d, 0xb7, 0xd5, 0x58, 0x35, 0xf3, 0xf1, 0x67, 0x1b, + 0x89, 0x7d, 0xf2, 0x21, 0x3b, 0x61, 0x7a, 0xa3, 0xde, 0x6c, 0xd4, 0xef, 0xab, 0x4a, 0x35, 0xff, + 0xf1, 0x67, 0x1b, 0x19, 0x9d, 0xf0, 0x8e, 0xd4, 0xad, 0xfb, 0x50, 0x9e, 0xda, 0x98, 0x70, 0x55, + 0x81, 0xa0, 0x74, 0xe7, 0xf8, 0x70, 0xef, 0x5e, 0xbd, 0xd6, 0x6a, 0x18, 0x0f, 0x0e, 0x5a, 0x0d, + 0x55, 0x41, 0x8f, 0xc2, 0x95, 0xbd, 0x7b, 0x3f, 0x6e, 0xb6, 0x8c, 0xfa, 0xde, 0xbd, 0xc6, 0x7e, + 0xcb, 0xa8, 0xb5, 0x5a, 0xb5, 0xfa, 0x7d, 0x35, 0xbe, 0xfd, 0x97, 0x1c, 0x24, 0x6b, 0x3b, 0xf5, + 0x7b, 0xa8, 0x0e, 0x49, 0x0e, 0xfb, 0x2f, 0xbc, 0x72, 0x51, 0xbd, 0xb8, 0xb7, 0x88, 0xee, 0x42, + 0x8a, 0x77, 0x04, 0xd0, 0xc5, 0x77, 0x30, 0xaa, 0x0b, 0x9a, 0x8d, 0x6c, 0x31, 0xfc, 0x0c, 0x5d, + 0x78, 0x29, 0xa3, 0x7a, 0x71, 0xef, 0x11, 0xed, 0x41, 0xc6, 0x03, 0x84, 0x8b, 0x6e, 0x4a, 0x54, + 0x17, 0x36, 0x04, 0xd9, 0xa7, 0x09, 0x60, 0x7d, 0xf1, 0x7d, 0x8d, 0xea, 0x82, 0xae, 0x24, 0xba, + 0x07, 0x69, 0x09, 0xa4, 0x16, 0x5c, 0xc1, 0xa8, 0x2e, 0xea, 0x33, 0x22, 0x1d, 0x72, 0x93, 0x96, + 0xc5, 0xe2, 0x5b, 0x28, 0xd5, 0x25, 0x1a, 0xae, 0xe8, 0x5d, 0x28, 0x86, 0x41, 0xda, 0x72, 0xd7, + 0x3c, 0xaa, 0x4b, 0x76, 0x34, 0x99, 0xfe, 0x30, 0x62, 0x5b, 0xee, 0xda, 0x47, 0x75, 0xc9, 0x06, + 0x27, 0x7a, 0x1f, 0x56, 0x66, 0x11, 0xd5, 0xf2, 0xb7, 0x40, 0xaa, 0x97, 0x68, 0x79, 0xa2, 0x01, + 0xa0, 0x39, 0x48, 0xec, 0x12, 0x97, 0x42, 0xaa, 0x97, 0xe9, 0x80, 0xa2, 0x0e, 0x94, 0xa7, 0xe1, + 0xcd, 0xb2, 0x97, 0x44, 0xaa, 0x4b, 0x77, 0x43, 0xc5, 0x2c, 0x61, 0x58, 0xb4, 0xec, 0xa5, 0x91, + 0xea, 0xd2, 0xcd, 0x51, 0xe6, 0x06, 0x61, 0x60, 0xb3, 0xdc, 0x25, 0x92, 0xea, 0x92, 0x9d, 0xd2, + 0x9d, 0xc6, 0xe7, 0x5f, 0xad, 0x29, 0x5f, 0x7c, 0xb5, 0xa6, 0xfc, 0xe3, 0xab, 0x35, 0xe5, 0x93, + 0xaf, 0xd7, 0x62, 0x5f, 0x7c, 0xbd, 0x16, 0xfb, 0xeb, 0xd7, 0x6b, 0xb1, 0x9f, 0x3c, 0xdb, 0x35, + 0x69, 0x6f, 0x74, 0xb2, 0xd9, 0xb6, 0x06, 0x5b, 0xc1, 0xdb, 0x6c, 0xf3, 0xee, 0xd0, 0x9d, 0xa4, + 0x79, 0xf2, 0x79, 0xf1, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x45, 0x53, 0xe3, 0x57, 0x63, 0x27, + 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3660,612 +3521,540 @@ var _ grpc.ClientConn // is compatible with the grpc package it is being compiled against. const _ = grpc.SupportPackageIsVersion4 -// ABCIApplicationClient is the client API for ABCIApplication service. +// ABCIClient is the client API for ABCI service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type ABCIApplicationClient interface { +type ABCIClient interface { Echo(ctx context.Context, in *RequestEcho, opts ...grpc.CallOption) (*ResponseEcho, error) Flush(ctx context.Context, in *RequestFlush, opts ...grpc.CallOption) (*ResponseFlush, error) Info(ctx context.Context, in *RequestInfo, opts ...grpc.CallOption) (*ResponseInfo, error) - DeliverTx(ctx context.Context, in *RequestDeliverTx, opts ...grpc.CallOption) (*ResponseDeliverTx, error) CheckTx(ctx context.Context, in *RequestCheckTx, opts ...grpc.CallOption) (*ResponseCheckTx, error) Query(ctx context.Context, in *RequestQuery, opts ...grpc.CallOption) (*ResponseQuery, error) Commit(ctx context.Context, in *RequestCommit, opts ...grpc.CallOption) (*ResponseCommit, error) InitChain(ctx context.Context, in *RequestInitChain, opts ...grpc.CallOption) (*ResponseInitChain, error) - BeginBlock(ctx context.Context, in *RequestBeginBlock, opts ...grpc.CallOption) (*ResponseBeginBlock, error) - EndBlock(ctx context.Context, in *RequestEndBlock, opts ...grpc.CallOption) (*ResponseEndBlock, error) ListSnapshots(ctx context.Context, in *RequestListSnapshots, opts ...grpc.CallOption) (*ResponseListSnapshots, error) OfferSnapshot(ctx context.Context, in *RequestOfferSnapshot, opts ...grpc.CallOption) (*ResponseOfferSnapshot, error) LoadSnapshotChunk(ctx context.Context, in *RequestLoadSnapshotChunk, opts ...grpc.CallOption) (*ResponseLoadSnapshotChunk, error) ApplySnapshotChunk(ctx context.Context, in *RequestApplySnapshotChunk, opts ...grpc.CallOption) (*ResponseApplySnapshotChunk, error) PrepareProposal(ctx context.Context, in *RequestPrepareProposal, opts ...grpc.CallOption) (*ResponsePrepareProposal, error) ProcessProposal(ctx context.Context, in *RequestProcessProposal, opts ...grpc.CallOption) (*ResponseProcessProposal, error) + FinalizeBlock(ctx context.Context, in *RequestFinalizeBlock, opts ...grpc.CallOption) (*ResponseFinalizeBlock, error) } -type aBCIApplicationClient struct { +type aBCIClient struct { cc grpc1.ClientConn } -func NewABCIApplicationClient(cc grpc1.ClientConn) ABCIApplicationClient { - return &aBCIApplicationClient{cc} +func NewABCIClient(cc grpc1.ClientConn) ABCIClient { + return &aBCIClient{cc} } -func (c *aBCIApplicationClient) Echo(ctx context.Context, in *RequestEcho, opts ...grpc.CallOption) (*ResponseEcho, error) { +func (c *aBCIClient) Echo(ctx context.Context, in *RequestEcho, opts ...grpc.CallOption) (*ResponseEcho, error) { out := new(ResponseEcho) - err := c.cc.Invoke(ctx, "/tendermint.abci.ABCIApplication/Echo", in, out, opts...) + err := c.cc.Invoke(ctx, "/tendermint.abci.ABCI/Echo", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *aBCIApplicationClient) Flush(ctx context.Context, in *RequestFlush, opts ...grpc.CallOption) (*ResponseFlush, error) { +func (c *aBCIClient) Flush(ctx context.Context, in *RequestFlush, opts ...grpc.CallOption) (*ResponseFlush, error) { out := new(ResponseFlush) - err := c.cc.Invoke(ctx, "/tendermint.abci.ABCIApplication/Flush", in, out, opts...) + err := c.cc.Invoke(ctx, "/tendermint.abci.ABCI/Flush", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *aBCIApplicationClient) Info(ctx context.Context, in *RequestInfo, opts ...grpc.CallOption) (*ResponseInfo, error) { +func (c *aBCIClient) Info(ctx context.Context, in *RequestInfo, opts ...grpc.CallOption) (*ResponseInfo, error) { out := new(ResponseInfo) - err := c.cc.Invoke(ctx, "/tendermint.abci.ABCIApplication/Info", in, out, opts...) + err := c.cc.Invoke(ctx, "/tendermint.abci.ABCI/Info", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *aBCIApplicationClient) DeliverTx(ctx context.Context, in *RequestDeliverTx, opts ...grpc.CallOption) (*ResponseDeliverTx, error) { - out := new(ResponseDeliverTx) - err := c.cc.Invoke(ctx, "/tendermint.abci.ABCIApplication/DeliverTx", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *aBCIApplicationClient) CheckTx(ctx context.Context, in *RequestCheckTx, opts ...grpc.CallOption) (*ResponseCheckTx, error) { +func (c *aBCIClient) CheckTx(ctx context.Context, in *RequestCheckTx, opts ...grpc.CallOption) (*ResponseCheckTx, error) { out := new(ResponseCheckTx) - err := c.cc.Invoke(ctx, "/tendermint.abci.ABCIApplication/CheckTx", in, out, opts...) + err := c.cc.Invoke(ctx, "/tendermint.abci.ABCI/CheckTx", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *aBCIApplicationClient) Query(ctx context.Context, in *RequestQuery, opts ...grpc.CallOption) (*ResponseQuery, error) { +func (c *aBCIClient) Query(ctx context.Context, in *RequestQuery, opts ...grpc.CallOption) (*ResponseQuery, error) { out := new(ResponseQuery) - err := c.cc.Invoke(ctx, "/tendermint.abci.ABCIApplication/Query", in, out, opts...) + err := c.cc.Invoke(ctx, "/tendermint.abci.ABCI/Query", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *aBCIApplicationClient) Commit(ctx context.Context, in *RequestCommit, opts ...grpc.CallOption) (*ResponseCommit, error) { +func (c *aBCIClient) Commit(ctx context.Context, in *RequestCommit, opts ...grpc.CallOption) (*ResponseCommit, error) { out := new(ResponseCommit) - err := c.cc.Invoke(ctx, "/tendermint.abci.ABCIApplication/Commit", in, out, opts...) + err := c.cc.Invoke(ctx, "/tendermint.abci.ABCI/Commit", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *aBCIApplicationClient) InitChain(ctx context.Context, in *RequestInitChain, opts ...grpc.CallOption) (*ResponseInitChain, error) { +func (c *aBCIClient) InitChain(ctx context.Context, in *RequestInitChain, opts ...grpc.CallOption) (*ResponseInitChain, error) { out := new(ResponseInitChain) - err := c.cc.Invoke(ctx, "/tendermint.abci.ABCIApplication/InitChain", in, out, opts...) + err := c.cc.Invoke(ctx, "/tendermint.abci.ABCI/InitChain", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *aBCIApplicationClient) BeginBlock(ctx context.Context, in *RequestBeginBlock, opts ...grpc.CallOption) (*ResponseBeginBlock, error) { - out := new(ResponseBeginBlock) - err := c.cc.Invoke(ctx, "/tendermint.abci.ABCIApplication/BeginBlock", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *aBCIApplicationClient) EndBlock(ctx context.Context, in *RequestEndBlock, opts ...grpc.CallOption) (*ResponseEndBlock, error) { - out := new(ResponseEndBlock) - err := c.cc.Invoke(ctx, "/tendermint.abci.ABCIApplication/EndBlock", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *aBCIApplicationClient) ListSnapshots(ctx context.Context, in *RequestListSnapshots, opts ...grpc.CallOption) (*ResponseListSnapshots, error) { +func (c *aBCIClient) ListSnapshots(ctx context.Context, in *RequestListSnapshots, opts ...grpc.CallOption) (*ResponseListSnapshots, error) { out := new(ResponseListSnapshots) - err := c.cc.Invoke(ctx, "/tendermint.abci.ABCIApplication/ListSnapshots", in, out, opts...) + err := c.cc.Invoke(ctx, "/tendermint.abci.ABCI/ListSnapshots", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *aBCIApplicationClient) OfferSnapshot(ctx context.Context, in *RequestOfferSnapshot, opts ...grpc.CallOption) (*ResponseOfferSnapshot, error) { +func (c *aBCIClient) OfferSnapshot(ctx context.Context, in *RequestOfferSnapshot, opts ...grpc.CallOption) (*ResponseOfferSnapshot, error) { out := new(ResponseOfferSnapshot) - err := c.cc.Invoke(ctx, "/tendermint.abci.ABCIApplication/OfferSnapshot", in, out, opts...) + err := c.cc.Invoke(ctx, "/tendermint.abci.ABCI/OfferSnapshot", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *aBCIApplicationClient) LoadSnapshotChunk(ctx context.Context, in *RequestLoadSnapshotChunk, opts ...grpc.CallOption) (*ResponseLoadSnapshotChunk, error) { +func (c *aBCIClient) LoadSnapshotChunk(ctx context.Context, in *RequestLoadSnapshotChunk, opts ...grpc.CallOption) (*ResponseLoadSnapshotChunk, error) { out := new(ResponseLoadSnapshotChunk) - err := c.cc.Invoke(ctx, "/tendermint.abci.ABCIApplication/LoadSnapshotChunk", in, out, opts...) + err := c.cc.Invoke(ctx, "/tendermint.abci.ABCI/LoadSnapshotChunk", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *aBCIApplicationClient) ApplySnapshotChunk(ctx context.Context, in *RequestApplySnapshotChunk, opts ...grpc.CallOption) (*ResponseApplySnapshotChunk, error) { +func (c *aBCIClient) ApplySnapshotChunk(ctx context.Context, in *RequestApplySnapshotChunk, opts ...grpc.CallOption) (*ResponseApplySnapshotChunk, error) { out := new(ResponseApplySnapshotChunk) - err := c.cc.Invoke(ctx, "/tendermint.abci.ABCIApplication/ApplySnapshotChunk", in, out, opts...) + err := c.cc.Invoke(ctx, "/tendermint.abci.ABCI/ApplySnapshotChunk", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *aBCIApplicationClient) PrepareProposal(ctx context.Context, in *RequestPrepareProposal, opts ...grpc.CallOption) (*ResponsePrepareProposal, error) { +func (c *aBCIClient) PrepareProposal(ctx context.Context, in *RequestPrepareProposal, opts ...grpc.CallOption) (*ResponsePrepareProposal, error) { out := new(ResponsePrepareProposal) - err := c.cc.Invoke(ctx, "/tendermint.abci.ABCIApplication/PrepareProposal", in, out, opts...) + err := c.cc.Invoke(ctx, "/tendermint.abci.ABCI/PrepareProposal", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *aBCIApplicationClient) ProcessProposal(ctx context.Context, in *RequestProcessProposal, opts ...grpc.CallOption) (*ResponseProcessProposal, error) { +func (c *aBCIClient) ProcessProposal(ctx context.Context, in *RequestProcessProposal, opts ...grpc.CallOption) (*ResponseProcessProposal, error) { out := new(ResponseProcessProposal) - err := c.cc.Invoke(ctx, "/tendermint.abci.ABCIApplication/ProcessProposal", in, out, opts...) + err := c.cc.Invoke(ctx, "/tendermint.abci.ABCI/ProcessProposal", in, out, opts...) if err != nil { return nil, err } return out, nil } -// ABCIApplicationServer is the server API for ABCIApplication service. -type ABCIApplicationServer interface { +func (c *aBCIClient) FinalizeBlock(ctx context.Context, in *RequestFinalizeBlock, opts ...grpc.CallOption) (*ResponseFinalizeBlock, error) { + out := new(ResponseFinalizeBlock) + err := c.cc.Invoke(ctx, "/tendermint.abci.ABCI/FinalizeBlock", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ABCIServer is the server API for ABCI service. +type ABCIServer interface { Echo(context.Context, *RequestEcho) (*ResponseEcho, error) Flush(context.Context, *RequestFlush) (*ResponseFlush, error) Info(context.Context, *RequestInfo) (*ResponseInfo, error) - DeliverTx(context.Context, *RequestDeliverTx) (*ResponseDeliverTx, error) CheckTx(context.Context, *RequestCheckTx) (*ResponseCheckTx, error) Query(context.Context, *RequestQuery) (*ResponseQuery, error) Commit(context.Context, *RequestCommit) (*ResponseCommit, error) InitChain(context.Context, *RequestInitChain) (*ResponseInitChain, error) - BeginBlock(context.Context, *RequestBeginBlock) (*ResponseBeginBlock, error) - EndBlock(context.Context, *RequestEndBlock) (*ResponseEndBlock, error) ListSnapshots(context.Context, *RequestListSnapshots) (*ResponseListSnapshots, error) OfferSnapshot(context.Context, *RequestOfferSnapshot) (*ResponseOfferSnapshot, error) LoadSnapshotChunk(context.Context, *RequestLoadSnapshotChunk) (*ResponseLoadSnapshotChunk, error) ApplySnapshotChunk(context.Context, *RequestApplySnapshotChunk) (*ResponseApplySnapshotChunk, error) PrepareProposal(context.Context, *RequestPrepareProposal) (*ResponsePrepareProposal, error) ProcessProposal(context.Context, *RequestProcessProposal) (*ResponseProcessProposal, error) + FinalizeBlock(context.Context, *RequestFinalizeBlock) (*ResponseFinalizeBlock, error) } -// UnimplementedABCIApplicationServer can be embedded to have forward compatible implementations. -type UnimplementedABCIApplicationServer struct { +// UnimplementedABCIServer can be embedded to have forward compatible implementations. +type UnimplementedABCIServer struct { } -func (*UnimplementedABCIApplicationServer) Echo(ctx context.Context, req *RequestEcho) (*ResponseEcho, error) { +func (*UnimplementedABCIServer) Echo(ctx context.Context, req *RequestEcho) (*ResponseEcho, error) { return nil, status.Errorf(codes.Unimplemented, "method Echo not implemented") } -func (*UnimplementedABCIApplicationServer) Flush(ctx context.Context, req *RequestFlush) (*ResponseFlush, error) { +func (*UnimplementedABCIServer) Flush(ctx context.Context, req *RequestFlush) (*ResponseFlush, error) { return nil, status.Errorf(codes.Unimplemented, "method Flush not implemented") } -func (*UnimplementedABCIApplicationServer) Info(ctx context.Context, req *RequestInfo) (*ResponseInfo, error) { +func (*UnimplementedABCIServer) Info(ctx context.Context, req *RequestInfo) (*ResponseInfo, error) { return nil, status.Errorf(codes.Unimplemented, "method Info not implemented") } -func (*UnimplementedABCIApplicationServer) DeliverTx(ctx context.Context, req *RequestDeliverTx) (*ResponseDeliverTx, error) { - return nil, status.Errorf(codes.Unimplemented, "method DeliverTx not implemented") -} -func (*UnimplementedABCIApplicationServer) CheckTx(ctx context.Context, req *RequestCheckTx) (*ResponseCheckTx, error) { +func (*UnimplementedABCIServer) CheckTx(ctx context.Context, req *RequestCheckTx) (*ResponseCheckTx, error) { return nil, status.Errorf(codes.Unimplemented, "method CheckTx not implemented") } -func (*UnimplementedABCIApplicationServer) Query(ctx context.Context, req *RequestQuery) (*ResponseQuery, error) { +func (*UnimplementedABCIServer) Query(ctx context.Context, req *RequestQuery) (*ResponseQuery, error) { return nil, status.Errorf(codes.Unimplemented, "method Query not implemented") } -func (*UnimplementedABCIApplicationServer) Commit(ctx context.Context, req *RequestCommit) (*ResponseCommit, error) { +func (*UnimplementedABCIServer) Commit(ctx context.Context, req *RequestCommit) (*ResponseCommit, error) { return nil, status.Errorf(codes.Unimplemented, "method Commit not implemented") } -func (*UnimplementedABCIApplicationServer) InitChain(ctx context.Context, req *RequestInitChain) (*ResponseInitChain, error) { +func (*UnimplementedABCIServer) InitChain(ctx context.Context, req *RequestInitChain) (*ResponseInitChain, error) { return nil, status.Errorf(codes.Unimplemented, "method InitChain not implemented") } -func (*UnimplementedABCIApplicationServer) BeginBlock(ctx context.Context, req *RequestBeginBlock) (*ResponseBeginBlock, error) { - return nil, status.Errorf(codes.Unimplemented, "method BeginBlock not implemented") -} -func (*UnimplementedABCIApplicationServer) EndBlock(ctx context.Context, req *RequestEndBlock) (*ResponseEndBlock, error) { - return nil, status.Errorf(codes.Unimplemented, "method EndBlock not implemented") -} -func (*UnimplementedABCIApplicationServer) ListSnapshots(ctx context.Context, req *RequestListSnapshots) (*ResponseListSnapshots, error) { +func (*UnimplementedABCIServer) ListSnapshots(ctx context.Context, req *RequestListSnapshots) (*ResponseListSnapshots, error) { return nil, status.Errorf(codes.Unimplemented, "method ListSnapshots not implemented") } -func (*UnimplementedABCIApplicationServer) OfferSnapshot(ctx context.Context, req *RequestOfferSnapshot) (*ResponseOfferSnapshot, error) { +func (*UnimplementedABCIServer) OfferSnapshot(ctx context.Context, req *RequestOfferSnapshot) (*ResponseOfferSnapshot, error) { return nil, status.Errorf(codes.Unimplemented, "method OfferSnapshot not implemented") } -func (*UnimplementedABCIApplicationServer) LoadSnapshotChunk(ctx context.Context, req *RequestLoadSnapshotChunk) (*ResponseLoadSnapshotChunk, error) { +func (*UnimplementedABCIServer) LoadSnapshotChunk(ctx context.Context, req *RequestLoadSnapshotChunk) (*ResponseLoadSnapshotChunk, error) { return nil, status.Errorf(codes.Unimplemented, "method LoadSnapshotChunk not implemented") } -func (*UnimplementedABCIApplicationServer) ApplySnapshotChunk(ctx context.Context, req *RequestApplySnapshotChunk) (*ResponseApplySnapshotChunk, error) { +func (*UnimplementedABCIServer) ApplySnapshotChunk(ctx context.Context, req *RequestApplySnapshotChunk) (*ResponseApplySnapshotChunk, error) { return nil, status.Errorf(codes.Unimplemented, "method ApplySnapshotChunk not implemented") } -func (*UnimplementedABCIApplicationServer) PrepareProposal(ctx context.Context, req *RequestPrepareProposal) (*ResponsePrepareProposal, error) { +func (*UnimplementedABCIServer) PrepareProposal(ctx context.Context, req *RequestPrepareProposal) (*ResponsePrepareProposal, error) { return nil, status.Errorf(codes.Unimplemented, "method PrepareProposal not implemented") } -func (*UnimplementedABCIApplicationServer) ProcessProposal(ctx context.Context, req *RequestProcessProposal) (*ResponseProcessProposal, error) { +func (*UnimplementedABCIServer) ProcessProposal(ctx context.Context, req *RequestProcessProposal) (*ResponseProcessProposal, error) { return nil, status.Errorf(codes.Unimplemented, "method ProcessProposal not implemented") } - -func RegisterABCIApplicationServer(s grpc1.Server, srv ABCIApplicationServer) { - s.RegisterService(&_ABCIApplication_serviceDesc, srv) +func (*UnimplementedABCIServer) FinalizeBlock(ctx context.Context, req *RequestFinalizeBlock) (*ResponseFinalizeBlock, error) { + return nil, status.Errorf(codes.Unimplemented, "method FinalizeBlock not implemented") } -func _ABCIApplication_Echo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func RegisterABCIServer(s grpc1.Server, srv ABCIServer) { + s.RegisterService(&_ABCI_serviceDesc, srv) +} + +func _ABCI_Echo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RequestEcho) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ABCIApplicationServer).Echo(ctx, in) + return srv.(ABCIServer).Echo(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/tendermint.abci.ABCIApplication/Echo", + FullMethod: "/tendermint.abci.ABCI/Echo", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ABCIApplicationServer).Echo(ctx, req.(*RequestEcho)) + return srv.(ABCIServer).Echo(ctx, req.(*RequestEcho)) } return interceptor(ctx, in, info, handler) } -func _ABCIApplication_Flush_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _ABCI_Flush_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RequestFlush) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ABCIApplicationServer).Flush(ctx, in) + return srv.(ABCIServer).Flush(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/tendermint.abci.ABCIApplication/Flush", + FullMethod: "/tendermint.abci.ABCI/Flush", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ABCIApplicationServer).Flush(ctx, req.(*RequestFlush)) + return srv.(ABCIServer).Flush(ctx, req.(*RequestFlush)) } return interceptor(ctx, in, info, handler) } -func _ABCIApplication_Info_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _ABCI_Info_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RequestInfo) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ABCIApplicationServer).Info(ctx, in) + return srv.(ABCIServer).Info(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/tendermint.abci.ABCIApplication/Info", + FullMethod: "/tendermint.abci.ABCI/Info", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ABCIApplicationServer).Info(ctx, req.(*RequestInfo)) + return srv.(ABCIServer).Info(ctx, req.(*RequestInfo)) } return interceptor(ctx, in, info, handler) } -func _ABCIApplication_DeliverTx_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(RequestDeliverTx) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ABCIApplicationServer).DeliverTx(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/tendermint.abci.ABCIApplication/DeliverTx", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ABCIApplicationServer).DeliverTx(ctx, req.(*RequestDeliverTx)) - } - return interceptor(ctx, in, info, handler) -} - -func _ABCIApplication_CheckTx_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _ABCI_CheckTx_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RequestCheckTx) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ABCIApplicationServer).CheckTx(ctx, in) + return srv.(ABCIServer).CheckTx(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/tendermint.abci.ABCIApplication/CheckTx", + FullMethod: "/tendermint.abci.ABCI/CheckTx", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ABCIApplicationServer).CheckTx(ctx, req.(*RequestCheckTx)) + return srv.(ABCIServer).CheckTx(ctx, req.(*RequestCheckTx)) } return interceptor(ctx, in, info, handler) } -func _ABCIApplication_Query_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _ABCI_Query_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RequestQuery) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ABCIApplicationServer).Query(ctx, in) + return srv.(ABCIServer).Query(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/tendermint.abci.ABCIApplication/Query", + FullMethod: "/tendermint.abci.ABCI/Query", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ABCIApplicationServer).Query(ctx, req.(*RequestQuery)) + return srv.(ABCIServer).Query(ctx, req.(*RequestQuery)) } return interceptor(ctx, in, info, handler) } -func _ABCIApplication_Commit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _ABCI_Commit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RequestCommit) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ABCIApplicationServer).Commit(ctx, in) + return srv.(ABCIServer).Commit(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/tendermint.abci.ABCIApplication/Commit", + FullMethod: "/tendermint.abci.ABCI/Commit", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ABCIApplicationServer).Commit(ctx, req.(*RequestCommit)) + return srv.(ABCIServer).Commit(ctx, req.(*RequestCommit)) } return interceptor(ctx, in, info, handler) } -func _ABCIApplication_InitChain_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _ABCI_InitChain_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RequestInitChain) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ABCIApplicationServer).InitChain(ctx, in) + return srv.(ABCIServer).InitChain(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/tendermint.abci.ABCIApplication/InitChain", + FullMethod: "/tendermint.abci.ABCI/InitChain", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ABCIApplicationServer).InitChain(ctx, req.(*RequestInitChain)) + return srv.(ABCIServer).InitChain(ctx, req.(*RequestInitChain)) } return interceptor(ctx, in, info, handler) } -func _ABCIApplication_BeginBlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(RequestBeginBlock) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ABCIApplicationServer).BeginBlock(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/tendermint.abci.ABCIApplication/BeginBlock", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ABCIApplicationServer).BeginBlock(ctx, req.(*RequestBeginBlock)) - } - return interceptor(ctx, in, info, handler) -} - -func _ABCIApplication_EndBlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(RequestEndBlock) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ABCIApplicationServer).EndBlock(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/tendermint.abci.ABCIApplication/EndBlock", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ABCIApplicationServer).EndBlock(ctx, req.(*RequestEndBlock)) - } - return interceptor(ctx, in, info, handler) -} - -func _ABCIApplication_ListSnapshots_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _ABCI_ListSnapshots_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RequestListSnapshots) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ABCIApplicationServer).ListSnapshots(ctx, in) + return srv.(ABCIServer).ListSnapshots(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/tendermint.abci.ABCIApplication/ListSnapshots", + FullMethod: "/tendermint.abci.ABCI/ListSnapshots", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ABCIApplicationServer).ListSnapshots(ctx, req.(*RequestListSnapshots)) + return srv.(ABCIServer).ListSnapshots(ctx, req.(*RequestListSnapshots)) } return interceptor(ctx, in, info, handler) } -func _ABCIApplication_OfferSnapshot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _ABCI_OfferSnapshot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RequestOfferSnapshot) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ABCIApplicationServer).OfferSnapshot(ctx, in) + return srv.(ABCIServer).OfferSnapshot(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/tendermint.abci.ABCIApplication/OfferSnapshot", + FullMethod: "/tendermint.abci.ABCI/OfferSnapshot", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ABCIApplicationServer).OfferSnapshot(ctx, req.(*RequestOfferSnapshot)) + return srv.(ABCIServer).OfferSnapshot(ctx, req.(*RequestOfferSnapshot)) } return interceptor(ctx, in, info, handler) } -func _ABCIApplication_LoadSnapshotChunk_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _ABCI_LoadSnapshotChunk_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RequestLoadSnapshotChunk) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ABCIApplicationServer).LoadSnapshotChunk(ctx, in) + return srv.(ABCIServer).LoadSnapshotChunk(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/tendermint.abci.ABCIApplication/LoadSnapshotChunk", + FullMethod: "/tendermint.abci.ABCI/LoadSnapshotChunk", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ABCIApplicationServer).LoadSnapshotChunk(ctx, req.(*RequestLoadSnapshotChunk)) + return srv.(ABCIServer).LoadSnapshotChunk(ctx, req.(*RequestLoadSnapshotChunk)) } return interceptor(ctx, in, info, handler) } -func _ABCIApplication_ApplySnapshotChunk_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _ABCI_ApplySnapshotChunk_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RequestApplySnapshotChunk) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ABCIApplicationServer).ApplySnapshotChunk(ctx, in) + return srv.(ABCIServer).ApplySnapshotChunk(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/tendermint.abci.ABCIApplication/ApplySnapshotChunk", + FullMethod: "/tendermint.abci.ABCI/ApplySnapshotChunk", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ABCIApplicationServer).ApplySnapshotChunk(ctx, req.(*RequestApplySnapshotChunk)) + return srv.(ABCIServer).ApplySnapshotChunk(ctx, req.(*RequestApplySnapshotChunk)) } return interceptor(ctx, in, info, handler) } -func _ABCIApplication_PrepareProposal_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _ABCI_PrepareProposal_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RequestPrepareProposal) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ABCIApplicationServer).PrepareProposal(ctx, in) + return srv.(ABCIServer).PrepareProposal(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/tendermint.abci.ABCIApplication/PrepareProposal", + FullMethod: "/tendermint.abci.ABCI/PrepareProposal", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ABCIApplicationServer).PrepareProposal(ctx, req.(*RequestPrepareProposal)) + return srv.(ABCIServer).PrepareProposal(ctx, req.(*RequestPrepareProposal)) } return interceptor(ctx, in, info, handler) } -func _ABCIApplication_ProcessProposal_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _ABCI_ProcessProposal_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RequestProcessProposal) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ABCIApplicationServer).ProcessProposal(ctx, in) + return srv.(ABCIServer).ProcessProposal(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/tendermint.abci.ABCIApplication/ProcessProposal", + FullMethod: "/tendermint.abci.ABCI/ProcessProposal", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ABCIApplicationServer).ProcessProposal(ctx, req.(*RequestProcessProposal)) + return srv.(ABCIServer).ProcessProposal(ctx, req.(*RequestProcessProposal)) } return interceptor(ctx, in, info, handler) } -var _ABCIApplication_serviceDesc = grpc.ServiceDesc{ - ServiceName: "tendermint.abci.ABCIApplication", - HandlerType: (*ABCIApplicationServer)(nil), +func _ABCI_FinalizeBlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RequestFinalizeBlock) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ABCIServer).FinalizeBlock(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/tendermint.abci.ABCI/FinalizeBlock", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ABCIServer).FinalizeBlock(ctx, req.(*RequestFinalizeBlock)) + } + return interceptor(ctx, in, info, handler) +} + +var _ABCI_serviceDesc = grpc.ServiceDesc{ + ServiceName: "tendermint.abci.ABCI", + HandlerType: (*ABCIServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "Echo", - Handler: _ABCIApplication_Echo_Handler, + Handler: _ABCI_Echo_Handler, }, { MethodName: "Flush", - Handler: _ABCIApplication_Flush_Handler, + Handler: _ABCI_Flush_Handler, }, { MethodName: "Info", - Handler: _ABCIApplication_Info_Handler, - }, - { - MethodName: "DeliverTx", - Handler: _ABCIApplication_DeliverTx_Handler, + Handler: _ABCI_Info_Handler, }, { MethodName: "CheckTx", - Handler: _ABCIApplication_CheckTx_Handler, + Handler: _ABCI_CheckTx_Handler, }, { MethodName: "Query", - Handler: _ABCIApplication_Query_Handler, + Handler: _ABCI_Query_Handler, }, { MethodName: "Commit", - Handler: _ABCIApplication_Commit_Handler, + Handler: _ABCI_Commit_Handler, }, { MethodName: "InitChain", - Handler: _ABCIApplication_InitChain_Handler, - }, - { - MethodName: "BeginBlock", - Handler: _ABCIApplication_BeginBlock_Handler, - }, - { - MethodName: "EndBlock", - Handler: _ABCIApplication_EndBlock_Handler, + Handler: _ABCI_InitChain_Handler, }, { MethodName: "ListSnapshots", - Handler: _ABCIApplication_ListSnapshots_Handler, + Handler: _ABCI_ListSnapshots_Handler, }, { MethodName: "OfferSnapshot", - Handler: _ABCIApplication_OfferSnapshot_Handler, + Handler: _ABCI_OfferSnapshot_Handler, }, { MethodName: "LoadSnapshotChunk", - Handler: _ABCIApplication_LoadSnapshotChunk_Handler, + Handler: _ABCI_LoadSnapshotChunk_Handler, }, { MethodName: "ApplySnapshotChunk", - Handler: _ABCIApplication_ApplySnapshotChunk_Handler, + Handler: _ABCI_ApplySnapshotChunk_Handler, }, { MethodName: "PrepareProposal", - Handler: _ABCIApplication_PrepareProposal_Handler, + Handler: _ABCI_PrepareProposal_Handler, }, { MethodName: "ProcessProposal", - Handler: _ABCIApplication_ProcessProposal_Handler, + Handler: _ABCI_ProcessProposal_Handler, + }, + { + MethodName: "FinalizeBlock", + Handler: _ABCI_FinalizeBlock_Handler, }, }, Streams: []grpc.StreamDesc{}, @@ -4409,27 +4198,6 @@ func (m *Request_Query) MarshalToSizedBuffer(dAtA []byte) (int, error) { } return len(dAtA) - i, nil } -func (m *Request_BeginBlock) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Request_BeginBlock) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.BeginBlock != nil { - { - size, err := m.BeginBlock.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTypes(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x3a - } - return len(dAtA) - i, nil -} func (m *Request_CheckTx) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) @@ -4451,48 +4219,6 @@ func (m *Request_CheckTx) MarshalToSizedBuffer(dAtA []byte) (int, error) { } return len(dAtA) - i, nil } -func (m *Request_DeliverTx) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Request_DeliverTx) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.DeliverTx != nil { - { - size, err := m.DeliverTx.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTypes(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x4a - } - return len(dAtA) - i, nil -} -func (m *Request_EndBlock) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Request_EndBlock) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.EndBlock != nil { - { - size, err := m.EndBlock.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTypes(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x52 - } - return len(dAtA) - i, nil -} func (m *Request_Commit) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) @@ -4644,6 +4370,29 @@ func (m *Request_ProcessProposal) MarshalToSizedBuffer(dAtA []byte) (int, error) } return len(dAtA) - i, nil } +func (m *Request_FinalizeBlock) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Request_FinalizeBlock) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.FinalizeBlock != nil { + { + size, err := m.FinalizeBlock.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xa2 + } + return len(dAtA) - i, nil +} func (m *RequestEcho) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -4809,12 +4558,12 @@ func (m *RequestInitChain) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x12 } - n18, err18 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Time):]) - if err18 != nil { - return 0, err18 + n16, err16 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Time):]) + if err16 != nil { + return 0, err16 } - i -= n18 - i = encodeVarintTypes(dAtA, i, uint64(n18)) + i -= n16 + i = encodeVarintTypes(dAtA, i, uint64(n16)) i-- dAtA[i] = 0xa return len(dAtA) - i, nil @@ -4872,70 +4621,6 @@ func (m *RequestQuery) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *RequestBeginBlock) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *RequestBeginBlock) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *RequestBeginBlock) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.ByzantineValidators) > 0 { - for iNdEx := len(m.ByzantineValidators) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.ByzantineValidators[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTypes(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x22 - } - } - { - size, err := m.LastCommitInfo.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTypes(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - { - size, err := m.Header.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTypes(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - if len(m.Hash) > 0 { - i -= len(m.Hash) - copy(dAtA[i:], m.Hash) - i = encodeVarintTypes(dAtA, i, uint64(len(m.Hash))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - func (m *RequestCheckTx) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -4971,64 +4656,6 @@ func (m *RequestCheckTx) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *RequestDeliverTx) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *RequestDeliverTx) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *RequestDeliverTx) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Tx) > 0 { - i -= len(m.Tx) - copy(dAtA[i:], m.Tx) - i = encodeVarintTypes(dAtA, i, uint64(len(m.Tx))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *RequestEndBlock) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *RequestEndBlock) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *RequestEndBlock) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Height != 0 { - i = encodeVarintTypes(dAtA, i, uint64(m.Height)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - func (m *RequestCommit) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -5231,12 +4858,12 @@ func (m *RequestPrepareProposal) MarshalToSizedBuffer(dAtA []byte) (int, error) i-- dAtA[i] = 0x3a } - n22, err22 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Time):]) - if err22 != nil { - return 0, err22 + n18, err18 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Time):]) + if err18 != nil { + return 0, err18 } - i -= n22 - i = encodeVarintTypes(dAtA, i, uint64(n22)) + i -= n18 + i = encodeVarintTypes(dAtA, i, uint64(n18)) i-- dAtA[i] = 0x32 if m.Height != 0 { @@ -5319,12 +4946,12 @@ func (m *RequestProcessProposal) MarshalToSizedBuffer(dAtA []byte) (int, error) i-- dAtA[i] = 0x3a } - n24, err24 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Time):]) - if err24 != nil { - return 0, err24 + n20, err20 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Time):]) + if err20 != nil { + return 0, err20 } - i -= n24 - i = encodeVarintTypes(dAtA, i, uint64(n24)) + i -= n20 + i = encodeVarintTypes(dAtA, i, uint64(n20)) i-- dAtA[i] = 0x32 if m.Height != 0 { @@ -5375,6 +5002,96 @@ func (m *RequestProcessProposal) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } +func (m *RequestFinalizeBlock) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RequestFinalizeBlock) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RequestFinalizeBlock) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ProposerAddress) > 0 { + i -= len(m.ProposerAddress) + copy(dAtA[i:], m.ProposerAddress) + i = encodeVarintTypes(dAtA, i, uint64(len(m.ProposerAddress))) + i-- + dAtA[i] = 0x42 + } + if len(m.NextValidatorsHash) > 0 { + i -= len(m.NextValidatorsHash) + copy(dAtA[i:], m.NextValidatorsHash) + i = encodeVarintTypes(dAtA, i, uint64(len(m.NextValidatorsHash))) + i-- + dAtA[i] = 0x3a + } + n22, err22 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Time):]) + if err22 != nil { + return 0, err22 + } + i -= n22 + i = encodeVarintTypes(dAtA, i, uint64(n22)) + i-- + dAtA[i] = 0x32 + if m.Height != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Height)) + i-- + dAtA[i] = 0x28 + } + if len(m.Hash) > 0 { + i -= len(m.Hash) + copy(dAtA[i:], m.Hash) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Hash))) + i-- + dAtA[i] = 0x22 + } + if len(m.Misbehavior) > 0 { + for iNdEx := len(m.Misbehavior) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Misbehavior[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + { + size, err := m.DecidedLastCommit.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.Txs) > 0 { + for iNdEx := len(m.Txs) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Txs[iNdEx]) + copy(dAtA[i:], m.Txs[iNdEx]) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Txs[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func (m *Response) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -5533,27 +5250,6 @@ func (m *Response_Query) MarshalToSizedBuffer(dAtA []byte) (int, error) { } return len(dAtA) - i, nil } -func (m *Response_BeginBlock) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Response_BeginBlock) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.BeginBlock != nil { - { - size, err := m.BeginBlock.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTypes(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x42 - } - return len(dAtA) - i, nil -} func (m *Response_CheckTx) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) @@ -5575,48 +5271,6 @@ func (m *Response_CheckTx) MarshalToSizedBuffer(dAtA []byte) (int, error) { } return len(dAtA) - i, nil } -func (m *Response_DeliverTx) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Response_DeliverTx) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.DeliverTx != nil { - { - size, err := m.DeliverTx.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTypes(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x52 - } - return len(dAtA) - i, nil -} -func (m *Response_EndBlock) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Response_EndBlock) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.EndBlock != nil { - { - size, err := m.EndBlock.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTypes(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x5a - } - return len(dAtA) - i, nil -} func (m *Response_Commit) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) @@ -5770,6 +5424,29 @@ func (m *Response_ProcessProposal) MarshalToSizedBuffer(dAtA []byte) (int, error } return len(dAtA) - i, nil } +func (m *Response_FinalizeBlock) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Response_FinalizeBlock) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.FinalizeBlock != nil { + { + size, err := m.FinalizeBlock.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xaa + } + return len(dAtA) - i, nil +} func (m *ResponseException) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -6048,43 +5725,6 @@ func (m *ResponseQuery) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *ResponseBeginBlock) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ResponseBeginBlock) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ResponseBeginBlock) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Events) > 0 { - for iNdEx := len(m.Events) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Events[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTypes(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - func (m *ResponseCheckTx) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -6184,149 +5824,6 @@ func (m *ResponseCheckTx) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *ResponseDeliverTx) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ResponseDeliverTx) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ResponseDeliverTx) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Codespace) > 0 { - i -= len(m.Codespace) - copy(dAtA[i:], m.Codespace) - i = encodeVarintTypes(dAtA, i, uint64(len(m.Codespace))) - i-- - dAtA[i] = 0x42 - } - if len(m.Events) > 0 { - for iNdEx := len(m.Events) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Events[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTypes(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x3a - } - } - if m.GasUsed != 0 { - i = encodeVarintTypes(dAtA, i, uint64(m.GasUsed)) - i-- - dAtA[i] = 0x30 - } - if m.GasWanted != 0 { - i = encodeVarintTypes(dAtA, i, uint64(m.GasWanted)) - i-- - dAtA[i] = 0x28 - } - if len(m.Info) > 0 { - i -= len(m.Info) - copy(dAtA[i:], m.Info) - i = encodeVarintTypes(dAtA, i, uint64(len(m.Info))) - i-- - dAtA[i] = 0x22 - } - if len(m.Log) > 0 { - i -= len(m.Log) - copy(dAtA[i:], m.Log) - i = encodeVarintTypes(dAtA, i, uint64(len(m.Log))) - i-- - dAtA[i] = 0x1a - } - if len(m.Data) > 0 { - i -= len(m.Data) - copy(dAtA[i:], m.Data) - i = encodeVarintTypes(dAtA, i, uint64(len(m.Data))) - i-- - dAtA[i] = 0x12 - } - if m.Code != 0 { - i = encodeVarintTypes(dAtA, i, uint64(m.Code)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func (m *ResponseEndBlock) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ResponseEndBlock) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ResponseEndBlock) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Events) > 0 { - for iNdEx := len(m.Events) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Events[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTypes(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - } - if m.ConsensusParamUpdates != nil { - { - size, err := m.ConsensusParamUpdates.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTypes(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if len(m.ValidatorUpdates) > 0 { - for iNdEx := len(m.ValidatorUpdates) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.ValidatorUpdates[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTypes(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - func (m *ResponseCommit) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -6352,13 +5849,6 @@ func (m *ResponseCommit) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x18 } - if len(m.Data) > 0 { - i -= len(m.Data) - copy(dAtA[i:], m.Data) - i = encodeVarintTypes(dAtA, i, uint64(len(m.Data))) - i-- - dAtA[i] = 0x12 - } return len(dAtA) - i, nil } @@ -6487,20 +5977,20 @@ func (m *ResponseApplySnapshotChunk) MarshalToSizedBuffer(dAtA []byte) (int, err } } if len(m.RefetchChunks) > 0 { - dAtA47 := make([]byte, len(m.RefetchChunks)*10) - var j46 int + dAtA42 := make([]byte, len(m.RefetchChunks)*10) + var j41 int for _, num := range m.RefetchChunks { for num >= 1<<7 { - dAtA47[j46] = uint8(uint64(num)&0x7f | 0x80) + dAtA42[j41] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j46++ + j41++ } - dAtA47[j46] = uint8(num) - j46++ + dAtA42[j41] = uint8(num) + j41++ } - i -= j46 - copy(dAtA[i:], dAtA47[:j46]) - i = encodeVarintTypes(dAtA, i, uint64(j46)) + i -= j41 + copy(dAtA[i:], dAtA42[:j41]) + i = encodeVarintTypes(dAtA, i, uint64(j41)) i-- dAtA[i] = 0x12 } @@ -6572,6 +6062,90 @@ func (m *ResponseProcessProposal) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } +func (m *ResponseFinalizeBlock) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResponseFinalizeBlock) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResponseFinalizeBlock) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.AgreedAppData) > 0 { + i -= len(m.AgreedAppData) + copy(dAtA[i:], m.AgreedAppData) + i = encodeVarintTypes(dAtA, i, uint64(len(m.AgreedAppData))) + i-- + dAtA[i] = 0x2a + } + if m.ConsensusParamUpdates != nil { + { + size, err := m.ConsensusParamUpdates.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + if len(m.ValidatorUpdates) > 0 { + for iNdEx := len(m.ValidatorUpdates) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ValidatorUpdates[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.TxResults) > 0 { + for iNdEx := len(m.TxResults) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.TxResults[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.Events) > 0 { + for iNdEx := len(m.Events) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Events[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func (m *CommitInfo) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -6747,6 +6321,86 @@ func (m *EventAttribute) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ExecTxResult) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ExecTxResult) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ExecTxResult) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Codespace) > 0 { + i -= len(m.Codespace) + copy(dAtA[i:], m.Codespace) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Codespace))) + i-- + dAtA[i] = 0x42 + } + if len(m.Events) > 0 { + for iNdEx := len(m.Events) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Events[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + } + } + if m.GasUsed != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.GasUsed)) + i-- + dAtA[i] = 0x30 + } + if m.GasWanted != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.GasWanted)) + i-- + dAtA[i] = 0x28 + } + if len(m.Info) > 0 { + i -= len(m.Info) + copy(dAtA[i:], m.Info) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Info))) + i-- + dAtA[i] = 0x22 + } + if len(m.Log) > 0 { + i -= len(m.Log) + copy(dAtA[i:], m.Log) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Log))) + i-- + dAtA[i] = 0x1a + } + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0x12 + } + if m.Code != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Code)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func (m *TxResult) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -6988,12 +6642,12 @@ func (m *Misbehavior) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x28 } - n52, err52 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Time):]) - if err52 != nil { - return 0, err52 + n48, err48 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Time):]) + if err48 != nil { + return 0, err48 } - i -= n52 - i = encodeVarintTypes(dAtA, i, uint64(n52)) + i -= n48 + i = encodeVarintTypes(dAtA, i, uint64(n48)) i-- dAtA[i] = 0x22 if m.Height != 0 { @@ -7154,18 +6808,6 @@ func (m *Request_Query) Size() (n int) { } return n } -func (m *Request_BeginBlock) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.BeginBlock != nil { - l = m.BeginBlock.Size() - n += 1 + l + sovTypes(uint64(l)) - } - return n -} func (m *Request_CheckTx) Size() (n int) { if m == nil { return 0 @@ -7178,30 +6820,6 @@ func (m *Request_CheckTx) Size() (n int) { } return n } -func (m *Request_DeliverTx) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.DeliverTx != nil { - l = m.DeliverTx.Size() - n += 1 + l + sovTypes(uint64(l)) - } - return n -} -func (m *Request_EndBlock) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.EndBlock != nil { - l = m.EndBlock.Size() - n += 1 + l + sovTypes(uint64(l)) - } - return n -} func (m *Request_Commit) Size() (n int) { if m == nil { return 0 @@ -7286,6 +6904,18 @@ func (m *Request_ProcessProposal) Size() (n int) { } return n } +func (m *Request_FinalizeBlock) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.FinalizeBlock != nil { + l = m.FinalizeBlock.Size() + n += 2 + l + sovTypes(uint64(l)) + } + return n +} func (m *RequestEcho) Size() (n int) { if m == nil { return 0 @@ -7386,29 +7016,6 @@ func (m *RequestQuery) Size() (n int) { return n } -func (m *RequestBeginBlock) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Hash) - if l > 0 { - n += 1 + l + sovTypes(uint64(l)) - } - l = m.Header.Size() - n += 1 + l + sovTypes(uint64(l)) - l = m.LastCommitInfo.Size() - n += 1 + l + sovTypes(uint64(l)) - if len(m.ByzantineValidators) > 0 { - for _, e := range m.ByzantineValidators { - l = e.Size() - n += 1 + l + sovTypes(uint64(l)) - } - } - return n -} - func (m *RequestCheckTx) Size() (n int) { if m == nil { return 0 @@ -7425,31 +7032,6 @@ func (m *RequestCheckTx) Size() (n int) { return n } -func (m *RequestDeliverTx) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Tx) - if l > 0 { - n += 1 + l + sovTypes(uint64(l)) - } - return n -} - -func (m *RequestEndBlock) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Height != 0 { - n += 1 + sovTypes(uint64(m.Height)) - } - return n -} - func (m *RequestCommit) Size() (n int) { if m == nil { return 0 @@ -7602,6 +7184,46 @@ func (m *RequestProcessProposal) Size() (n int) { return n } +func (m *RequestFinalizeBlock) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Txs) > 0 { + for _, b := range m.Txs { + l = len(b) + n += 1 + l + sovTypes(uint64(l)) + } + } + l = m.DecidedLastCommit.Size() + n += 1 + l + sovTypes(uint64(l)) + if len(m.Misbehavior) > 0 { + for _, e := range m.Misbehavior { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + l = len(m.Hash) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.Height != 0 { + n += 1 + sovTypes(uint64(m.Height)) + } + l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Time) + n += 1 + l + sovTypes(uint64(l)) + l = len(m.NextValidatorsHash) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.ProposerAddress) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + return n +} + func (m *Response) Size() (n int) { if m == nil { return 0 @@ -7686,18 +7308,6 @@ func (m *Response_Query) Size() (n int) { } return n } -func (m *Response_BeginBlock) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.BeginBlock != nil { - l = m.BeginBlock.Size() - n += 1 + l + sovTypes(uint64(l)) - } - return n -} func (m *Response_CheckTx) Size() (n int) { if m == nil { return 0 @@ -7710,30 +7320,6 @@ func (m *Response_CheckTx) Size() (n int) { } return n } -func (m *Response_DeliverTx) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.DeliverTx != nil { - l = m.DeliverTx.Size() - n += 1 + l + sovTypes(uint64(l)) - } - return n -} -func (m *Response_EndBlock) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.EndBlock != nil { - l = m.EndBlock.Size() - n += 1 + l + sovTypes(uint64(l)) - } - return n -} func (m *Response_Commit) Size() (n int) { if m == nil { return 0 @@ -7818,6 +7404,18 @@ func (m *Response_ProcessProposal) Size() (n int) { } return n } +func (m *Response_FinalizeBlock) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.FinalizeBlock != nil { + l = m.FinalizeBlock.Size() + n += 2 + l + sovTypes(uint64(l)) + } + return n +} func (m *ResponseException) Size() (n int) { if m == nil { return 0 @@ -7945,21 +7543,6 @@ func (m *ResponseQuery) Size() (n int) { return n } -func (m *ResponseBeginBlock) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Events) > 0 { - for _, e := range m.Events { - l = e.Size() - n += 1 + l + sovTypes(uint64(l)) - } - } - return n -} - func (m *ResponseCheckTx) Size() (n int) { if m == nil { return 0 @@ -8011,81 +7594,12 @@ func (m *ResponseCheckTx) Size() (n int) { return n } -func (m *ResponseDeliverTx) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Code != 0 { - n += 1 + sovTypes(uint64(m.Code)) - } - l = len(m.Data) - if l > 0 { - n += 1 + l + sovTypes(uint64(l)) - } - l = len(m.Log) - if l > 0 { - n += 1 + l + sovTypes(uint64(l)) - } - l = len(m.Info) - if l > 0 { - n += 1 + l + sovTypes(uint64(l)) - } - if m.GasWanted != 0 { - n += 1 + sovTypes(uint64(m.GasWanted)) - } - if m.GasUsed != 0 { - n += 1 + sovTypes(uint64(m.GasUsed)) - } - if len(m.Events) > 0 { - for _, e := range m.Events { - l = e.Size() - n += 1 + l + sovTypes(uint64(l)) - } - } - l = len(m.Codespace) - if l > 0 { - n += 1 + l + sovTypes(uint64(l)) - } - return n -} - -func (m *ResponseEndBlock) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.ValidatorUpdates) > 0 { - for _, e := range m.ValidatorUpdates { - l = e.Size() - n += 1 + l + sovTypes(uint64(l)) - } - } - if m.ConsensusParamUpdates != nil { - l = m.ConsensusParamUpdates.Size() - n += 1 + l + sovTypes(uint64(l)) - } - if len(m.Events) > 0 { - for _, e := range m.Events { - l = e.Size() - n += 1 + l + sovTypes(uint64(l)) - } - } - return n -} - func (m *ResponseCommit) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = len(m.Data) - if l > 0 { - n += 1 + l + sovTypes(uint64(l)) - } if m.RetainHeight != 0 { n += 1 + sovTypes(uint64(m.RetainHeight)) } @@ -8184,6 +7698,41 @@ func (m *ResponseProcessProposal) Size() (n int) { return n } +func (m *ResponseFinalizeBlock) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Events) > 0 { + for _, e := range m.Events { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + if len(m.TxResults) > 0 { + for _, e := range m.TxResults { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + if len(m.ValidatorUpdates) > 0 { + for _, e := range m.ValidatorUpdates { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + if m.ConsensusParamUpdates != nil { + l = m.ConsensusParamUpdates.Size() + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.AgreedAppData) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + return n +} + func (m *CommitInfo) Size() (n int) { if m == nil { return 0 @@ -8259,6 +7808,46 @@ func (m *EventAttribute) Size() (n int) { return n } +func (m *ExecTxResult) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Code != 0 { + n += 1 + sovTypes(uint64(m.Code)) + } + l = len(m.Data) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.Log) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.Info) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.GasWanted != 0 { + n += 1 + sovTypes(uint64(m.GasWanted)) + } + if m.GasUsed != 0 { + n += 1 + sovTypes(uint64(m.GasUsed)) + } + if len(m.Events) > 0 { + for _, e := range m.Events { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + l = len(m.Codespace) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + return n +} + func (m *TxResult) Size() (n int) { if m == nil { return 0 @@ -8600,41 +8189,6 @@ func (m *Request) Unmarshal(dAtA []byte) error { } m.Value = &Request_Query{v} iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BeginBlock", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &RequestBeginBlock{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Value = &Request_BeginBlock{v} - iNdEx = postIndex case 8: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field CheckTx", wireType) @@ -8670,76 +8224,6 @@ func (m *Request) Unmarshal(dAtA []byte) error { } m.Value = &Request_CheckTx{v} iNdEx = postIndex - case 9: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DeliverTx", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &RequestDeliverTx{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Value = &Request_DeliverTx{v} - iNdEx = postIndex - case 10: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field EndBlock", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &RequestEndBlock{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Value = &Request_EndBlock{v} - iNdEx = postIndex case 11: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Commit", wireType) @@ -8985,6 +8469,41 @@ func (m *Request) Unmarshal(dAtA []byte) error { } m.Value = &Request_ProcessProposal{v} iNdEx = postIndex + case 20: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FinalizeBlock", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &RequestFinalizeBlock{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &Request_FinalizeBlock{v} + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -9683,190 +9202,6 @@ func (m *RequestQuery) Unmarshal(dAtA []byte) error { } return nil } -func (m *RequestBeginBlock) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: RequestBeginBlock: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: RequestBeginBlock: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Hash = append(m.Hash[:0], dAtA[iNdEx:postIndex]...) - if m.Hash == nil { - m.Hash = []byte{} - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field LastCommitInfo", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.LastCommitInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ByzantineValidators", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ByzantineValidators = append(m.ByzantineValidators, Misbehavior{}) - if err := m.ByzantineValidators[len(m.ByzantineValidators)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipTypes(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTypes - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func (m *RequestCheckTx) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -9970,159 +9305,6 @@ func (m *RequestCheckTx) Unmarshal(dAtA []byte) error { } return nil } -func (m *RequestDeliverTx) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: RequestDeliverTx: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: RequestDeliverTx: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Tx", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Tx = append(m.Tx[:0], dAtA[iNdEx:postIndex]...) - if m.Tx == nil { - m.Tx = []byte{} - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipTypes(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTypes - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *RequestEndBlock) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: RequestEndBlock: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: RequestEndBlock: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) - } - m.Height = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Height |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skipTypes(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTypes - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func (m *RequestCommit) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -11176,6 +10358,309 @@ func (m *RequestProcessProposal) Unmarshal(dAtA []byte) error { } return nil } +func (m *RequestFinalizeBlock) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RequestFinalizeBlock: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RequestFinalizeBlock: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Txs", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Txs = append(m.Txs, make([]byte, postIndex-iNdEx)) + copy(m.Txs[len(m.Txs)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DecidedLastCommit", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.DecidedLastCommit.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Misbehavior", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Misbehavior = append(m.Misbehavior, Misbehavior{}) + if err := m.Misbehavior[len(m.Misbehavior)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Hash = append(m.Hash[:0], dAtA[iNdEx:postIndex]...) + if m.Hash == nil { + m.Hash = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Time", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.Time, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NextValidatorsHash", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NextValidatorsHash = append(m.NextValidatorsHash[:0], dAtA[iNdEx:postIndex]...) + if m.NextValidatorsHash == nil { + m.NextValidatorsHash = []byte{} + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProposerAddress", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ProposerAddress = append(m.ProposerAddress[:0], dAtA[iNdEx:postIndex]...) + if m.ProposerAddress == nil { + m.ProposerAddress = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *Response) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -11415,41 +10900,6 @@ func (m *Response) Unmarshal(dAtA []byte) error { } m.Value = &Response_Query{v} iNdEx = postIndex - case 8: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BeginBlock", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &ResponseBeginBlock{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Value = &Response_BeginBlock{v} - iNdEx = postIndex case 9: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field CheckTx", wireType) @@ -11485,76 +10935,6 @@ func (m *Response) Unmarshal(dAtA []byte) error { } m.Value = &Response_CheckTx{v} iNdEx = postIndex - case 10: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DeliverTx", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &ResponseDeliverTx{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Value = &Response_DeliverTx{v} - iNdEx = postIndex - case 11: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field EndBlock", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &ResponseEndBlock{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Value = &Response_EndBlock{v} - iNdEx = postIndex case 12: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Commit", wireType) @@ -11800,6 +11180,41 @@ func (m *Response) Unmarshal(dAtA []byte) error { } m.Value = &Response_ProcessProposal{v} iNdEx = postIndex + case 21: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FinalizeBlock", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &ResponseFinalizeBlock{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &Response_FinalizeBlock{v} + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -12682,90 +12097,6 @@ func (m *ResponseQuery) Unmarshal(dAtA []byte) error { } return nil } -func (m *ResponseBeginBlock) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ResponseBeginBlock: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ResponseBeginBlock: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Events", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Events = append(m.Events, Event{}) - if err := m.Events[len(m.Events)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipTypes(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTypes - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func (m *ResponseCheckTx) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -13120,431 +12451,6 @@ func (m *ResponseCheckTx) Unmarshal(dAtA []byte) error { } return nil } -func (m *ResponseDeliverTx) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ResponseDeliverTx: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ResponseDeliverTx: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType) - } - m.Code = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Code |= uint32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) - if m.Data == nil { - m.Data = []byte{} - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Log", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Log = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Info", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Info = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field GasWanted", wireType) - } - m.GasWanted = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.GasWanted |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 6: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field GasUsed", wireType) - } - m.GasUsed = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.GasUsed |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Events", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Events = append(m.Events, Event{}) - if err := m.Events[len(m.Events)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 8: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Codespace", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Codespace = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipTypes(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTypes - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ResponseEndBlock) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ResponseEndBlock: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ResponseEndBlock: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ValidatorUpdates", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ValidatorUpdates = append(m.ValidatorUpdates, ValidatorUpdate{}) - if err := m.ValidatorUpdates[len(m.ValidatorUpdates)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConsensusParamUpdates", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.ConsensusParamUpdates == nil { - m.ConsensusParamUpdates = &types1.ConsensusParams{} - } - if err := m.ConsensusParamUpdates.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Events", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Events = append(m.Events, Event{}) - if err := m.Events[len(m.Events)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipTypes(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTypes - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func (m *ResponseCommit) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -13574,40 +12480,6 @@ func (m *ResponseCommit) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: ResponseCommit: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) - if m.Data == nil { - m.Data = []byte{} - } - iNdEx = postIndex case 3: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field RetainHeight", wireType) @@ -14213,6 +13085,228 @@ func (m *ResponseProcessProposal) Unmarshal(dAtA []byte) error { } return nil } +func (m *ResponseFinalizeBlock) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResponseFinalizeBlock: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResponseFinalizeBlock: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Events", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Events = append(m.Events, Event{}) + if err := m.Events[len(m.Events)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TxResults", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TxResults = append(m.TxResults, &ExecTxResult{}) + if err := m.TxResults[len(m.TxResults)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorUpdates", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ValidatorUpdates = append(m.ValidatorUpdates, ValidatorUpdate{}) + if err := m.ValidatorUpdates[len(m.ValidatorUpdates)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConsensusParamUpdates", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ConsensusParamUpdates == nil { + m.ConsensusParamUpdates = &types1.ConsensusParams{} + } + if err := m.ConsensusParamUpdates.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AgreedAppData", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AgreedAppData = append(m.AgreedAppData[:0], dAtA[iNdEx:postIndex]...) + if m.AgreedAppData == nil { + m.AgreedAppData = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *CommitInfo) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -14669,6 +13763,277 @@ func (m *EventAttribute) Unmarshal(dAtA []byte) error { } return nil } +func (m *ExecTxResult) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ExecTxResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ExecTxResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType) + } + m.Code = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Code |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Log", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Log = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Info", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Info = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field GasWanted", wireType) + } + m.GasWanted = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.GasWanted |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field GasUsed", wireType) + } + m.GasUsed = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.GasUsed |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Events", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Events = append(m.Events, Event{}) + if err := m.Events[len(m.Events)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Codespace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Codespace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *TxResult) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/abci/types/types_test.go b/abci/types/types_test.go new file mode 100644 index 000000000..f79a24454 --- /dev/null +++ b/abci/types/types_test.go @@ -0,0 +1,74 @@ +package types_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto/merkle" +) + +func TestHashAndProveResults(t *testing.T) { + trs := []*abci.ExecTxResult{ + // Note, these tests rely on the first two entries being in this order. + {Code: 0, Data: nil}, + {Code: 0, Data: []byte{}}, + + {Code: 0, Data: []byte("one")}, + {Code: 14, Data: nil}, + {Code: 14, Data: []byte("foo")}, + {Code: 14, Data: []byte("bar")}, + } + + // Nil and []byte{} should produce the same bytes + bz0, err := trs[0].Marshal() + require.NoError(t, err) + bz1, err := trs[1].Marshal() + require.NoError(t, err) + require.Equal(t, bz0, bz1) + + // Make sure that we can get a root hash from results and verify proofs. + rs, err := abci.MarshalTxResults(trs) + require.NoError(t, err) + root := merkle.HashFromByteSlices(rs) + assert.NotEmpty(t, root) + + _, proofs := merkle.ProofsFromByteSlices(rs) + for i, tr := range trs { + bz, err := tr.Marshal() + require.NoError(t, err) + + valid := proofs[i].Verify(root, bz) + assert.NoError(t, valid, "%d", i) + } +} + +func TestHashDeterministicFieldsOnly(t *testing.T) { + tr1 := abci.ExecTxResult{ + Code: 1, + Data: []byte("transaction"), + Log: "nondeterministic data: abc", + Info: "nondeterministic data: abc", + GasWanted: 1000, + GasUsed: 1000, + Events: []abci.Event{}, + Codespace: "nondeterministic.data.abc", + } + tr2 := abci.ExecTxResult{ + Code: 1, + Data: []byte("transaction"), + Log: "nondeterministic data: def", + Info: "nondeterministic data: def", + GasWanted: 1000, + GasUsed: 1000, + Events: []abci.Event{}, + Codespace: "nondeterministic.data.def", + } + r1, err := abci.MarshalTxResults([]*abci.ExecTxResult{&tr1}) + require.NoError(t, err) + r2, err := abci.MarshalTxResults([]*abci.ExecTxResult{&tr2}) + require.NoError(t, err) + require.Equal(t, merkle.HashFromByteSlices(r1), merkle.HashFromByteSlices(r2)) +} diff --git a/blocksync/reactor_test.go b/blocksync/reactor_test.go index 0ab127b53..10c7105cf 100644 --- a/blocksync/reactor_test.go +++ b/blocksync/reactor_test.go @@ -63,7 +63,7 @@ func newReactor( panic("only support one validator") } - app := &testApp{} + app := abci.NewBaseApplication() cc := proxy.NewLocalClientCreator(app) proxyApp := proxy.NewAppConns(cc, proxy.NopMetrics()) err := proxyApp.Start() @@ -297,37 +297,3 @@ func TestBadBlockStopsPeer(t *testing.T) { assert.True(t, lastReactorPair.reactor.Switch.Peers().Size() < len(reactorPairs)-1) } - -type testApp struct { - abci.BaseApplication -} - -var _ abci.Application = (*testApp)(nil) - -func (app *testApp) Info(req abci.RequestInfo) (resInfo abci.ResponseInfo) { - return abci.ResponseInfo{} -} - -func (app *testApp) BeginBlock(req abci.RequestBeginBlock) abci.ResponseBeginBlock { - return abci.ResponseBeginBlock{} -} - -func (app *testApp) EndBlock(req abci.RequestEndBlock) abci.ResponseEndBlock { - return abci.ResponseEndBlock{} -} - -func (app *testApp) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx { - return abci.ResponseDeliverTx{Events: []abci.Event{}} -} - -func (app *testApp) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx { - return abci.ResponseCheckTx{} -} - -func (app *testApp) Commit() abci.ResponseCommit { - return abci.ResponseCommit{} -} - -func (app *testApp) Query(reqQuery abci.RequestQuery) (resQuery abci.ResponseQuery) { - return -} diff --git a/cmd/tendermint/commands/reindex_event.go b/cmd/tendermint/commands/reindex_event.go index 976224f96..f5a9acb4d 100644 --- a/cmd/tendermint/commands/reindex_event.go +++ b/cmd/tendermint/commands/reindex_event.go @@ -143,38 +143,38 @@ func eventReIndex(cmd *cobra.Command, args eventReIndexArgs) error { fmt.Println("start re-indexing events:") defer bar.Finish() - for i := args.startHeight; i <= args.endHeight; i++ { + for height := args.startHeight; height <= args.endHeight; height++ { select { case <-cmd.Context().Done(): - return fmt.Errorf("event re-index terminated at height %d: %w", i, cmd.Context().Err()) + return fmt.Errorf("event re-index terminated at height %d: %w", height, cmd.Context().Err()) default: - b := args.blockStore.LoadBlock(i) - if b == nil { - return fmt.Errorf("not able to load block at height %d from the blockstore", i) + block := args.blockStore.LoadBlock(height) + if block == nil { + return fmt.Errorf("not able to load block at height %d from the blockstore", height) } - r, err := args.stateStore.LoadABCIResponses(i) + resp, err := args.stateStore.LoadFinalizeBlockResponse(height) if err != nil { - return fmt.Errorf("not able to load ABCI Response at height %d from the statestore", i) + return fmt.Errorf("not able to load ABCI Response at height %d from the statestore", height) } - e := types.EventDataNewBlockHeader{ - Header: b.Header, - NumTxs: int64(len(b.Txs)), - ResultBeginBlock: *r.BeginBlock, - ResultEndBlock: *r.EndBlock, + e := types.EventDataNewBlockEvents{ + Height: height, + Events: resp.Events, } + numTxs := len(resp.TxResults) + var batch *txindex.Batch - if e.NumTxs > 0 { - batch = txindex.NewBatch(e.NumTxs) + if numTxs > 0 { + batch = txindex.NewBatch(int64(numTxs)) - for i := range b.Data.Txs { + for idx, txResult := range resp.TxResults { tr := abcitypes.TxResult{ - Height: b.Height, - Index: uint32(i), - Tx: b.Data.Txs[i], - Result: *(r.DeliverTxs[i]), + Height: height, + Index: uint32(idx), + Tx: block.Txs[idx], + Result: *txResult, } if err = batch.Add(&tr); err != nil { @@ -183,16 +183,16 @@ func eventReIndex(cmd *cobra.Command, args eventReIndexArgs) error { } if err := args.txIndexer.AddBatch(batch); err != nil { - return fmt.Errorf("tx event re-index at height %d failed: %w", i, err) + return fmt.Errorf("tx event re-index at height %d failed: %w", height, err) } } if err := args.blockIndexer.Index(e); err != nil { - return fmt.Errorf("block event re-index at height %d failed: %w", i, err) + return fmt.Errorf("block event re-index at height %d failed: %w", height, err) } } - bar.Play(i) + bar.Play(height) } return nil diff --git a/cmd/tendermint/commands/reindex_event_test.go b/cmd/tendermint/commands/reindex_event_test.go index 336f61a61..0cd833db2 100644 --- a/cmd/tendermint/commands/reindex_event_test.go +++ b/cmd/tendermint/commands/reindex_event_test.go @@ -14,7 +14,6 @@ import ( abcitypes "github.com/tendermint/tendermint/abci/types" tmcfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/internal/test" - prototmstate "github.com/tendermint/tendermint/proto/tendermint/state" blockmocks "github.com/tendermint/tendermint/state/indexer/mocks" "github.com/tendermint/tendermint/state/mocks" txmocks "github.com/tendermint/tendermint/state/txindex/mocks" @@ -141,25 +140,24 @@ func TestReIndexEvent(t *testing.T) { On("LoadBlock", base).Return(&types.Block{Data: types.Data{Txs: types.Txs{make(types.Tx, 1)}}}). On("LoadBlock", height).Return(&types.Block{Data: types.Data{Txs: types.Txs{make(types.Tx, 1)}}}) - dtx := abcitypes.ResponseDeliverTx{} - abciResp := &prototmstate.ABCIResponses{ - DeliverTxs: []*abcitypes.ResponseDeliverTx{&dtx}, - EndBlock: &abcitypes.ResponseEndBlock{}, - BeginBlock: &abcitypes.ResponseBeginBlock{}, + abciResp := &abcitypes.ResponseFinalizeBlock{ + TxResults: []*abcitypes.ExecTxResult{ + {Code: 1}, + }, } mockBlockIndexer. - On("Index", mock.AnythingOfType("types.EventDataNewBlockHeader")).Return(errors.New("")).Once(). - On("Index", mock.AnythingOfType("types.EventDataNewBlockHeader")).Return(nil) + On("Index", mock.AnythingOfType("types.EventDataNewBlockEvents")).Return(errors.New("")).Once(). + On("Index", mock.AnythingOfType("types.EventDataNewBlockEvents")).Return(nil) mockTxIndexer. On("AddBatch", mock.AnythingOfType("*txindex.Batch")).Return(errors.New("")).Once(). On("AddBatch", mock.AnythingOfType("*txindex.Batch")).Return(nil) mockStateStore. - On("LoadABCIResponses", base).Return(nil, errors.New("")).Once(). - On("LoadABCIResponses", base).Return(abciResp, nil). - On("LoadABCIResponses", height).Return(abciResp, nil) + On("LoadFinalizeBlockResponse", base).Return(nil, errors.New("")).Once(). + On("LoadFinalizeBlockResponse", base).Return(abciResp, nil). + On("LoadFinalizeBlockResponse", height).Return(abciResp, nil) testCases := []struct { startHeight int64 @@ -167,7 +165,7 @@ func TestReIndexEvent(t *testing.T) { reIndexErr bool }{ {base, height, true}, // LoadBlock error - {base, height, true}, // LoadABCIResponses error + {base, height, true}, // LoadFinalizeBlockResponse error {base, height, true}, // index block event error {base, height, true}, // index tx event error {base, base, false}, diff --git a/consensus/byzantine_test.go b/consensus/byzantine_test.go index 850584a8c..a1cb43949 100644 --- a/consensus/byzantine_test.go +++ b/consensus/byzantine_test.go @@ -21,6 +21,7 @@ import ( "github.com/tendermint/tendermint/libs/service" tmsync "github.com/tendermint/tendermint/libs/sync" mempl "github.com/tendermint/tendermint/mempool" + "github.com/tendermint/tendermint/proxy" cfg "github.com/tendermint/tendermint/config" mempoolv0 "github.com/tendermint/tendermint/mempool/v0" @@ -60,15 +61,16 @@ func TestByzantinePrevoteEquivocation(t *testing.T) { ensureDir(path.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal app := appFunc() vals := types.TM2PB.ValidatorUpdates(state.Validators) - app.InitChain(abci.RequestInitChain{Validators: vals}) + _, err := app.InitChain(context.Background(), &abci.RequestInitChain{Validators: vals}) + require.NoError(t, err) blockDB := dbm.NewMemDB() blockStore := store.NewBlockStore(blockDB) mtx := new(tmsync.Mutex) // one for mempool, one for consensus - proxyAppConnCon := abcicli.NewLocalClient(mtx, app) - proxyAppConnConMem := abcicli.NewLocalClient(mtx, app) + proxyAppConnCon := proxy.NewAppConnConsensus(abcicli.NewLocalClient(mtx, app), proxy.NopMetrics()) + proxyAppConnMem := proxy.NewAppConnMempool(abcicli.NewLocalClient(mtx, app), proxy.NopMetrics()) // Make Mempool var mempool mempl.Mempool @@ -76,14 +78,14 @@ func TestByzantinePrevoteEquivocation(t *testing.T) { switch thisConfig.Mempool.Version { case cfg.MempoolV0: mempool = mempoolv0.NewCListMempool(config.Mempool, - proxyAppConnConMem, + proxyAppConnMem, state.LastBlockHeight, mempoolv0.WithPreCheck(sm.TxPreCheck(state)), mempoolv0.WithPostCheck(sm.TxPostCheck(state))) case cfg.MempoolV1: mempool = mempoolv1.NewTxMempool(logger, config.Mempool, - proxyAppConnConMem, + proxyAppConnMem, state.LastBlockHeight, mempoolv1.WithPreCheck(sm.TxPreCheck(state)), mempoolv1.WithPostCheck(sm.TxPostCheck(state)), @@ -298,9 +300,6 @@ func TestByzantinePrevoteEquivocation(t *testing.T) { } } case <-time.After(20 * time.Second): - for i, reactor := range reactors { - t.Logf("Consensus Reactor %d\n%v", i, reactor) - } t.Fatalf("Timed out waiting for validators to commit evidence") } } @@ -314,7 +313,7 @@ func TestByzantineConflictingProposalsWithPartition(t *testing.T) { N := 4 logger := consensusLogger().With("test", "byzantine") app := newKVStore - css, cleanup := randConsensusNet(N, "consensus_byzantine_test", newMockTickerFunc(false), app) + css, cleanup := randConsensusNet(t, N, "consensus_byzantine_test", newMockTickerFunc(false), app) defer cleanup() // give the byzantine validator a normal ticker @@ -486,7 +485,7 @@ func byzantineDecideProposalFunc(t *testing.T, height int64, round int32, cs *St proposal1.Signature = p1.Signature // some new transactions come in (this ensures that the proposals are different) - deliverTxsRange(cs, 0, 1) + deliverTxsRange(t, cs, 0, 1) // Create a new proposal block from state/txs from the mempool. block2, err := cs.createProposalBlock() diff --git a/consensus/common_test.go b/consensus/common_test.go index fee218198..2144bd556 100644 --- a/consensus/common_test.go +++ b/consensus/common_test.go @@ -36,6 +36,7 @@ import ( "github.com/tendermint/tendermint/p2p" "github.com/tendermint/tendermint/privval" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + "github.com/tendermint/tendermint/proxy" sm "github.com/tendermint/tendermint/state" "github.com/tendermint/tendermint/store" "github.com/tendermint/tendermint/types" @@ -397,8 +398,8 @@ func newStateWithConfigAndBlockStore( // one for mempool, one for consensus mtx := new(tmsync.Mutex) - proxyAppConnCon := abcicli.NewLocalClient(mtx, app) - proxyAppConnConMem := abcicli.NewLocalClient(mtx, app) + proxyAppConnCon := proxy.NewAppConnConsensus(abcicli.NewLocalClient(mtx, app), proxy.NopMetrics()) + proxyAppConnMem := proxy.NewAppConnMempool(abcicli.NewLocalClient(mtx, app), proxy.NopMetrics()) // Make Mempool memplMetrics := mempl.NopMetrics() @@ -408,7 +409,7 @@ func newStateWithConfigAndBlockStore( switch config.Mempool.Version { case cfg.MempoolV0: mempool = mempoolv0.NewCListMempool(config.Mempool, - proxyAppConnConMem, + proxyAppConnMem, state.LastBlockHeight, mempoolv0.WithMetrics(memplMetrics), mempoolv0.WithPreCheck(sm.TxPreCheck(state)), @@ -417,7 +418,7 @@ func newStateWithConfigAndBlockStore( logger := consensusLogger() mempool = mempoolv1.NewTxMempool(logger, config.Mempool, - proxyAppConnConMem, + proxyAppConnMem, state.LastBlockHeight, mempoolv1.WithMetrics(memplMetrics), mempoolv1.WithPreCheck(sm.TxPreCheck(state)), @@ -435,6 +436,7 @@ func newStateWithConfigAndBlockStore( stateStore := sm.NewStore(stateDB, sm.StoreOptions{ DiscardABCIResponses: false, }) + if err := stateStore.Save(state); err != nil { // for save height 1's validators info panic(err) } @@ -464,7 +466,7 @@ func loadPrivValidator(config *cfg.Config) *privval.FilePV { } func randState(nValidators int) (*State, []*validatorStub) { - return randStateWithApp(nValidators, kvstore.NewApplication()) + return randStateWithApp(nValidators, kvstore.NewInMemoryApplication()) } func randStateWithApp(nValidators int, app abci.Application) (*State, []*validatorStub) { @@ -747,8 +749,9 @@ func consensusLogger() log.Logger { }).With("module", "consensus") } -func randConsensusNet(nValidators int, testName string, tickerFunc func() TimeoutTicker, +func randConsensusNet(t *testing.T, nValidators int, testName string, tickerFunc func() TimeoutTicker, appFunc func() abci.Application, configOpts ...func(*cfg.Config)) ([]*State, cleanupFunc) { + t.Helper() genDoc, privVals := randGenesisDoc(nValidators, false, 30) css := make([]*State, nValidators) logger := consensusLogger() @@ -767,7 +770,8 @@ func randConsensusNet(nValidators int, testName string, tickerFunc func() Timeou ensureDir(filepath.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal app := appFunc() vals := types.TM2PB.ValidatorUpdates(state.Validators) - app.InitChain(abci.RequestInitChain{Validators: vals}) + _, err := app.InitChain(context.Background(), &abci.RequestInitChain{Validators: vals}) + require.NoError(t, err) css[i] = newStateWithConfigAndBlockStore(thisConfig, state, privVals[i], app, stateDB) css[i].SetTimeoutTicker(tickerFunc()) @@ -782,6 +786,7 @@ func randConsensusNet(nValidators int, testName string, tickerFunc func() Timeou // nPeers = nValidators + nNotValidator func randConsensusNetWithPeers( + t *testing.T, nValidators, nPeers int, testName string, @@ -798,6 +803,7 @@ func randConsensusNetWithPeers( stateStore := sm.NewStore(stateDB, sm.StoreOptions{ DiscardABCIResponses: false, }) + t.Cleanup(func() { _ = stateStore.Close() }) state, _ := stateStore.LoadFromDBOrGenesisDoc(genDoc) thisConfig := ResetConfig(fmt.Sprintf("%s_%d", testName, i)) configRootDirs = append(configRootDirs, thisConfig.RootDir) @@ -823,12 +829,12 @@ func randConsensusNetWithPeers( app := appFunc(path.Join(config.DBDir(), fmt.Sprintf("%s_%d", testName, i))) vals := types.TM2PB.ValidatorUpdates(state.Validators) - if _, ok := app.(*kvstore.PersistentKVStoreApplication); ok { + if _, ok := app.(*kvstore.Application); ok { // simulate handshake, receive app version. If don't do this, replay test will fail - state.Version.Consensus.App = kvstore.ProtocolVersion + state.Version.Consensus.App = kvstore.AppVersion } - app.InitChain(abci.RequestInitChain{Validators: vals}) - // sm.SaveState(stateDB,state) //height 1's validatorsInfo already saved in LoadStateFromDBOrGenesisDoc above + _, err := app.InitChain(context.Background(), &abci.RequestInitChain{Validators: vals}) + require.NoError(t, err) css[i] = newStateWithConfig(thisConfig, state, privVal, app) css[i].SetTimeoutTicker(tickerFunc()) @@ -933,15 +939,15 @@ func newPersistentKVStore() abci.Application { if err != nil { panic(err) } - return kvstore.NewPersistentKVStoreApplication(dir) + return kvstore.NewPersistentApplication(dir) } func newKVStore() abci.Application { - return kvstore.NewApplication() + return kvstore.NewInMemoryApplication() } func newPersistentKVStoreWithPath(dbDir string) abci.Application { - return kvstore.NewPersistentKVStoreApplication(dbDir) + return kvstore.NewPersistentApplication(dbDir) } func signDataIsEqual(v1 *types.Vote, v2 *tmproto.Vote) bool { diff --git a/consensus/invalid_test.go b/consensus/invalid_test.go index 4e6f39bab..54bc453fb 100644 --- a/consensus/invalid_test.go +++ b/consensus/invalid_test.go @@ -19,7 +19,7 @@ import ( // Ensure a testnet makes blocks func TestReactorInvalidPrecommit(t *testing.T) { N := 4 - css, cleanup := randConsensusNet(N, "consensus_reactor_test", newMockTickerFunc(true), newKVStore) + css, cleanup := randConsensusNet(t, N, "consensus_reactor_test", newMockTickerFunc(true), newKVStore) defer cleanup() for i := 0; i < 4; i++ { diff --git a/consensus/mempool_test.go b/consensus/mempool_test.go index 50d941e59..a729e5b2d 100644 --- a/consensus/mempool_test.go +++ b/consensus/mempool_test.go @@ -1,7 +1,7 @@ package consensus import ( - "encoding/binary" + "context" "fmt" "os" "testing" @@ -12,9 +12,10 @@ import ( dbm "github.com/tendermint/tm-db" - "github.com/tendermint/tendermint/abci/example/code" + "github.com/tendermint/tendermint/abci/example/kvstore" abci "github.com/tendermint/tendermint/abci/types" mempl "github.com/tendermint/tendermint/mempool" + "github.com/tendermint/tendermint/proxy" sm "github.com/tendermint/tendermint/state" "github.com/tendermint/tendermint/types" ) @@ -29,7 +30,11 @@ func TestMempoolNoProgressUntilTxsAvailable(t *testing.T) { defer os.RemoveAll(config.RootDir) config.Consensus.CreateEmptyBlocks = false state, privVals := randGenesisState(1, false, 10) - cs := newStateWithConfig(config, state, privVals[0], NewCounterApplication()) + app := kvstore.NewInMemoryApplication() + resp, err := app.Info(context.Background(), proxy.RequestInfo) + require.NoError(t, err) + state.AppHash = resp.LastBlockAppHash + cs := newStateWithConfig(config, state, privVals[0], app) assertMempool(cs.txNotifier).EnableTxsAvailable() height, round := cs.Height, cs.Round newBlockCh := subscribe(cs.eventBus, types.EventQueryNewBlock) @@ -37,7 +42,7 @@ func TestMempoolNoProgressUntilTxsAvailable(t *testing.T) { ensureNewEventOnChannel(newBlockCh) // first block gets committed ensureNoNewEventOnChannel(newBlockCh) - deliverTxsRange(cs, 0, 1) + deliverTxsRange(t, cs, 0, 1) ensureNewEventOnChannel(newBlockCh) // commit txs ensureNewEventOnChannel(newBlockCh) // commit updated app hash ensureNoNewEventOnChannel(newBlockCh) @@ -49,7 +54,11 @@ func TestMempoolProgressAfterCreateEmptyBlocksInterval(t *testing.T) { config.Consensus.CreateEmptyBlocksInterval = ensureTimeout state, privVals := randGenesisState(1, false, 10) - cs := newStateWithConfig(config, state, privVals[0], NewCounterApplication()) + app := kvstore.NewInMemoryApplication() + resp, err := app.Info(context.Background(), proxy.RequestInfo) + require.NoError(t, err) + state.AppHash = resp.LastBlockAppHash + cs := newStateWithConfig(config, state, privVals[0], app) assertMempool(cs.txNotifier).EnableTxsAvailable() @@ -66,7 +75,7 @@ func TestMempoolProgressInHigherRound(t *testing.T) { defer os.RemoveAll(config.RootDir) config.Consensus.CreateEmptyBlocks = false state, privVals := randGenesisState(1, false, 10) - cs := newStateWithConfig(config, state, privVals[0], NewCounterApplication()) + cs := newStateWithConfig(config, state, privVals[0], kvstore.NewInMemoryApplication()) assertMempool(cs.txNotifier).EnableTxsAvailable() height, round := cs.Height, cs.Round newBlockCh := subscribe(cs.eventBus, types.EventQueryNewBlock) @@ -90,7 +99,7 @@ func TestMempoolProgressInHigherRound(t *testing.T) { round = 0 ensureNewRound(newRoundCh, height, round) // first round at next height - deliverTxsRange(cs, 0, 1) // we deliver txs, but dont set a proposal so we get the next round + deliverTxsRange(t, cs, 0, 1) // we deliver txs, but dont set a proposal so we get the next round ensureNewTimeout(timeoutCh, height, round, cs.config.TimeoutPropose.Nanoseconds()) round++ // moving to the next round @@ -98,15 +107,11 @@ func TestMempoolProgressInHigherRound(t *testing.T) { ensureNewEventOnChannel(newBlockCh) // now we can commit the block } -func deliverTxsRange(cs *State, start, end int) { +func deliverTxsRange(t *testing.T, cs *State, start, end int) { // Deliver some txs. for i := start; i < end; i++ { - txBytes := make([]byte, 8) - binary.BigEndian.PutUint64(txBytes, uint64(i)) - err := assertMempool(cs.txNotifier).CheckTx(txBytes, nil, mempl.TxInfo{}) - if err != nil { - panic(fmt.Sprintf("Error after CheckTx: %v", err)) - } + err := assertMempool(cs.txNotifier).CheckTx(kvstore.NewTx(fmt.Sprintf("%d", i), "true"), nil, mempl.TxInfo{}) + require.NoError(t, err) } } @@ -114,20 +119,20 @@ func TestMempoolTxConcurrentWithCommit(t *testing.T) { state, privVals := randGenesisState(1, false, 10) blockDB := dbm.NewMemDB() stateStore := sm.NewStore(blockDB, sm.StoreOptions{DiscardABCIResponses: false}) - cs := newStateWithConfigAndBlockStore(config, state, privVals[0], NewCounterApplication(), blockDB) + cs := newStateWithConfigAndBlockStore(config, state, privVals[0], kvstore.NewInMemoryApplication(), blockDB) err := stateStore.Save(state) require.NoError(t, err) - newBlockHeaderCh := subscribe(cs.eventBus, types.EventQueryNewBlockHeader) + newBlockEventsCh := subscribe(cs.eventBus, types.EventQueryNewBlockEvents) const numTxs int64 = 3000 - go deliverTxsRange(cs, 0, int(numTxs)) + go deliverTxsRange(t, cs, 0, int(numTxs)) startTestRound(cs, cs.Height, cs.Round) for n := int64(0); n < numTxs; { select { - case msg := <-newBlockHeaderCh: - headerEvent := msg.Data().(types.EventDataNewBlockHeader) - n += headerEvent.NumTxs + case msg := <-newBlockEventsCh: + event := msg.Data().(types.EventDataNewBlockEvents) + n += event.NumTxs case <-time.After(30 * time.Second): t.Fatal("Timed out waiting 30s to commit blocks with transactions") } @@ -136,7 +141,7 @@ func TestMempoolTxConcurrentWithCommit(t *testing.T) { func TestMempoolRmBadTx(t *testing.T) { state, privVals := randGenesisState(1, false, 10) - app := NewCounterApplication() + app := kvstore.NewInMemoryApplication() blockDB := dbm.NewMemDB() stateStore := sm.NewStore(blockDB, sm.StoreOptions{DiscardABCIResponses: false}) cs := newStateWithConfigAndBlockStore(config, state, privVals[0], app, blockDB) @@ -144,14 +149,14 @@ func TestMempoolRmBadTx(t *testing.T) { require.NoError(t, err) // increment the counter by 1 - txBytes := make([]byte, 8) - binary.BigEndian.PutUint64(txBytes, uint64(0)) + txBytes := kvstore.NewTx("key", "value") + res, err := app.FinalizeBlock(context.Background(), &abci.RequestFinalizeBlock{Txs: [][]byte{txBytes}}) + require.NoError(t, err) + assert.False(t, res.TxResults[0].IsErr()) + assert.True(t, len(res.AgreedAppData) > 0) - resDeliver := app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes}) - assert.False(t, resDeliver.IsErr(), fmt.Sprintf("expected no error. got %v", resDeliver)) - - resCommit := app.Commit() - assert.True(t, len(resCommit.Data) > 0) + _, err = app.Commit(context.Background(), &abci.RequestCommit{}) + require.NoError(t, err) emptyMempoolCh := make(chan struct{}) checkTxRespCh := make(chan struct{}) @@ -159,9 +164,10 @@ func TestMempoolRmBadTx(t *testing.T) { // Try to send the tx through the mempool. // CheckTx should not err, but the app should return a bad abci code // and the tx should get removed from the pool - err := assertMempool(cs.txNotifier).CheckTx(txBytes, func(r *abci.Response) { - if r.GetCheckTx().Code != code.CodeTypeBadNonce { - t.Errorf("expected checktx to return bad nonce, got %v", r) + invalidTx := []byte("invalidTx") + err := assertMempool(cs.txNotifier).CheckTx(invalidTx, func(r *abci.ResponseCheckTx) { + if r.Code != kvstore.CodeTypeInvalidTxFormat { + t.Errorf("expected checktx to return invalid format, got %v", r) return } checkTxRespCh <- struct{}{} @@ -173,7 +179,7 @@ func TestMempoolRmBadTx(t *testing.T) { // check for the tx for { - txs := assertMempool(cs.txNotifier).ReapMaxBytesMaxGas(int64(len(txBytes)), -1) + txs := assertMempool(cs.txNotifier).ReapMaxBytesMaxGas(int64(len(invalidTx)), -1) if len(txs) == 0 { emptyMempoolCh <- struct{}{} return @@ -202,76 +208,3 @@ func TestMempoolRmBadTx(t *testing.T) { return } } - -// CounterApplication that maintains a mempool state and resets it upon commit -type CounterApplication struct { - abci.BaseApplication - - txCount int - mempoolTxCount int -} - -func NewCounterApplication() *CounterApplication { - return &CounterApplication{} -} - -func (app *CounterApplication) Info(req abci.RequestInfo) abci.ResponseInfo { - return abci.ResponseInfo{Data: fmt.Sprintf("txs:%v", app.txCount)} -} - -func (app *CounterApplication) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx { - txValue := txAsUint64(req.Tx) - if txValue != uint64(app.txCount) { - return abci.ResponseDeliverTx{ - Code: code.CodeTypeBadNonce, - Log: fmt.Sprintf("Invalid nonce. Expected %v, got %v", app.txCount, txValue)} - } - app.txCount++ - return abci.ResponseDeliverTx{Code: code.CodeTypeOK} -} - -func (app *CounterApplication) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx { - txValue := txAsUint64(req.Tx) - if txValue != uint64(app.mempoolTxCount) { - return abci.ResponseCheckTx{ - Code: code.CodeTypeBadNonce, - Log: fmt.Sprintf("Invalid nonce. Expected %v, got %v", app.mempoolTxCount, txValue)} - } - app.mempoolTxCount++ - return abci.ResponseCheckTx{Code: code.CodeTypeOK} -} - -func txAsUint64(tx []byte) uint64 { - tx8 := make([]byte, 8) - copy(tx8[len(tx8)-len(tx):], tx) - return binary.BigEndian.Uint64(tx8) -} - -func (app *CounterApplication) Commit() abci.ResponseCommit { - app.mempoolTxCount = app.txCount - if app.txCount == 0 { - return abci.ResponseCommit{} - } - hash := make([]byte, 8) - binary.BigEndian.PutUint64(hash, uint64(app.txCount)) - return abci.ResponseCommit{Data: hash} -} - -func (app *CounterApplication) PrepareProposal( - req abci.RequestPrepareProposal) abci.ResponsePrepareProposal { - txs := make([][]byte, 0, len(req.Txs)) - var totalBytes int64 - for _, tx := range req.Txs { - totalBytes += int64(len(tx)) - if totalBytes > req.MaxTxBytes { - break - } - txs = append(txs, tx) - } - return abci.ResponsePrepareProposal{Txs: txs} -} - -func (app *CounterApplication) ProcessProposal( - req abci.RequestProcessProposal) abci.ResponseProcessProposal { - return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT} -} diff --git a/consensus/reactor_test.go b/consensus/reactor_test.go index f0cdc5f9d..1f52df754 100644 --- a/consensus/reactor_test.go +++ b/consensus/reactor_test.go @@ -5,8 +5,6 @@ import ( "fmt" "os" "path" - "runtime" - "runtime/pprof" "sync" "testing" "time" @@ -35,6 +33,7 @@ import ( p2pmock "github.com/tendermint/tendermint/p2p/mock" tmcons "github.com/tendermint/tendermint/proto/tendermint/consensus" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + "github.com/tendermint/tendermint/proxy" sm "github.com/tendermint/tendermint/state" statemocks "github.com/tendermint/tendermint/state/mocks" "github.com/tendermint/tendermint/store" @@ -113,7 +112,7 @@ func stopConsensusNet(logger log.Logger, reactors []*Reactor, eventBuses []*type // Ensure a testnet makes blocks func TestReactorBasic(t *testing.T) { N := 4 - css, cleanup := randConsensusNet(N, "consensus_reactor_test", newMockTickerFunc(true), newKVStore) + css, cleanup := randConsensusNet(t, N, "consensus_reactor_test", newMockTickerFunc(true), newKVStore) defer cleanup() reactors, blocksSubs, eventBuses := startConsensusNet(t, css, N) defer stopConsensusNet(log.TestingLogger(), reactors, eventBuses) @@ -148,7 +147,8 @@ func TestReactorWithEvidence(t *testing.T) { ensureDir(path.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal app := appFunc() vals := types.TM2PB.ValidatorUpdates(state.Validators) - app.InitChain(abci.RequestInitChain{Validators: vals}) + _, err := app.InitChain(context.Background(), &abci.RequestInitChain{Validators: vals}) + require.NoError(t, err) pv := privVals[i] // duplicate code from: @@ -160,8 +160,8 @@ func TestReactorWithEvidence(t *testing.T) { mtx := new(tmsync.Mutex) memplMetrics := mempl.NopMetrics() // one for mempool, one for consensus - proxyAppConnCon := abcicli.NewLocalClient(mtx, app) - proxyAppConnConMem := abcicli.NewLocalClient(mtx, app) + proxyAppConnCon := proxy.NewAppConnConsensus(abcicli.NewLocalClient(mtx, app), proxy.NopMetrics()) + proxyAppConnMem := proxy.NewAppConnMempool(abcicli.NewLocalClient(mtx, app), proxy.NopMetrics()) // Make Mempool var mempool mempl.Mempool @@ -169,7 +169,7 @@ func TestReactorWithEvidence(t *testing.T) { switch config.Mempool.Version { case cfg.MempoolV0: mempool = mempoolv0.NewCListMempool(config.Mempool, - proxyAppConnConMem, + proxyAppConnMem, state.LastBlockHeight, mempoolv0.WithMetrics(memplMetrics), mempoolv0.WithPreCheck(sm.TxPreCheck(state)), @@ -177,7 +177,7 @@ func TestReactorWithEvidence(t *testing.T) { case cfg.MempoolV1: mempool = mempoolv1.NewTxMempool(logger, config.Mempool, - proxyAppConnConMem, + proxyAppConnMem, state.LastBlockHeight, mempoolv1.WithMetrics(memplMetrics), mempoolv1.WithPreCheck(sm.TxPreCheck(state)), @@ -237,7 +237,7 @@ func TestReactorWithEvidence(t *testing.T) { // Ensure a testnet makes blocks when there are txs func TestReactorCreatesBlockWhenEmptyBlocksFalse(t *testing.T) { N := 4 - css, cleanup := randConsensusNet(N, "consensus_reactor_test", newMockTickerFunc(true), newKVStore, + css, cleanup := randConsensusNet(t, N, "consensus_reactor_test", newMockTickerFunc(true), newKVStore, func(c *cfg.Config) { c.Consensus.CreateEmptyBlocks = false }) @@ -246,7 +246,9 @@ func TestReactorCreatesBlockWhenEmptyBlocksFalse(t *testing.T) { defer stopConsensusNet(log.TestingLogger(), reactors, eventBuses) // send a tx - if err := assertMempool(css[3].txNotifier).CheckTx([]byte{1, 2, 3}, nil, mempl.TxInfo{}); err != nil { + if err := assertMempool(css[3].txNotifier).CheckTx(kvstore.NewTxFromID(1), func(resp *abci.ResponseCheckTx) { + require.False(t, resp.IsErr()) + }, mempl.TxInfo{}); err != nil { t.Error(err) } @@ -258,7 +260,7 @@ func TestReactorCreatesBlockWhenEmptyBlocksFalse(t *testing.T) { func TestReactorReceiveDoesNotPanicIfAddPeerHasntBeenCalledYet(t *testing.T) { N := 1 - css, cleanup := randConsensusNet(N, "consensus_reactor_test", newMockTickerFunc(true), newKVStore) + css, cleanup := randConsensusNet(t, N, "consensus_reactor_test", newMockTickerFunc(true), newKVStore) defer cleanup() reactors, _, eventBuses := startConsensusNet(t, css, N) defer stopConsensusNet(log.TestingLogger(), reactors, eventBuses) @@ -284,7 +286,7 @@ func TestReactorReceiveDoesNotPanicIfAddPeerHasntBeenCalledYet(t *testing.T) { func TestReactorReceivePanicsIfInitPeerHasntBeenCalledYet(t *testing.T) { N := 1 - css, cleanup := randConsensusNet(N, "consensus_reactor_test", newMockTickerFunc(true), newKVStore) + css, cleanup := randConsensusNet(t, N, "consensus_reactor_test", newMockTickerFunc(true), newKVStore) defer cleanup() reactors, _, eventBuses := startConsensusNet(t, css, N) defer stopConsensusNet(log.TestingLogger(), reactors, eventBuses) @@ -310,7 +312,7 @@ func TestReactorReceivePanicsIfInitPeerHasntBeenCalledYet(t *testing.T) { // Test we record stats about votes and block parts from other peers. func TestReactorRecordsVotesAndBlockParts(t *testing.T) { N := 4 - css, cleanup := randConsensusNet(N, "consensus_reactor_test", newMockTickerFunc(true), newKVStore) + css, cleanup := randConsensusNet(t, N, "consensus_reactor_test", newMockTickerFunc(true), newKVStore) defer cleanup() reactors, blocksSubs, eventBuses := startConsensusNet(t, css, N) defer stopConsensusNet(log.TestingLogger(), reactors, eventBuses) @@ -336,6 +338,7 @@ func TestReactorVotingPowerChange(t *testing.T) { nVals := 4 logger := log.TestingLogger() css, cleanup := randConsensusNet( + t, nVals, "consensus_voting_power_changes_test", newMockTickerFunc(true), @@ -416,6 +419,7 @@ func TestReactorValidatorSetChanges(t *testing.T) { nPeers := 7 nVals := 4 css, _, _, cleanup := randConsensusNetWithPeers( + t, nVals, nPeers, "consensus_val_set_changes_test", @@ -441,59 +445,54 @@ func TestReactorValidatorSetChanges(t *testing.T) { <-blocksSubs[j].Out() }, css) - //--------------------------------------------------------------------------- - logger.Info("---------------------------- Testing adding one validator") + t.Run("Testing adding one validator", func(t *testing.T) { + newValidatorPubKey1, err := css[nVals].privValidator.GetPubKey() + assert.NoError(t, err) + valPubKey1ABCI, err := cryptoenc.PubKeyToProto(newValidatorPubKey1) + assert.NoError(t, err) + newValidatorTx1 := kvstore.MakeValSetChangeTx(valPubKey1ABCI, testMinPower) - newValidatorPubKey1, err := css[nVals].privValidator.GetPubKey() - assert.NoError(t, err) - valPubKey1ABCI, err := cryptoenc.PubKeyToProto(newValidatorPubKey1) - assert.NoError(t, err) - newValidatorTx1 := kvstore.MakeValSetChangeTx(valPubKey1ABCI, testMinPower) + // wait till everyone makes block 2 + // ensure the commit includes all validators + // send newValTx to change vals in block 3 + waitForAndValidateBlock(t, nPeers, activeVals, blocksSubs, css, newValidatorTx1) - // wait till everyone makes block 2 - // ensure the commit includes all validators - // send newValTx to change vals in block 3 - waitForAndValidateBlock(t, nPeers, activeVals, blocksSubs, css, newValidatorTx1) + // wait till everyone makes block 3. + // it includes the commit for block 2, which is by the original validator set + waitForAndValidateBlockWithTx(t, nPeers, activeVals, blocksSubs, css, newValidatorTx1) - // wait till everyone makes block 3. - // it includes the commit for block 2, which is by the original validator set - waitForAndValidateBlockWithTx(t, nPeers, activeVals, blocksSubs, css, newValidatorTx1) + // wait till everyone makes block 4. + // it includes the commit for block 3, which is by the original validator set + waitForAndValidateBlock(t, nPeers, activeVals, blocksSubs, css) - // wait till everyone makes block 4. - // it includes the commit for block 3, which is by the original validator set - waitForAndValidateBlock(t, nPeers, activeVals, blocksSubs, css) + // the commits for block 4 should be with the updated validator set + activeVals[string(newValidatorPubKey1.Address())] = struct{}{} - // the commits for block 4 should be with the updated validator set - activeVals[string(newValidatorPubKey1.Address())] = struct{}{} + // wait till everyone makes block 5 + // it includes the commit for block 4, which should have the updated validator set + waitForBlockWithUpdatedValsAndValidateIt(t, nPeers, activeVals, blocksSubs, css) + }) - // wait till everyone makes block 5 - // it includes the commit for block 4, which should have the updated validator set - waitForBlockWithUpdatedValsAndValidateIt(t, nPeers, activeVals, blocksSubs, css) + t.Run("Testing changing the voting power of one validator", func(t *testing.T) { + updateValidatorPubKey1, err := css[nVals].privValidator.GetPubKey() + require.NoError(t, err) + updatePubKey1ABCI, err := cryptoenc.PubKeyToProto(updateValidatorPubKey1) + require.NoError(t, err) + updateValidatorTx1 := kvstore.MakeValSetChangeTx(updatePubKey1ABCI, 25) + previousTotalVotingPower := css[nVals].GetRoundState().LastValidators.TotalVotingPower() - //--------------------------------------------------------------------------- - logger.Info("---------------------------- Testing changing the voting power of one validator") + waitForAndValidateBlock(t, nPeers, activeVals, blocksSubs, css, updateValidatorTx1) + waitForAndValidateBlockWithTx(t, nPeers, activeVals, blocksSubs, css, updateValidatorTx1) + waitForAndValidateBlock(t, nPeers, activeVals, blocksSubs, css) + waitForBlockWithUpdatedValsAndValidateIt(t, nPeers, activeVals, blocksSubs, css) - updateValidatorPubKey1, err := css[nVals].privValidator.GetPubKey() - require.NoError(t, err) - updatePubKey1ABCI, err := cryptoenc.PubKeyToProto(updateValidatorPubKey1) - require.NoError(t, err) - updateValidatorTx1 := kvstore.MakeValSetChangeTx(updatePubKey1ABCI, 25) - previousTotalVotingPower := css[nVals].GetRoundState().LastValidators.TotalVotingPower() - - waitForAndValidateBlock(t, nPeers, activeVals, blocksSubs, css, updateValidatorTx1) - waitForAndValidateBlockWithTx(t, nPeers, activeVals, blocksSubs, css, updateValidatorTx1) - waitForAndValidateBlock(t, nPeers, activeVals, blocksSubs, css) - waitForBlockWithUpdatedValsAndValidateIt(t, nPeers, activeVals, blocksSubs, css) - - if css[nVals].GetRoundState().LastValidators.TotalVotingPower() == previousTotalVotingPower { - t.Errorf( - "expected voting power to change (before: %d, after: %d)", - previousTotalVotingPower, - css[nVals].GetRoundState().LastValidators.TotalVotingPower()) - } - - //--------------------------------------------------------------------------- - logger.Info("---------------------------- Testing adding two validators at once") + if css[nVals].GetRoundState().LastValidators.TotalVotingPower() == previousTotalVotingPower { + t.Errorf( + "expected voting power to change (before: %d, after: %d)", + previousTotalVotingPower, + css[nVals].GetRoundState().LastValidators.TotalVotingPower()) + } + }) newValidatorPubKey2, err := css[nVals+1].privValidator.GetPubKey() require.NoError(t, err) @@ -507,31 +506,34 @@ func TestReactorValidatorSetChanges(t *testing.T) { require.NoError(t, err) newValidatorTx3 := kvstore.MakeValSetChangeTx(newVal3ABCI, testMinPower) - waitForAndValidateBlock(t, nPeers, activeVals, blocksSubs, css, newValidatorTx2, newValidatorTx3) - waitForAndValidateBlockWithTx(t, nPeers, activeVals, blocksSubs, css, newValidatorTx2, newValidatorTx3) - waitForAndValidateBlock(t, nPeers, activeVals, blocksSubs, css) - activeVals[string(newValidatorPubKey2.Address())] = struct{}{} - activeVals[string(newValidatorPubKey3.Address())] = struct{}{} - waitForBlockWithUpdatedValsAndValidateIt(t, nPeers, activeVals, blocksSubs, css) + t.Run("Testing adding two validators at once", func(t *testing.T) { - //--------------------------------------------------------------------------- - logger.Info("---------------------------- Testing removing two validators at once") + waitForAndValidateBlock(t, nPeers, activeVals, blocksSubs, css, newValidatorTx2, newValidatorTx3) + waitForAndValidateBlockWithTx(t, nPeers, activeVals, blocksSubs, css, newValidatorTx2, newValidatorTx3) + waitForAndValidateBlock(t, nPeers, activeVals, blocksSubs, css) + activeVals[string(newValidatorPubKey2.Address())] = struct{}{} + activeVals[string(newValidatorPubKey3.Address())] = struct{}{} + waitForBlockWithUpdatedValsAndValidateIt(t, nPeers, activeVals, blocksSubs, css) + }) - removeValidatorTx2 := kvstore.MakeValSetChangeTx(newVal2ABCI, 0) - removeValidatorTx3 := kvstore.MakeValSetChangeTx(newVal3ABCI, 0) + t.Run("Testing removing two validators at once", func(t *testing.T) { + removeValidatorTx2 := kvstore.MakeValSetChangeTx(newVal2ABCI, 0) + removeValidatorTx3 := kvstore.MakeValSetChangeTx(newVal3ABCI, 0) + + waitForAndValidateBlock(t, nPeers, activeVals, blocksSubs, css, removeValidatorTx2, removeValidatorTx3) + waitForAndValidateBlockWithTx(t, nPeers, activeVals, blocksSubs, css, removeValidatorTx2, removeValidatorTx3) + waitForAndValidateBlock(t, nPeers, activeVals, blocksSubs, css) + delete(activeVals, string(newValidatorPubKey2.Address())) + delete(activeVals, string(newValidatorPubKey3.Address())) + waitForBlockWithUpdatedValsAndValidateIt(t, nPeers, activeVals, blocksSubs, css) + }) - waitForAndValidateBlock(t, nPeers, activeVals, blocksSubs, css, removeValidatorTx2, removeValidatorTx3) - waitForAndValidateBlockWithTx(t, nPeers, activeVals, blocksSubs, css, removeValidatorTx2, removeValidatorTx3) - waitForAndValidateBlock(t, nPeers, activeVals, blocksSubs, css) - delete(activeVals, string(newValidatorPubKey2.Address())) - delete(activeVals, string(newValidatorPubKey3.Address())) - waitForBlockWithUpdatedValsAndValidateIt(t, nPeers, activeVals, blocksSubs, css) } // Check we can make blocks with skip_timeout_commit=false func TestReactorWithTimeoutCommit(t *testing.T) { N := 4 - css, cleanup := randConsensusNet(N, "consensus_reactor_with_timeout_commit_test", newMockTickerFunc(false), newKVStore) + css, cleanup := randConsensusNet(t, N, "consensus_reactor_with_timeout_commit_test", newMockTickerFunc(false), newKVStore) defer cleanup() // override default SkipTimeoutCommit == true for tests for i := 0; i < N; i++ { @@ -561,10 +563,15 @@ func waitForAndValidateBlock( newBlock := msg.Data().(types.EventDataNewBlock).Block css[j].Logger.Debug("waitForAndValidateBlock: Got block", "height", newBlock.Height) err := validateBlock(newBlock, activeVals) - assert.Nil(t, err) + require.NoError(t, err) + + // optionally add transactions for the next block for _, tx := range txs { - err := assertMempool(css[j].txNotifier).CheckTx(tx, nil, mempl.TxInfo{}) - assert.Nil(t, err) + err := assertMempool(css[j].txNotifier).CheckTx(tx, func(resp *abci.ResponseCheckTx) { + require.False(t, resp.IsErr()) + fmt.Println(resp) + }, mempl.TxInfo{}) + require.NoError(t, err) } }, css) } @@ -586,7 +593,7 @@ func waitForAndValidateBlockWithTx( newBlock := msg.Data().(types.EventDataNewBlock).Block css[j].Logger.Debug("waitForAndValidateBlockWithTx: Got block", "height", newBlock.Height) err := validateBlock(newBlock, activeVals) - assert.Nil(t, err) + require.NoError(t, err) // check that txs match the txs we're waiting for. // note they could be spread over multiple blocks, @@ -625,8 +632,8 @@ func waitForBlockWithUpdatedValsAndValidateIt( } else { css[j].Logger.Debug( "waitForBlockWithUpdatedValsAndValidateIt: Got block with no new validators. Skipping", - "height", - newBlock.Height) + "height", newBlock.Height, "last_commit", newBlock.LastCommit.Size(), "updated_vals", len(updatedVals), + ) } } @@ -670,31 +677,15 @@ func timeoutWaitGroup(t *testing.T, n int, f func(int), css []*State) { // we're running many nodes in-process, possibly in in a virtual machine, // and spewing debug messages - making a block could take a while, - timeout := time.Second * 120 + timeout := time.Second * 20 select { case <-done: case <-time.After(timeout): - for i, cs := range css { - t.Log("#################") - t.Log("Validator", i) - t.Log(cs.GetRoundState()) - t.Log("") - } - os.Stdout.Write([]byte("pprof.Lookup('goroutine'):\n")) - err := pprof.Lookup("goroutine").WriteTo(os.Stdout, 1) - require.NoError(t, err) - capture() panic("Timed out waiting for all validators to commit a block") } } -func capture() { - trace := make([]byte, 10240000) - count := runtime.Stack(trace, true) - fmt.Printf("Stack of %d bytes: %s\n", count, trace) -} - //------------------------------------------------------------- // Ensure basic validation of structs is functioning diff --git a/consensus/replay.go b/consensus/replay.go index 5730a9a51..ea9b2ff46 100644 --- a/consensus/replay.go +++ b/consensus/replay.go @@ -2,6 +2,7 @@ package consensus import ( "bytes" + "context" "fmt" "hash/crc32" "io" @@ -241,7 +242,7 @@ func (h *Handshaker) NBlocks() int { func (h *Handshaker) Handshake(proxyApp proxy.AppConns) error { // Handshake is done via ABCI Info on the query conn. - res, err := proxyApp.Query().InfoSync(proxy.RequestInfo) + res, err := proxyApp.Query().Info(context.TODO(), proxy.RequestInfo) if err != nil { return fmt.Errorf("error calling Info: %v", err) } @@ -265,7 +266,7 @@ func (h *Handshaker) Handshake(proxyApp proxy.AppConns) error { } // Replay blocks up to the latest in the blockstore. - _, err = h.ReplayBlocks(h.initialState, appHash, blockHeight, proxyApp) + appHash, err = h.ReplayBlocks(h.initialState, appHash, blockHeight, proxyApp) if err != nil { return fmt.Errorf("error on replay: %v", err) } @@ -308,7 +309,7 @@ func (h *Handshaker) ReplayBlocks( validatorSet := types.NewValidatorSet(validators) nextVals := types.TM2PB.ValidatorUpdates(validatorSet) pbparams := h.genDoc.ConsensusParams.ToProto() - req := abci.RequestInitChain{ + req := &abci.RequestInitChain{ Time: h.genDoc.GenesisTime, ChainId: h.genDoc.ChainID, InitialHeight: h.genDoc.InitialHeight, @@ -316,7 +317,7 @@ func (h *Handshaker) ReplayBlocks( Validators: nextVals, AppStateBytes: h.genDoc.AppState, } - res, err := proxyApp.Consensus().InitChainSync(req) + res, err := proxyApp.Consensus().InitChain(context.TODO(), req) if err != nil { return nil, err } @@ -418,11 +419,18 @@ func (h *Handshaker) ReplayBlocks( case appBlockHeight == storeBlockHeight: // We ran Commit, but didn't save the state, so replayBlock with mock app. - abciResponses, err := h.stateStore.LoadLastABCIResponse(storeBlockHeight) + finalizeBlockResponse, err := h.stateStore.LoadLastFinalizeBlockResponse(storeBlockHeight) if err != nil { return nil, err } - mockApp := newMockProxyApp(appHash, abciResponses) + // NOTE: There is a rare edge case where a node has upgraded from + // v0.37 with endblock to v0.38 with finalize block and thus + // does not have the app hash saved from the previous height + // here we take the appHash provided from the Info handshake + if len(finalizeBlockResponse.AgreedAppData) == 0 { + finalizeBlockResponse.AgreedAppData = appHash + } + mockApp := newMockProxyApp(finalizeBlockResponse) h.logger.Info("Replay last block using mock app") state, err = h.replayBlock(state, storeBlockHeight, mockApp) return state.AppHash, err diff --git a/consensus/replay_stubs.go b/consensus/replay_stubs.go index aa74f9420..e2a72b3be 100644 --- a/consensus/replay_stubs.go +++ b/consensus/replay_stubs.go @@ -1,10 +1,11 @@ package consensus import ( + "context" + abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/libs/clist" mempl "github.com/tendermint/tendermint/mempool" - tmstate "github.com/tendermint/tendermint/proto/tendermint/state" "github.com/tendermint/tendermint/proxy" "github.com/tendermint/tendermint/types" ) @@ -19,7 +20,7 @@ func (emptyMempool) Lock() {} func (emptyMempool) Unlock() {} func (emptyMempool) Size() int { return 0 } func (emptyMempool) SizeBytes() int64 { return 0 } -func (emptyMempool) CheckTx(_ types.Tx, _ func(*abci.Response), _ mempl.TxInfo) error { +func (emptyMempool) CheckTx(_ types.Tx, _ func(*abci.ResponseCheckTx), _ mempl.TxInfo) error { return nil } @@ -32,7 +33,7 @@ func (emptyMempool) ReapMaxTxs(n int) types.Txs { return types.Txs{ func (emptyMempool) Update( _ int64, _ types.Txs, - _ []*abci.ResponseDeliverTx, + _ []*abci.ExecTxResult, _ mempl.PreCheckFunc, _ mempl.PostCheckFunc, ) error { @@ -56,10 +57,9 @@ func (emptyMempool) CloseWAL() {} // Useful because we don't want to call Commit() twice for the same block on // the real app. -func newMockProxyApp(appHash []byte, abciResponses *tmstate.ABCIResponses) proxy.AppConnConsensus { +func newMockProxyApp(finalizeBlockResponse *abci.ResponseFinalizeBlock) proxy.AppConnConsensus { clientCreator := proxy.NewLocalClientCreator(&mockProxyApp{ - appHash: appHash, - abciResponses: abciResponses, + finalizeBlockResponse: finalizeBlockResponse, }) cli, _ := clientCreator.NewABCIClient() err := cli.Start() @@ -71,26 +71,9 @@ func newMockProxyApp(appHash []byte, abciResponses *tmstate.ABCIResponses) proxy type mockProxyApp struct { abci.BaseApplication - - appHash []byte - txCount int - abciResponses *tmstate.ABCIResponses + finalizeBlockResponse *abci.ResponseFinalizeBlock } -func (mock *mockProxyApp) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx { - r := mock.abciResponses.DeliverTxs[mock.txCount] - mock.txCount++ - if r == nil { - return abci.ResponseDeliverTx{} - } - return *r -} - -func (mock *mockProxyApp) EndBlock(req abci.RequestEndBlock) abci.ResponseEndBlock { - mock.txCount = 0 - return *mock.abciResponses.EndBlock -} - -func (mock *mockProxyApp) Commit() abci.ResponseCommit { - return abci.ResponseCommit{Data: mock.appHash} +func (mock *mockProxyApp) FinalizeBlock(_ context.Context, req *abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { + return mock.finalizeBlockResponse, nil } diff --git a/consensus/replay_test.go b/consensus/replay_test.go index 44bbe09bf..df88ac096 100644 --- a/consensus/replay_test.go +++ b/consensus/replay_test.go @@ -14,23 +14,25 @@ import ( "github.com/cosmos/gogoproto/proto" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" dbm "github.com/tendermint/tm-db" "github.com/tendermint/tendermint/abci/example/kvstore" abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/abci/types/mocks" cfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/crypto" cryptoenc "github.com/tendermint/tendermint/crypto/encoding" "github.com/tendermint/tendermint/internal/test" "github.com/tendermint/tendermint/libs/log" tmrand "github.com/tendermint/tendermint/libs/rand" - mempl "github.com/tendermint/tendermint/mempool" + "github.com/tendermint/tendermint/mempool" "github.com/tendermint/tendermint/privval" - tmstate "github.com/tendermint/tendermint/proto/tendermint/state" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/proxy" sm "github.com/tendermint/tendermint/state" + smmocks "github.com/tendermint/tendermint/state/mocks" "github.com/tendermint/tendermint/types" ) @@ -73,7 +75,7 @@ func startNewStateAndWaitForBlock(t *testing.T, consensusReplayConfig *cfg.Confi consensusReplayConfig, state, privValidator, - kvstore.NewApplication(), + kvstore.NewInMemoryApplication(), blockDB, ) cs.SetLogger(logger) @@ -110,8 +112,12 @@ func sendTxs(ctx context.Context, cs *State) { case <-ctx.Done(): return default: - tx := []byte{byte(i)} - if err := assertMempool(cs.txNotifier).CheckTx(tx, nil, mempl.TxInfo{}); err != nil { + tx := kvstore.NewTxFromID(i) + if err := assertMempool(cs.txNotifier).CheckTx(tx, func(resp *abci.ResponseCheckTx) { + if resp.Code != 0 { + panic(fmt.Sprintf("Unexpected code: %d, log: %s", resp.Code, resp.Log)) + } + }, mempool.TxInfo{}); err != nil { panic(err) } i++ @@ -169,7 +175,7 @@ LOOP: consensusReplayConfig, state, privValidator, - kvstore.NewApplication(), + kvstore.NewInMemoryApplication(), blockDB, ) cs.SetLogger(logger) @@ -293,47 +299,34 @@ func (w *crashingWAL) Stop() error { return w.next.Stop() } func (w *crashingWAL) Wait() { w.next.Wait() } // ------------------------------------------------------------------------------------------ -type testSim struct { - GenesisState sm.State - Config *cfg.Config - Chain []*types.Block - Commits []*types.Commit - CleanupFunc cleanupFunc -} -const ( - numBlocks = 6 -) - -var ( - mempool = emptyMempool{} - evpool = sm.EmptyEvidencePool{} - - sim testSim -) +const numBlocks = 6 //--------------------------------------- // Test handshake/replay // 0 - all synced up -// 1 - saved block but app and state are behind -// 2 - save block and committed but state is behind -// 3 - save block and committed with truncated block store and state behind +// 1 - saved block but app and state are behind by one height +// 2 - save block and committed (i.e. app got `Commit`) but state is behind +// 3 - same as 2 but with a truncated block store var modes = []uint{0, 1, 2, 3} // This is actually not a test, it's for storing validator change tx data for testHandshakeReplay -func TestSimulateValidatorsChange(t *testing.T) { +func setupChainWithChangingValidators(t *testing.T, name string, nBlocks int) (*cfg.Config, []*types.Block, []*types.Commit, sm.State) { nPeers := 7 nVals := 4 css, genDoc, config, cleanup := randConsensusNetWithPeers( + t, nVals, nPeers, - "replay_test", + name, newMockTickerFunc(true), - newPersistentKVStoreWithPath) - sim.Config = config - sim.GenesisState, _ = sm.MakeGenesisState(genDoc) - sim.CleanupFunc = cleanup + func(_ string) abci.Application { + return newKVStore() + }) + genesisState, err := sm.MakeGenesisState(genDoc) + require.NoError(t, err) + t.Cleanup(cleanup) partSize := types.BlockPartSizeBytes @@ -363,7 +356,7 @@ func TestSimulateValidatorsChange(t *testing.T) { valPubKey1ABCI, err := cryptoenc.PubKeyToProto(newValidatorPubKey1) require.NoError(t, err) newValidatorTx1 := kvstore.MakeValSetChangeTx(valPubKey1ABCI, testMinPower) - err = assertMempool(css[0].txNotifier).CheckTx(newValidatorTx1, nil, mempl.TxInfo{}) + err = assertMempool(css[0].txNotifier).CheckTx(newValidatorTx1, nil, mempool.TxInfo{}) assert.NoError(t, err) propBlock, err := css[0].createProposalBlock() // changeProposer(t, cs1, vs2) require.NoError(t, err) @@ -373,7 +366,7 @@ func TestSimulateValidatorsChange(t *testing.T) { proposal := types.NewProposal(vss[1].Height, round, -1, blockID) p := proposal.ToProto() - if err := vss[1].SignProposal(genDoc.ChainID, p); err != nil { + if err := vss[1].SignProposal(test.DefaultTestChainID, p); err != nil { t.Fatal("failed to sign bad proposal", err) } proposal.Signature = p.Signature @@ -395,7 +388,7 @@ func TestSimulateValidatorsChange(t *testing.T) { updatePubKey1ABCI, err := cryptoenc.PubKeyToProto(updateValidatorPubKey1) require.NoError(t, err) updateValidatorTx1 := kvstore.MakeValSetChangeTx(updatePubKey1ABCI, 25) - err = assertMempool(css[0].txNotifier).CheckTx(updateValidatorTx1, nil, mempl.TxInfo{}) + err = assertMempool(css[0].txNotifier).CheckTx(updateValidatorTx1, nil, mempool.TxInfo{}) assert.NoError(t, err) propBlock, err = css[0].createProposalBlock() // changeProposer(t, cs1, vs2) require.NoError(t, err) @@ -405,7 +398,7 @@ func TestSimulateValidatorsChange(t *testing.T) { proposal = types.NewProposal(vss[2].Height, round, -1, blockID) p = proposal.ToProto() - if err := vss[2].SignProposal(genDoc.ChainID, p); err != nil { + if err := vss[2].SignProposal(test.DefaultTestChainID, p); err != nil { t.Fatal("failed to sign bad proposal", err) } proposal.Signature = p.Signature @@ -427,14 +420,14 @@ func TestSimulateValidatorsChange(t *testing.T) { newVal2ABCI, err := cryptoenc.PubKeyToProto(newValidatorPubKey2) require.NoError(t, err) newValidatorTx2 := kvstore.MakeValSetChangeTx(newVal2ABCI, testMinPower) - err = assertMempool(css[0].txNotifier).CheckTx(newValidatorTx2, nil, mempl.TxInfo{}) + err = assertMempool(css[0].txNotifier).CheckTx(newValidatorTx2, nil, mempool.TxInfo{}) assert.Nil(t, err) newValidatorPubKey3, err := css[nVals+2].privValidator.GetPubKey() require.NoError(t, err) newVal3ABCI, err := cryptoenc.PubKeyToProto(newValidatorPubKey3) require.NoError(t, err) newValidatorTx3 := kvstore.MakeValSetChangeTx(newVal3ABCI, testMinPower) - err = assertMempool(css[0].txNotifier).CheckTx(newValidatorTx3, nil, mempl.TxInfo{}) + err = assertMempool(css[0].txNotifier).CheckTx(newValidatorTx3, nil, mempool.TxInfo{}) assert.NoError(t, err) propBlock, err = css[0].createProposalBlock() // changeProposer(t, cs1, vs2) require.NoError(t, err) @@ -464,7 +457,7 @@ func TestSimulateValidatorsChange(t *testing.T) { proposal = types.NewProposal(vss[3].Height, round, -1, blockID) p = proposal.ToProto() - if err := vss[3].SignProposal(genDoc.ChainID, p); err != nil { + if err := vss[3].SignProposal(test.DefaultTestChainID, p); err != nil { t.Fatal("failed to sign bad proposal", err) } proposal.Signature = p.Signature @@ -476,7 +469,7 @@ func TestSimulateValidatorsChange(t *testing.T) { ensureNewProposal(proposalCh, height, round) removeValidatorTx2 := kvstore.MakeValSetChangeTx(newVal2ABCI, 0) - err = assertMempool(css[0].txNotifier).CheckTx(removeValidatorTx2, nil, mempl.TxInfo{}) + err = assertMempool(css[0].txNotifier).CheckTx(removeValidatorTx2, nil, mempool.TxInfo{}) assert.Nil(t, err) rs = css[0].GetRoundState() @@ -511,7 +504,7 @@ func TestSimulateValidatorsChange(t *testing.T) { height++ incrementHeight(vss...) removeValidatorTx3 := kvstore.MakeValSetChangeTx(newVal3ABCI, 0) - err = assertMempool(css[0].txNotifier).CheckTx(removeValidatorTx3, nil, mempl.TxInfo{}) + err = assertMempool(css[0].txNotifier).CheckTx(removeValidatorTx3, nil, mempool.TxInfo{}) assert.NoError(t, err) propBlock, err = css[0].createProposalBlock() // changeProposer(t, cs1, vs2) require.NoError(t, err) @@ -525,7 +518,7 @@ func TestSimulateValidatorsChange(t *testing.T) { selfIndex = valIndexFn(0) proposal = types.NewProposal(vss[1].Height, round, -1, blockID) p = proposal.ToProto() - if err := vss[1].SignProposal(genDoc.ChainID, p); err != nil { + if err := vss[1].SignProposal(test.DefaultTestChainID, p); err != nil { t.Fatal("failed to sign bad proposal", err) } proposal.Signature = p.Signature @@ -544,103 +537,61 @@ func TestSimulateValidatorsChange(t *testing.T) { } ensureNewRound(newRoundCh, height+1, 0) - sim.Chain = make([]*types.Block, 0) - sim.Commits = make([]*types.Commit, 0) - for i := 1; i <= numBlocks; i++ { - sim.Chain = append(sim.Chain, css[0].blockStore.LoadBlock(int64(i))) - sim.Commits = append(sim.Commits, css[0].blockStore.LoadBlockCommit(int64(i))) + chain := make([]*types.Block, 0) + commits := make([]*types.Commit, 0) + for i := 1; i <= nBlocks; i++ { + chain = append(chain, css[0].blockStore.LoadBlock(int64(i))) + commits = append(commits, css[0].blockStore.LoadBlockCommit(int64(i))) } + return config, chain, commits, genesisState } // Sync from scratch func TestHandshakeReplayAll(t *testing.T) { for _, m := range modes { - testHandshakeReplay(t, config, 0, m, false) - } - for _, m := range modes { - testHandshakeReplay(t, config, 0, m, true) + t.Run(fmt.Sprintf("mode_%d_single", m), func(t *testing.T) { + testHandshakeReplay(t, config, 0, m, false) + }) + t.Run(fmt.Sprintf("mode_%d_multi", m), func(t *testing.T) { + testHandshakeReplay(t, config, 0, m, false) + }) } } // Sync many, not from scratch func TestHandshakeReplaySome(t *testing.T) { for _, m := range modes { - testHandshakeReplay(t, config, 2, m, false) - } - for _, m := range modes { - testHandshakeReplay(t, config, 2, m, true) + t.Run(fmt.Sprintf("mode_%d_single", m), func(t *testing.T) { + testHandshakeReplay(t, config, 2, m, false) + }) + t.Run(fmt.Sprintf("mode_%d_multi", m), func(t *testing.T) { + testHandshakeReplay(t, config, 2, m, true) + }) } } // Sync from lagging by one func TestHandshakeReplayOne(t *testing.T) { for _, m := range modes { - testHandshakeReplay(t, config, numBlocks-1, m, false) - } - for _, m := range modes { - testHandshakeReplay(t, config, numBlocks-1, m, true) + t.Run(fmt.Sprintf("mode_%d_single", m), func(t *testing.T) { + testHandshakeReplay(t, config, numBlocks-1, m, false) + }) + t.Run(fmt.Sprintf("mode_%d_multi", m), func(t *testing.T) { + testHandshakeReplay(t, config, numBlocks-1, m, true) + }) } } // Sync from caught up func TestHandshakeReplayNone(t *testing.T) { for _, m := range modes { - testHandshakeReplay(t, config, numBlocks, m, false) + t.Run(fmt.Sprintf("mode_%d_single", m), func(t *testing.T) { + testHandshakeReplay(t, config, numBlocks, m, false) + }) + t.Run(fmt.Sprintf("mode_%d_multi", m), func(t *testing.T) { + testHandshakeReplay(t, config, numBlocks, m, true) + }) } - for _, m := range modes { - testHandshakeReplay(t, config, numBlocks, m, true) - } -} - -// Test mockProxyApp should not panic when app return ABCIResponses with some empty ResponseDeliverTx -func TestMockProxyApp(t *testing.T) { - sim.CleanupFunc() // clean the test env created in TestSimulateValidatorsChange - logger := log.TestingLogger() - var validTxs, invalidTxs = 0, 0 - txIndex := 0 - - assert.NotPanics(t, func() { - abciResWithEmptyDeliverTx := new(tmstate.ABCIResponses) - abciResWithEmptyDeliverTx.DeliverTxs = make([]*abci.ResponseDeliverTx, 0) - abciResWithEmptyDeliverTx.DeliverTxs = append(abciResWithEmptyDeliverTx.DeliverTxs, &abci.ResponseDeliverTx{}) - - // called when saveABCIResponses: - bytes, err := proto.Marshal(abciResWithEmptyDeliverTx) - require.NoError(t, err) - loadedAbciRes := new(tmstate.ABCIResponses) - - // this also happens sm.LoadABCIResponses - err = proto.Unmarshal(bytes, loadedAbciRes) - require.NoError(t, err) - - mock := newMockProxyApp([]byte("mock_hash"), loadedAbciRes) - - 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 { - logger.Debug("Invalid tx", "code", txRes.Code, "log", txRes.Log) - invalidTxs++ - } - abciRes.DeliverTxs[txIndex] = txRes - txIndex++ - } - } - mock.SetResponseCallback(proxyCb) - - someTx := []byte("tx") - mock.DeliverTxAsync(abci.RequestDeliverTx{Tx: someTx}) - }) - assert.True(t, validTxs == 1) - assert.True(t, invalidTxs == 0) } func tempWALWithData(data []byte) string { @@ -661,30 +612,32 @@ func tempWALWithData(data []byte) string { // Make some blocks. Start a fresh app and apply nBlocks blocks. // Then restart the app and sync it up with the remaining blocks func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uint, testValidatorsChange bool) { - var chain []*types.Block - var commits []*types.Commit - var store *mockBlockStore - var stateDB dbm.DB - var genesisState sm.State - if testValidatorsChange { - testConfig := ResetConfig(fmt.Sprintf("%s_%v_m", t.Name(), mode)) - defer os.RemoveAll(testConfig.RootDir) - stateDB = dbm.NewMemDB() + var ( + testConfig *cfg.Config + chain []*types.Block + commits []*types.Commit + store *mockBlockStore + stateDB dbm.DB + genesisState sm.State + mempool = emptyMempool{} + evpool = sm.EmptyEvidencePool{} + ) - genesisState = sim.GenesisState - config = sim.Config - chain = append([]*types.Block{}, sim.Chain...) // copy chain - commits = sim.Commits + if testValidatorsChange { + testConfig, chain, commits, genesisState = setupChainWithChangingValidators(t, fmt.Sprintf("%d_%d_m", nBlocks, mode), numBlocks) + stateDB = dbm.NewMemDB() store = newMockBlockStore(t, config, genesisState.ConsensusParams) - } else { // test single node - testConfig := ResetConfig(fmt.Sprintf("%s_%v_s", t.Name(), mode)) - defer os.RemoveAll(testConfig.RootDir) - walBody, err := WALWithNBlocks(t, numBlocks) + } else { + testConfig = ResetConfig(fmt.Sprintf("%d_%d_s", nBlocks, mode)) + t.Cleanup(func() { + _ = os.RemoveAll(testConfig.RootDir) + }) + walBody, err := WALWithNBlocks(t, numBlocks, testConfig) require.NoError(t, err) walFile := tempWALWithData(walBody) - config.Consensus.SetWalFile(walFile) + testConfig.Consensus.SetWalFile(walFile) - privVal := privval.LoadFilePV(config.PrivValidatorKeyFile(), config.PrivValidatorStateFile()) + privVal := privval.LoadFilePV(testConfig.PrivValidatorKeyFile(), testConfig.PrivValidatorStateFile()) wal, err := NewWAL(walFile) require.NoError(t, err) @@ -700,23 +653,28 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin require.NoError(t, err) pubKey, err := privVal.GetPubKey() require.NoError(t, err) - stateDB, genesisState, store = stateAndStore(t, config, pubKey, kvstore.ProtocolVersion) - + stateDB, genesisState, store = stateAndStore(t, testConfig, pubKey, kvstore.AppVersion) } + stateStore := sm.NewStore(stateDB, sm.StoreOptions{ DiscardABCIResponses: false, }) + t.Cleanup(func() { + _ = stateStore.Close() + }) store.chain = chain store.commits = commits state := genesisState.Copy() // run the chain through state.ApplyBlock to build up the tendermint state - state = buildTMStateFromChain(t, config, stateStore, state, chain, nBlocks, mode, store) - latestAppHash := state.AppHash + state, latestAppHash := buildTMStateFromChain(t, testConfig, stateStore, mempool, evpool, state, chain, nBlocks, mode, store) // make a new client creator - kvstoreApp := kvstore.NewPersistentKVStoreApplication( - filepath.Join(config.DBDir(), fmt.Sprintf("replay_test_%d_%d_a", nBlocks, mode))) + kvstoreApp := kvstore.NewPersistentApplication( + filepath.Join(testConfig.DBDir(), fmt.Sprintf("replay_test_%d_%d_a", nBlocks, mode))) + t.Cleanup(func() { + _ = kvstoreApp.Close() + }) clientCreator2 := proxy.NewLocalClientCreator(kvstoreApp) if nBlocks > 0 { @@ -724,12 +682,12 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin // use a throwaway tendermint state proxyApp := proxy.NewAppConns(clientCreator2, proxy.NopMetrics()) stateDB1 := dbm.NewMemDB() - stateStore := sm.NewStore(stateDB1, sm.StoreOptions{ + dummyStateStore := sm.NewStore(stateDB1, sm.StoreOptions{ DiscardABCIResponses: false, }) - err := stateStore.Save(genesisState) + err := dummyStateStore.Save(genesisState) require.NoError(t, err) - buildAppStateFromChain(t, proxyApp, stateStore, genesisState, chain, nBlocks, mode, store) + buildAppStateFromChain(t, proxyApp, dummyStateStore, mempool, evpool, genesisState, chain, nBlocks, mode, store) } // Prune block store if requested @@ -742,7 +700,8 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin } // now start the app using the handshake - it should sync - genDoc, _ := sm.MakeGenesisDocFromFile(config.GenesisFile()) + genDoc, err := sm.MakeGenesisDocFromFile(testConfig.GenesisFile()) + require.NoError(t, err) handshaker := NewHandshaker(stateStore, state, store, genDoc) proxyApp := proxy.NewAppConns(clientCreator2, proxy.NopMetrics()) if err := proxyApp.Start(); err != nil { @@ -755,19 +714,27 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin } }) - err := handshaker.Handshake(proxyApp) + // perform the replay protocol to sync Tendermint and the application + err = handshaker.Handshake(proxyApp) if expectError { require.Error(t, err) + // finish the test early return - } else if err != nil { - t.Fatalf("Error on abci handshake: %v", err) } + require.NoError(t, err) // get the latest app hash from the app - res, err := proxyApp.Query().InfoSync(abci.RequestInfo{Version: ""}) - if err != nil { - t.Fatal(err) - } + res, err := proxyApp.Query().Info(context.Background(), proxy.RequestInfo) + require.NoError(t, err) + + // block store and app height should be in sync + require.Equal(t, store.Height(), res.LastBlockHeight) + + // tendermint state height and app height should be in sync + state, err = stateStore.Load() + require.NoError(t, err) + require.Equal(t, state.LastBlockHeight, res.LastBlockHeight) + require.Equal(t, int64(numBlocks), res.LastBlockHeight) // the app hash should be synced up if !bytes.Equal(latestAppHash, res.LastBlockAppHash) { @@ -789,7 +756,7 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin } } -func applyBlock(t *testing.T, stateStore sm.Store, st sm.State, blk *types.Block, proxyApp proxy.AppConns, bs *mockBlockStore) sm.State { +func applyBlock(t *testing.T, stateStore sm.Store, mempool mempool.Mempool, evpool sm.EvidencePool, st sm.State, blk *types.Block, proxyApp proxy.AppConns, bs sm.BlockStore) sm.State { testPartSize := types.BlockPartSizeBytes blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyApp.Consensus(), mempool, evpool, bs) @@ -801,17 +768,17 @@ func applyBlock(t *testing.T, stateStore sm.Store, st sm.State, blk *types.Block return newState } -func buildAppStateFromChain(t *testing.T, proxyApp proxy.AppConns, stateStore sm.Store, - state sm.State, chain []*types.Block, nBlocks int, mode uint, blockStore *mockBlockStore) { +func buildAppStateFromChain(t *testing.T, proxyApp proxy.AppConns, stateStore sm.Store, mempool mempool.Mempool, evpool sm.EvidencePool, + state sm.State, chain []*types.Block, nBlocks int, mode uint, bs sm.BlockStore) { // start a new app without handshake, play nBlocks blocks if err := proxyApp.Start(); err != nil { panic(err) } defer proxyApp.Stop() //nolint:errcheck // ignore - state.Version.Consensus.App = kvstore.ProtocolVersion // simulate handshake, receive app version + state.Version.Consensus.App = kvstore.AppVersion // simulate handshake, receive app version validators := types.TM2PB.ValidatorUpdates(state.Validators) - if _, err := proxyApp.Consensus().InitChainSync(abci.RequestInitChain{ + if _, err := proxyApp.Consensus().InitChain(context.Background(), &abci.RequestInitChain{ Validators: validators, }); err != nil { panic(err) @@ -823,18 +790,21 @@ func buildAppStateFromChain(t *testing.T, proxyApp proxy.AppConns, stateStore sm case 0: for i := 0; i < nBlocks; i++ { block := chain[i] - state = applyBlock(t, stateStore, state, block, proxyApp, blockStore) + state = applyBlock(t, stateStore, mempool, evpool, state, block, proxyApp, bs) } case 1, 2, 3: for i := 0; i < nBlocks-1; i++ { block := chain[i] - state = applyBlock(t, stateStore, state, block, proxyApp, blockStore) + state = applyBlock(t, stateStore, mempool, evpool, state, block, proxyApp, bs) } + // mode 1 only the block at the last height is saved + // mode 2 and 3, the block is saved, commit is called, but the state is not saved if mode == 2 || mode == 3 { // update the kvstore height and apphash // as if we ran commit but not - state = applyBlock(t, stateStore, state, chain[nBlocks-1], proxyApp, blockStore) + // here we expect a dummy state store to be used + state = applyBlock(t, stateStore, mempool, evpool, state, chain[nBlocks-1], proxyApp, bs) } default: panic(fmt.Sprintf("unknown mode %v", mode)) @@ -846,14 +816,16 @@ func buildTMStateFromChain( t *testing.T, config *cfg.Config, stateStore sm.Store, + mempool mempool.Mempool, + evpool sm.EvidencePool, state sm.State, chain []*types.Block, nBlocks int, mode uint, - blockStore *mockBlockStore) sm.State { + bs sm.BlockStore) (sm.State, []byte) { // run the whole chain against this client to build up the tendermint state clientCreator := proxy.NewLocalClientCreator( - kvstore.NewPersistentKVStoreApplication( + kvstore.NewPersistentApplication( filepath.Join(config.DBDir(), fmt.Sprintf("replay_test_%d_%d_t", nBlocks, mode)))) proxyApp := proxy.NewAppConns(clientCreator, proxy.NopMetrics()) if err := proxyApp.Start(); err != nil { @@ -861,9 +833,9 @@ func buildTMStateFromChain( } defer proxyApp.Stop() //nolint:errcheck - state.Version.Consensus.App = kvstore.ProtocolVersion // simulate handshake, receive app version + state.Version.Consensus.App = kvstore.AppVersion // simulate handshake, receive app version validators := types.TM2PB.ValidatorUpdates(state.Validators) - if _, err := proxyApp.Consensus().InitChainSync(abci.RequestInitChain{ + if _, err := proxyApp.Consensus().InitChain(context.Background(), &abci.RequestInitChain{ Validators: validators, }); err != nil { panic(err) @@ -875,24 +847,35 @@ func buildTMStateFromChain( case 0: // sync right up for _, block := range chain { - state = applyBlock(t, stateStore, state, block, proxyApp, blockStore) + state = applyBlock(t, stateStore, mempool, evpool, state, block, proxyApp, bs) } + return state, state.AppHash case 1, 2, 3: // sync up to the penultimate as if we stored the block. // whether we commit or not depends on the appHash for _, block := range chain[:len(chain)-1] { - state = applyBlock(t, stateStore, state, block, proxyApp, blockStore) + state = applyBlock(t, stateStore, mempool, evpool, state, block, proxyApp, bs) } + dummyStateStore := &smmocks.Store{} + lastHeight := int64(len(chain)) + penultimateHeight := int64(len(chain) - 1) + vals, _ := stateStore.LoadValidators(penultimateHeight) + dummyStateStore.On("LoadValidators", penultimateHeight).Return(vals, nil) + dummyStateStore.On("Save", mock.Anything).Return(nil) + dummyStateStore.On("SaveFinalizeBlockResponse", lastHeight, mock.MatchedBy(func(response *abci.ResponseFinalizeBlock) bool { + require.NoError(t, stateStore.SaveFinalizeBlockResponse(lastHeight, response)) + return true + })).Return(nil) + // apply the final block to a state copy so we can // get the right next appHash but keep the state back - applyBlock(t, stateStore, state, chain[len(chain)-1], proxyApp, blockStore) + s := applyBlock(t, dummyStateStore, mempool, evpool, state, chain[len(chain)-1], proxyApp, bs) + return state, s.AppHash default: panic(fmt.Sprintf("unknown mode %v", mode)) } - - return state } func TestHandshakePanicsIfAppReturnsWrongAppHash(t *testing.T) { @@ -975,15 +958,15 @@ type badApp struct { onlyLastHashIsWrong bool } -func (app *badApp) Commit() abci.ResponseCommit { +func (app *badApp) FinalizeBlock(_ context.Context, req *abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { app.height++ if app.onlyLastHashIsWrong { if app.height == app.numBlocks { - return abci.ResponseCommit{Data: tmrand.Bytes(8)} + return &abci.ResponseFinalizeBlock{AgreedAppData: tmrand.Bytes(8)}, nil } - return abci.ResponseCommit{Data: []byte{app.height}} + return &abci.ResponseFinalizeBlock{AgreedAppData: []byte{app.height}}, nil } else if app.allHashesAreWrong { - return abci.ResponseCommit{Data: tmrand.Bytes(8)} + return &abci.ResponseFinalizeBlock{AgreedAppData: tmrand.Bytes(8)}, nil } panic("either allHashesAreWrong or onlyLastHashIsWrong must be set") @@ -1205,7 +1188,13 @@ func (bs *mockBlockStore) DeleteLatestBlock() error { return nil } func TestHandshakeUpdatesValidators(t *testing.T) { val, _ := types.RandValidator(true, 10) vals := types.NewValidatorSet([]*types.Validator{val}) - app := &initChainApp{vals: types.TM2PB.ValidatorUpdates(vals)} + app := &mocks.Application{} + app.On("Info", mock.Anything, mock.Anything).Return(&abci.ResponseInfo{ + LastBlockHeight: 0, + }, nil) + app.On("InitChain", mock.Anything, mock.Anything).Return(&abci.ResponseInitChain{ + Validators: types.TM2PB.ValidatorUpdates(vals), + }, nil) clientCreator := proxy.NewLocalClientCreator(app) config := ResetConfig("handshake_test_") @@ -1244,15 +1233,3 @@ func TestHandshakeUpdatesValidators(t *testing.T) { assert.NotEqual(t, oldValAddr, newValAddr) assert.Equal(t, newValAddr, expectValAddr) } - -// returns the vals on InitChain -type initChainApp struct { - abci.BaseApplication - vals []abci.ValidatorUpdate -} - -func (ica *initChainApp) InitChain(req abci.RequestInitChain) abci.ResponseInitChain { - return abci.ResponseInitChain{ - Validators: ica.vals, - } -} diff --git a/consensus/state_test.go b/consensus/state_test.go index e80015135..648359845 100644 --- a/consensus/state_test.go +++ b/consensus/state_test.go @@ -665,7 +665,7 @@ func TestStateLockPOLRelock(t *testing.T) { signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) // before we timeout to the new round set the new proposal - cs2 := newState(cs1.state, vs2, kvstore.NewApplication()) + cs2 := newState(cs1.state, vs2, kvstore.NewInMemoryApplication()) prop, propBlock := decideProposal(t, cs2, vs2, vs2.Height, vs2.Round+1) if prop == nil || propBlock == nil { t.Fatal("Failed to create proposal block with vs2") @@ -853,7 +853,7 @@ func TestStateLockPOLUnlockOnUnknownBlock(t *testing.T) { signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) // before we timeout to the new round set the new proposal - cs2 := newState(cs1.state, vs2, kvstore.NewApplication()) + cs2 := newState(cs1.state, vs2, kvstore.NewInMemoryApplication()) prop, propBlock := decideProposal(t, cs2, vs2, vs2.Height, vs2.Round+1) if prop == nil || propBlock == nil { t.Fatal("Failed to create proposal block with vs2") @@ -899,7 +899,7 @@ func TestStateLockPOLUnlockOnUnknownBlock(t *testing.T) { signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) // before we timeout to the new round set the new proposal - cs3 := newState(cs1.state, vs3, kvstore.NewApplication()) + cs3 := newState(cs1.state, vs3, kvstore.NewInMemoryApplication()) prop, propBlock = decideProposal(t, cs3, vs3, vs3.Height, vs3.Round+1) if prop == nil || propBlock == nil { t.Fatal("Failed to create proposal block with vs2") @@ -1395,8 +1395,8 @@ func TestProcessProposalAccept(t *testing.T) { if testCase.accept { status = abci.ResponseProcessProposal_ACCEPT } - m.On("ProcessProposal", mock.Anything).Return(abci.ResponseProcessProposal{Status: status}) - m.On("PrepareProposal", mock.Anything).Return(abci.ResponsePrepareProposal{}).Maybe() + m.On("ProcessProposal", mock.Anything, mock.Anything).Return(&abci.ResponseProcessProposal{Status: status}, nil) + m.On("PrepareProposal", mock.Anything, mock.Anything).Return(&abci.ResponsePrepareProposal{}, nil).Maybe() cs1, _ := randStateWithApp(4, m) height, round := cs1.Height, cs1.Round @@ -1421,6 +1421,78 @@ func TestProcessProposalAccept(t *testing.T) { } } +func TestFinalizeBlockCalled(t *testing.T) { + for _, testCase := range []struct { + name string + voteNil bool + expectCalled bool + }{ + { + name: "finalize block called when block committed", + voteNil: false, + expectCalled: true, + }, + { + name: "not called when block not committed", + voteNil: true, + expectCalled: false, + }, + } { + t.Run(testCase.name, func(t *testing.T) { + m := abcimocks.NewApplication(t) + m.On("ProcessProposal", mock.Anything, mock.Anything).Return(&abci.ResponseProcessProposal{ + Status: abci.ResponseProcessProposal_ACCEPT, + }, nil) + m.On("PrepareProposal", mock.Anything, mock.Anything).Return(&abci.ResponsePrepareProposal{}, nil) + r := &abci.ResponseFinalizeBlock{AgreedAppData: []byte("the_hash")} + m.On("FinalizeBlock", mock.Anything, mock.Anything).Return(r, nil).Maybe() + m.On("Commit", mock.Anything, mock.Anything).Return(&abci.ResponseCommit{}, nil).Maybe() + + cs1, vss := randStateWithApp(4, m) + height, round := cs1.Height, cs1.Round + + proposalCh := subscribe(cs1.eventBus, types.EventQueryCompleteProposal) + newRoundCh := subscribe(cs1.eventBus, types.EventQueryNewRound) + pv1, err := cs1.privValidator.GetPubKey() + require.NoError(t, err) + addr := pv1.Address() + voteCh := subscribeToVoter(cs1, addr) + + startTestRound(cs1, cs1.Height, round) + ensureNewRound(newRoundCh, height, round) + ensureNewProposal(proposalCh, height, round) + rs := cs1.GetRoundState() + + blockID := types.BlockID{} + nextRound := round + 1 + nextHeight := height + if !testCase.voteNil { + nextRound = 0 + nextHeight = height + 1 + blockID = types.BlockID{ + Hash: rs.ProposalBlock.Hash(), + PartSetHeader: rs.ProposalBlockParts.Header(), + } + } + + signAddVotes(cs1, tmproto.PrevoteType, blockID.Hash, blockID.PartSetHeader, vss[1:]...) + ensurePrevoteMatch(t, voteCh, height, round, rs.ProposalBlock.Hash()) + + signAddVotes(cs1, tmproto.PrecommitType, blockID.Hash, blockID.PartSetHeader, vss[1:]...) + ensurePrecommit(voteCh, height, round) + + ensureNewRound(newRoundCh, nextHeight, nextRound) + m.AssertExpectations(t) + + if !testCase.expectCalled { + m.AssertNotCalled(t, "FinalizeBlock", context.TODO(), mock.Anything) + } else { + m.AssertCalled(t, "FinalizeBlock", context.TODO(), mock.Anything) + } + }) + } +} + // 4 vals, 3 Nil Precommits at P0 // What we want: // P0 waits for timeoutPrecommit before starting next round diff --git a/consensus/wal_generator.go b/consensus/wal_generator.go index 96a0d485c..4501bb42d 100644 --- a/consensus/wal_generator.go +++ b/consensus/wal_generator.go @@ -28,10 +28,8 @@ import ( // persistent kvstore application and special consensus wal instance // (byteBufferWAL) and waits until numBlocks are created. // If the node fails to produce given numBlocks, it returns an error. -func WALGenerateNBlocks(t *testing.T, wr io.Writer, numBlocks int) (err error) { - config := getConfig(t) - - app := kvstore.NewPersistentKVStoreApplication(filepath.Join(config.DBDir(), "wal_generator")) +func WALGenerateNBlocks(t *testing.T, wr io.Writer, numBlocks int, config *cfg.Config) (err error) { + app := kvstore.NewPersistentApplication(filepath.Join(config.DBDir(), "wal_generator")) logger := log.TestingLogger().With("wal_generator", "wal_generator") logger.Info("generating WAL (last height msg excluded)", "numBlocks", numBlocks) @@ -55,7 +53,7 @@ func WALGenerateNBlocks(t *testing.T, wr io.Writer, numBlocks int) (err error) { if err != nil { return fmt.Errorf("failed to make genesis state: %w", err) } - state.Version.Consensus.App = kvstore.ProtocolVersion + state.Version.Consensus.App = kvstore.AppVersion if err = stateStore.Save(state); err != nil { t.Error(err) } @@ -123,11 +121,11 @@ func WALGenerateNBlocks(t *testing.T, wr io.Writer, numBlocks int) (err error) { } // WALWithNBlocks returns a WAL content with numBlocks. -func WALWithNBlocks(t *testing.T, numBlocks int) (data []byte, err error) { +func WALWithNBlocks(t *testing.T, numBlocks int, config *cfg.Config) (data []byte, err error) { var b bytes.Buffer wr := bufio.NewWriter(&b) - if err := WALGenerateNBlocks(t, wr, numBlocks); err != nil { + if err := WALGenerateNBlocks(t, wr, numBlocks, config); err != nil { return []byte{}, err } diff --git a/consensus/wal_test.go b/consensus/wal_test.go index 12b775b41..80367c000 100644 --- a/consensus/wal_test.go +++ b/consensus/wal_test.go @@ -56,7 +56,7 @@ func TestWALTruncate(t *testing.T) { // 60 block's size nearly 70K, greater than group's headBuf size(4096 * 10), // when headBuf is full, truncate content will Flush to the file. at this // time, RotateFile is called, truncate content exist in each file. - err = WALGenerateNBlocks(t, wal.Group(), 60) + err = WALGenerateNBlocks(t, wal.Group(), 60, getConfig(t)) require.NoError(t, err) time.Sleep(1 * time.Millisecond) // wait groupCheckDuration, make sure RotateFile run @@ -150,7 +150,7 @@ func TestWALWrite(t *testing.T) { } func TestWALSearchForEndHeight(t *testing.T) { - walBody, err := WALWithNBlocks(t, 6) + walBody, err := WALWithNBlocks(t, 6, getConfig(t)) if err != nil { t.Fatal(err) } @@ -188,7 +188,7 @@ func TestWALPeriodicSync(t *testing.T) { wal.SetLogger(log.TestingLogger()) // Generate some data - err = WALGenerateNBlocks(t, wal.Group(), 5) + err = WALGenerateNBlocks(t, wal.Group(), 5, getConfig(t)) require.NoError(t, err) // We should have data in the buffer now diff --git a/internal/test/tx.go b/internal/test/tx.go index c61d0cfe0..2771904bd 100644 --- a/internal/test/tx.go +++ b/internal/test/tx.go @@ -2,7 +2,7 @@ package test import "github.com/tendermint/tendermint/types" -func MakeNTxs(height, n int64) []types.Tx { +func MakeNTxs(height, n int64) types.Txs { txs := make([]types.Tx, n) for i := range txs { txs[i] = types.Tx([]byte{byte(height), byte(i / 256), byte(i % 256)}) diff --git a/light/detector.go b/light/detector.go index 1fd21f41e..dd56d9428 100644 --- a/light/detector.go +++ b/light/detector.go @@ -34,7 +34,7 @@ func (c *Client) detectDivergence(ctx context.Context, primaryTrace []*types.Lig lastVerifiedHeader = primaryTrace[len(primaryTrace)-1].SignedHeader witnessesToRemove = make([]int, 0) ) - c.logger.Debug("Running detector against trace", "endBlockHeight", lastVerifiedHeader.Height, + c.logger.Debug("Running detector against trace", "finalizeBlockHeight", lastVerifiedHeader.Height, "endBlockHash", lastVerifiedHeader.Hash, "length", len(primaryTrace)) c.providerMutex.Lock() diff --git a/light/example_test.go b/light/example_test.go index 756a9d551..8423cefad 100644 --- a/light/example_test.go +++ b/light/example_test.go @@ -150,7 +150,7 @@ func ExampleClient_VerifyLightBlockAtHeight() { func TestMain(m *testing.M) { // start a tendermint node (and kvstore) in the background to test against - app := kvstore.NewApplication() + app := kvstore.NewInMemoryApplication() node := rpctest.StartTendermint(app, rpctest.SuppressStdout) code := m.Run() diff --git a/light/provider/http/http_test.go b/light/provider/http/http_test.go index 36be4d281..5768a481a 100644 --- a/light/provider/http/http_test.go +++ b/light/provider/http/http_test.go @@ -34,7 +34,7 @@ func TestNewProvider(t *testing.T) { } func TestProvider(t *testing.T) { - app := kvstore.NewApplication() + app := kvstore.NewInMemoryApplication() app.RetainBlocks = 10 node := rpctest.StartTendermint(app) diff --git a/light/rpc/client.go b/light/rpc/client.go index 920641295..eba9bbec7 100644 --- a/light/rpc/client.go +++ b/light/rpc/client.go @@ -8,9 +8,6 @@ import ( "regexp" "time" - "github.com/cosmos/gogoproto/proto" - - abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto/merkle" tmbytes "github.com/tendermint/tendermint/libs/bytes" tmmath "github.com/tendermint/tendermint/libs/math" @@ -18,6 +15,7 @@ import ( rpcclient "github.com/tendermint/tendermint/rpc/client" ctypes "github.com/tendermint/tendermint/rpc/core/types" rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types" + "github.com/tendermint/tendermint/state" "github.com/tendermint/tendermint/types" ) @@ -379,6 +377,7 @@ func (c *Client) BlockByHash(ctx context.Context, hash []byte) (*ctypes.ResultBl // BlockResults returns the block results for the given height. If no height is // provided, the results of the block preceding the latest are returned. +// NOTE: Light client only verifies the tx results func (c *Client) BlockResults(ctx context.Context, height *int64) (*ctypes.ResultBlockResults, error) { var h int64 if height == nil { @@ -410,27 +409,8 @@ func (c *Client) BlockResults(ctx context.Context, height *int64) (*ctypes.Resul return nil, err } - // proto-encode BeginBlock events - bbeBytes, err := proto.Marshal(&abci.ResponseBeginBlock{ - Events: res.BeginBlockEvents, - }) - if err != nil { - return nil, err - } - - // Build a Merkle tree of proto-encoded DeliverTx results and get a hash. - results := types.NewResults(res.TxsResults) - - // proto-encode EndBlock events. - ebeBytes, err := proto.Marshal(&abci.ResponseEndBlock{ - Events: res.EndBlockEvents, - }) - if err != nil { - return nil, err - } - // Build a Merkle tree out of the above 3 binary slices. - rH := merkle.HashFromByteSlices([][]byte{bbeBytes, results.Hash(), ebeBytes}) + rH := state.TxResultsHash(res.TxsResults) // Verify block results. if !bytes.Equal(rH, trustedBlock.LastResultsHash) { diff --git a/mempool/mempool.go b/mempool/mempool.go index bf6eb2e72..4de0f61b5 100644 --- a/mempool/mempool.go +++ b/mempool/mempool.go @@ -32,7 +32,7 @@ const ( type Mempool interface { // CheckTx executes a new transaction against the application to determine // its validity and whether it should be added to the mempool. - CheckTx(tx types.Tx, callback func(*abci.Response), txInfo TxInfo) error + CheckTx(tx types.Tx, callback func(*abci.ResponseCheckTx), txInfo TxInfo) error // RemoveTxByKey removes a transaction, identified by its key, // from the mempool. @@ -67,7 +67,7 @@ type Mempool interface { Update( blockHeight int64, blockTxs types.Txs, - deliverTxResponses []*abci.ResponseDeliverTx, + deliverTxResponses []*abci.ExecTxResult, newPreFn PreCheckFunc, newPostFn PostCheckFunc, ) error diff --git a/mempool/mocks/mempool.go b/mempool/mocks/mempool.go index fa16a2633..6eb65f198 100644 --- a/mempool/mocks/mempool.go +++ b/mempool/mocks/mempool.go @@ -17,11 +17,11 @@ type Mempool struct { } // CheckTx provides a mock function with given fields: tx, callback, txInfo -func (_m *Mempool) CheckTx(tx types.Tx, callback func(*abcitypes.Response), txInfo mempool.TxInfo) error { +func (_m *Mempool) CheckTx(tx types.Tx, callback func(*abcitypes.ResponseCheckTx), txInfo mempool.TxInfo) error { ret := _m.Called(tx, callback, txInfo) var r0 error - if rf, ok := ret.Get(0).(func(types.Tx, func(*abcitypes.Response), mempool.TxInfo) error); ok { + if rf, ok := ret.Get(0).(func(types.Tx, func(*abcitypes.ResponseCheckTx), mempool.TxInfo) error); ok { r0 = rf(tx, callback, txInfo) } else { r0 = ret.Error(0) @@ -155,11 +155,11 @@ func (_m *Mempool) Unlock() { } // Update provides a mock function with given fields: blockHeight, blockTxs, deliverTxResponses, newPreFn, newPostFn -func (_m *Mempool) Update(blockHeight int64, blockTxs types.Txs, deliverTxResponses []*abcitypes.ResponseDeliverTx, newPreFn mempool.PreCheckFunc, newPostFn mempool.PostCheckFunc) error { +func (_m *Mempool) Update(blockHeight int64, blockTxs types.Txs, deliverTxResponses []*abcitypes.ExecTxResult, newPreFn mempool.PreCheckFunc, newPostFn mempool.PostCheckFunc) error { ret := _m.Called(blockHeight, blockTxs, deliverTxResponses, newPreFn, newPostFn) var r0 error - if rf, ok := ret.Get(0).(func(int64, types.Txs, []*abcitypes.ResponseDeliverTx, mempool.PreCheckFunc, mempool.PostCheckFunc) error); ok { + if rf, ok := ret.Get(0).(func(int64, types.Txs, []*abcitypes.ExecTxResult, mempool.PreCheckFunc, mempool.PostCheckFunc) error); ok { r0 = rf(blockHeight, blockTxs, deliverTxResponses, newPreFn, newPostFn) } else { r0 = ret.Error(0) diff --git a/mempool/v0/bench_test.go b/mempool/v0/bench_test.go index cb1be502a..19c704e55 100644 --- a/mempool/v0/bench_test.go +++ b/mempool/v0/bench_test.go @@ -11,7 +11,7 @@ import ( ) func BenchmarkReap(b *testing.B) { - app := kvstore.NewApplication() + app := kvstore.NewInMemoryApplication() cc := proxy.NewLocalClientCreator(app) mp, cleanup := newMempoolWithApp(cc) defer cleanup() @@ -33,7 +33,7 @@ func BenchmarkReap(b *testing.B) { } func BenchmarkCheckTx(b *testing.B) { - app := kvstore.NewApplication() + app := kvstore.NewInMemoryApplication() cc := proxy.NewLocalClientCreator(app) mp, cleanup := newMempoolWithApp(cc) defer cleanup() @@ -55,7 +55,7 @@ func BenchmarkCheckTx(b *testing.B) { } func BenchmarkParallelCheckTx(b *testing.B) { - app := kvstore.NewApplication() + app := kvstore.NewInMemoryApplication() cc := proxy.NewLocalClientCreator(app) mp, cleanup := newMempoolWithApp(cc) defer cleanup() @@ -80,7 +80,7 @@ func BenchmarkParallelCheckTx(b *testing.B) { } func BenchmarkCheckDuplicateTx(b *testing.B) { - app := kvstore.NewApplication() + app := kvstore.NewInMemoryApplication() cc := proxy.NewLocalClientCreator(app) mp, cleanup := newMempoolWithApp(cc) defer cleanup() diff --git a/mempool/v0/cache_test.go b/mempool/v0/cache_test.go index c62e99891..4e50ffc68 100644 --- a/mempool/v0/cache_test.go +++ b/mempool/v0/cache_test.go @@ -2,6 +2,7 @@ package v0 import ( "crypto/sha256" + "fmt" "testing" "github.com/stretchr/testify/require" @@ -14,7 +15,7 @@ import ( ) func TestCacheAfterUpdate(t *testing.T) { - app := kvstore.NewApplication() + app := kvstore.NewInMemoryApplication() cc := proxy.NewLocalClientCreator(app) mp, cleanup := newMempoolWithApp(cc) defer cleanup() @@ -35,22 +36,26 @@ func TestCacheAfterUpdate(t *testing.T) { } for tcIndex, tc := range tests { for i := 0; i < tc.numTxsToCreate; i++ { - tx := types.Tx{byte(i)} - err := mp.CheckTx(tx, nil, mempool.TxInfo{}) + tx := kvstore.NewTx(fmt.Sprintf("%d", i), "value") + err := mp.CheckTx(tx, func(resp *abci.ResponseCheckTx) { + require.False(t, resp.IsErr()) + }, mempool.TxInfo{}) require.NoError(t, err) } updateTxs := []types.Tx{} for _, v := range tc.updateIndices { - tx := types.Tx{byte(v)} + tx := kvstore.NewTx(fmt.Sprintf("%d", v), "value") updateTxs = append(updateTxs, tx) } err := mp.Update(int64(tcIndex), updateTxs, abciResponses(len(updateTxs), abci.CodeTypeOK), nil, nil) require.NoError(t, err) for _, v := range tc.reAddIndices { - tx := types.Tx{byte(v)} - _ = mp.CheckTx(tx, nil, mempool.TxInfo{}) + tx := kvstore.NewTx(fmt.Sprintf("%d", v), "value") + _ = mp.CheckTx(tx, func(resp *abci.ResponseCheckTx) { + require.False(t, resp.IsErr()) + }, mempool.TxInfo{}) } cache := mp.cache.(*mempool.LRUTxCache) @@ -61,7 +66,8 @@ func TestCacheAfterUpdate(t *testing.T) { "cache larger than expected on testcase %d", tcIndex) nodeVal := node.Value.(types.TxKey) - expectedBz := sha256.Sum256([]byte{byte(tc.txsInCache[len(tc.txsInCache)-counter-1])}) + expTx := kvstore.NewTx(fmt.Sprintf("%d", tc.txsInCache[len(tc.txsInCache)-counter-1]), "value") + expectedBz := sha256.Sum256(expTx) // Reference for reading the errors: // >>> sha256('\x00').hexdigest() // '6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d' diff --git a/mempool/v0/clist_mempool.go b/mempool/v0/clist_mempool.go index 516a57f22..9fb23c52a 100644 --- a/mempool/v0/clist_mempool.go +++ b/mempool/v0/clist_mempool.go @@ -2,6 +2,7 @@ package v0 import ( "bytes" + "context" "errors" "sync" "sync/atomic" @@ -152,7 +153,7 @@ func (mem *CListMempool) SizeBytes() int64 { // Lock() must be help by the caller during execution. func (mem *CListMempool) FlushAppConn() error { - return mem.proxyAppConn.FlushSync() + return mem.proxyAppConn.Flush(context.TODO()) } // XXX: Unsafe! Calling Flush may leave mempool in inconsistent state. @@ -202,7 +203,7 @@ func (mem *CListMempool) TxsWaitChan() <-chan struct{} { // Safe for concurrent use by multiple goroutines. func (mem *CListMempool) CheckTx( tx types.Tx, - cb func(*abci.Response), + cb func(*abci.ResponseCheckTx), txInfo mempool.TxInfo, ) error { @@ -251,7 +252,10 @@ func (mem *CListMempool) CheckTx( return mempool.ErrTxInCache } - reqRes := mem.proxyAppConn.CheckTxAsync(abci.RequestCheckTx{Tx: tx}) + reqRes, err := mem.proxyAppConn.CheckTxAsync(context.TODO(), &abci.RequestCheckTx{Tx: tx}) + if err != nil { + return err + } reqRes.SetCallback(mem.reqResCb(tx, txInfo.SenderID, txInfo.SenderP2PID, cb)) return nil @@ -291,7 +295,7 @@ func (mem *CListMempool) reqResCb( tx []byte, peerID uint16, peerP2PID p2p.ID, - externalCb func(*abci.Response), + externalCb func(*abci.ResponseCheckTx), ) func(res *abci.Response) { return func(res *abci.Response) { if mem.recheckCursor != nil { @@ -306,7 +310,7 @@ func (mem *CListMempool) reqResCb( // passed in by the caller of CheckTx, eg. the RPC if externalCb != nil { - externalCb(res) + externalCb(res.GetCheckTx()) } } } @@ -579,7 +583,7 @@ func (mem *CListMempool) ReapMaxTxs(max int) types.Txs { func (mem *CListMempool) Update( height int64, txs types.Txs, - deliverTxResponses []*abci.ResponseDeliverTx, + txResults []*abci.ExecTxResult, preCheck mempool.PreCheckFunc, postCheck mempool.PostCheckFunc, ) error { @@ -595,7 +599,7 @@ func (mem *CListMempool) Update( } for i, tx := range txs { - if deliverTxResponses[i].Code == abci.CodeTypeOK { + if txResults[i].Code == abci.CodeTypeOK { // Add valid committed tx to the cache (if missing). _ = mem.cache.Push(tx) } else if !mem.config.KeepInvalidTxsInCache { @@ -650,13 +654,19 @@ func (mem *CListMempool) recheckTxs() { // NOTE: globalCb may be called concurrently. for e := mem.txs.Front(); e != nil; e = e.Next() { memTx := e.Value.(*mempoolTx) - mem.proxyAppConn.CheckTxAsync(abci.RequestCheckTx{ + _, err := mem.proxyAppConn.CheckTxAsync(context.TODO(), &abci.RequestCheckTx{ Tx: memTx.tx, Type: abci.CheckTxType_Recheck, }) + if err != nil { + mem.logger.Error("recheckTx", err, "err") + return + } } - mem.proxyAppConn.FlushAsync() + // In ensure it's received by the second reactor. - tx1 := tmrand.Bytes(config.Mempool.MaxTxBytes) - err := reactors[0].mempool.CheckTx(tx1, nil, mempool.TxInfo{SenderID: mempool.UnknownPeerID}) + tx1 := kvstore.NewRandomTx(config.Mempool.MaxTxBytes) + err := reactors[0].mempool.CheckTx(tx1, func(resp *abci.ResponseCheckTx) { + require.False(t, resp.IsErr()) + }, mempool.TxInfo{SenderID: mempool.UnknownPeerID}) require.NoError(t, err) waitForTxsOnReactors(t, []types.Tx{tx1}, reactors) @@ -180,8 +181,10 @@ func TestReactor_MaxTxBytes(t *testing.T) { // Broadcast a tx, which is beyond the max size // => ensure it's not sent - tx2 := tmrand.Bytes(config.Mempool.MaxTxBytes + 1) - err = reactors[0].mempool.CheckTx(tx2, nil, mempool.TxInfo{SenderID: mempool.UnknownPeerID}) + tx2 := kvstore.NewRandomTx(config.Mempool.MaxTxBytes + 1) + err = reactors[0].mempool.CheckTx(tx2, func(resp *abci.ResponseCheckTx) { + require.False(t, resp.IsErr()) + }, mempool.TxInfo{SenderID: mempool.UnknownPeerID}) require.Error(t, err) } @@ -311,7 +314,7 @@ func makeAndConnectReactors(config *cfg.Config, n int) []*Reactor { reactors := make([]*Reactor, n) logger := mempoolLogger() for i := 0; i < n; i++ { - app := kvstore.NewApplication() + app := kvstore.NewInMemoryApplication() cc := proxy.NewLocalClientCreator(app) mempool, cleanup := newMempoolWithApp(cc) defer cleanup() diff --git a/mempool/v1/mempool.go b/mempool/v1/mempool.go index 8b444ac53..6f7b19e83 100644 --- a/mempool/v1/mempool.go +++ b/mempool/v1/mempool.go @@ -1,6 +1,7 @@ package v1 import ( + "context" "fmt" "runtime" "sort" @@ -138,7 +139,7 @@ func (txmp *TxMempool) FlushAppConn() error { txmp.mtx.Unlock() defer txmp.mtx.Lock() - return txmp.proxyAppConn.FlushSync() + return txmp.proxyAppConn.Flush(context.TODO()) } // EnableTxsAvailable enables the mempool to trigger events when transactions @@ -174,7 +175,7 @@ func (txmp *TxMempool) TxsAvailable() <-chan struct{} { return txmp.txsAvailable // is (strictly) lower than the priority of tx and whose size together exceeds // the size of tx, and adds tx instead. If no such transactions exist, tx is // discarded. -func (txmp *TxMempool) CheckTx(tx types.Tx, cb func(*abci.Response), txInfo mempool.TxInfo) error { +func (txmp *TxMempool) CheckTx(tx types.Tx, cb func(*abci.ResponseCheckTx), txInfo mempool.TxInfo) error { // During the initial phase of CheckTx, we do not need to modify any state. // A transaction will not actually be added to the mempool until it survives @@ -218,7 +219,7 @@ func (txmp *TxMempool) CheckTx(tx types.Tx, cb func(*abci.Response), txInfo memp } // Invoke an ABCI CheckTx for this transaction. - rsp, err := txmp.proxyAppConn.CheckTxSync(abci.RequestCheckTx{Tx: tx}) + rsp, err := txmp.proxyAppConn.CheckTx(context.TODO(), &abci.RequestCheckTx{Tx: tx}) if err != nil { txmp.cache.Remove(tx) return err @@ -232,7 +233,7 @@ func (txmp *TxMempool) CheckTx(tx types.Tx, cb func(*abci.Response), txInfo memp wtx.SetPeer(txInfo.SenderID) txmp.addNewTransaction(wtx, rsp) if cb != nil { - cb(&abci.Response{Value: &abci.Response_CheckTx{CheckTx: rsp}}) + cb(rsp) } return nil } @@ -367,7 +368,7 @@ func (txmp *TxMempool) ReapMaxTxs(max int) types.Txs { } // Update removes all the given transactions from the mempool and the cache, -// and updates the current block height. The blockTxs and deliverTxResponses +// and updates the current block height. The blockTxs and txResults // must have the same length with each response corresponding to the tx at the // same offset. // @@ -380,14 +381,14 @@ func (txmp *TxMempool) ReapMaxTxs(max int) types.Txs { func (txmp *TxMempool) Update( blockHeight int64, blockTxs types.Txs, - deliverTxResponses []*abci.ResponseDeliverTx, + txResults []*abci.ExecTxResult, newPreFn mempool.PreCheckFunc, newPostFn mempool.PostCheckFunc, ) error { // Safety check: Transactions and responses must match in number. - if len(blockTxs) != len(deliverTxResponses) { - panic(fmt.Sprintf("mempool: got %d transactions but %d DeliverTx responses", - len(blockTxs), len(deliverTxResponses))) + if len(blockTxs) != len(txResults) { + panic(fmt.Sprintf("mempool: got %d transactions but %d TxResult responses", + len(blockTxs), len(txResults))) } txmp.height = blockHeight @@ -404,7 +405,7 @@ func (txmp *TxMempool) Update( // Add successful committed transactions to the cache (if they are not // already present). Transactions that failed to commit are removed from // the cache unless the operator has explicitly requested we keep them. - if deliverTxResponses[i].Code == abci.CodeTypeOK { + if txResults[i].Code == abci.CodeTypeOK { _ = txmp.cache.Push(tx) } else if !txmp.config.KeepInvalidTxsInCache { txmp.cache.Remove(tx) @@ -679,7 +680,7 @@ func (txmp *TxMempool) recheckTransactions() { wtx := wtx start(func() error { // The response for this CheckTx is handled by the default recheckTxCallback. - rsp, err := txmp.proxyAppConn.CheckTxSync(abci.RequestCheckTx{ + rsp, err := txmp.proxyAppConn.CheckTx(context.TODO(), &abci.RequestCheckTx{ Tx: wtx.tx, Type: abci.CheckTxType_Recheck, }) @@ -692,7 +693,9 @@ func (txmp *TxMempool) recheckTransactions() { return nil }) } - _ = txmp.proxyAppConn.FlushAsync() + // In 0 { - responses := make([]*abci.ResponseDeliverTx, len(reapedTxs)) + responses := make([]*abci.ExecTxResult, len(reapedTxs)) for i := 0; i < len(responses); i++ { var code uint32 @@ -495,7 +495,7 @@ func TestTxMempool_ConcurrentTxs(t *testing.T) { code = abci.CodeTypeOK } - responses[i] = &abci.ResponseDeliverTx{Code: code} + responses[i] = &abci.ExecTxResult{Code: code} } txmp.Lock() @@ -577,9 +577,9 @@ func TestTxMempool_ExpiredTxs_NumBlocks(t *testing.T) { // reap 5 txs at the next height -- no txs should expire reapedTxs := txmp.ReapMaxTxs(5) - responses := make([]*abci.ResponseDeliverTx, len(reapedTxs)) + responses := make([]*abci.ExecTxResult, len(reapedTxs)) for i := 0; i < len(responses); i++ { - responses[i] = &abci.ResponseDeliverTx{Code: abci.CodeTypeOK} + responses[i] = &abci.ExecTxResult{Code: abci.CodeTypeOK} } txmp.Lock() @@ -601,9 +601,9 @@ func TestTxMempool_ExpiredTxs_NumBlocks(t *testing.T) { // removed. However, we do know that that at most 95 txs can be expired and // removed. reapedTxs = txmp.ReapMaxTxs(5) - responses = make([]*abci.ResponseDeliverTx, len(reapedTxs)) + responses = make([]*abci.ExecTxResult, len(reapedTxs)) for i := 0; i < len(responses); i++ { - responses[i] = &abci.ResponseDeliverTx{Code: abci.CodeTypeOK} + responses[i] = &abci.ExecTxResult{Code: abci.CodeTypeOK} } txmp.Lock() @@ -639,14 +639,12 @@ func TestTxMempool_CheckTxPostCheckError(t *testing.T) { _, err := rng.Read(tx) require.NoError(t, err) - callback := func(res *abci.Response) { - checkTxRes, ok := res.Value.(*abci.Response_CheckTx) - require.True(t, ok) + callback := func(res *abci.ResponseCheckTx) { expectedErrString := "" if testCase.err != nil { expectedErrString = testCase.err.Error() } - require.Equal(t, expectedErrString, checkTxRes.CheckTx.MempoolError) + require.Equal(t, expectedErrString, res.MempoolError) } require.NoError(t, txmp.CheckTx(tx, callback, mempool.TxInfo{SenderID: 0})) }) diff --git a/mempool/v1/reactor_test.go b/mempool/v1/reactor_test.go index 9dc56839f..a114d4fc6 100644 --- a/mempool/v1/reactor_test.go +++ b/mempool/v1/reactor_test.go @@ -98,7 +98,7 @@ func makeAndConnectReactors(config *cfg.Config, n int) []*Reactor { reactors := make([]*Reactor, n) logger := mempoolLogger() for i := 0; i < n; i++ { - app := kvstore.NewApplication() + app := kvstore.NewInMemoryApplication() cc := proxy.NewLocalClientCreator(app) mempool, cleanup := newMempoolWithApp(cc) defer cleanup() diff --git a/node/node.go b/node/node.go index ddf86e0dc..2342257cf 100644 --- a/node/node.go +++ b/node/node.go @@ -171,7 +171,7 @@ func NewNode(config *cfg.Config, // EventBus and IndexerService must be started before the handshake because // we might need to index the txs of the replayed block as this might not have happened // when the node stopped last time (i.e. the node stopped after it saved the block - // but before it indexed the txs, or, endblocker panicked) + // but before it indexed the txs) eventBus, err := createAndStartEventBus(logger) if err != nil { return nil, err diff --git a/node/node_test.go b/node/node_test.go index 4fdf63f3f..436218d78 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -125,7 +125,7 @@ func TestNodeSetAppVersion(t *testing.T) { require.NoError(t, err) // default config uses the kvstore app - var appVersion = kvstore.ProtocolVersion + var appVersion = kvstore.AppVersion // check version is set in state state, err := n.stateStore.Load() @@ -250,7 +250,7 @@ func testFreeAddr(t *testing.T) string { func TestCreateProposalBlock(t *testing.T) { config := test.ResetTestRoot("node_create_proposal") defer os.RemoveAll(config.RootDir) - cc := proxy.NewLocalClientCreator(kvstore.NewApplication()) + cc := proxy.NewLocalClientCreator(kvstore.NewInMemoryApplication()) proxyApp := proxy.NewAppConns(cc, proxy.NopMetrics()) err := proxyApp.Start() require.Nil(t, err) @@ -362,7 +362,7 @@ func TestCreateProposalBlock(t *testing.T) { func TestMaxProposalBlockSize(t *testing.T) { config := test.ResetTestRoot("node_create_proposal") defer os.RemoveAll(config.RootDir) - cc := proxy.NewLocalClientCreator(kvstore.NewApplication()) + cc := proxy.NewLocalClientCreator(kvstore.NewInMemoryApplication()) proxyApp := proxy.NewAppConns(cc, proxy.NopMetrics()) err := proxyApp.Start() require.Nil(t, err) diff --git a/node/setup.go b/node/setup.go index 5bada8b6f..5fedcbe8e 100644 --- a/node/setup.go +++ b/node/setup.go @@ -413,7 +413,7 @@ func createTransport( connFilters, // ABCI query for address filtering. func(_ p2p.ConnSet, c net.Conn, _ []net.IP) error { - res, err := proxyApp.Query().QuerySync(abci.RequestQuery{ + res, err := proxyApp.Query().Query(context.TODO(), &abci.RequestQuery{ Path: fmt.Sprintf("/p2p/filter/addr/%s", c.RemoteAddr().String()), }) if err != nil { @@ -431,7 +431,7 @@ func createTransport( peerFilters, // ABCI query for ID filtering. func(_ p2p.IPeerSet, p p2p.Peer) error { - res, err := proxyApp.Query().QuerySync(abci.RequestQuery{ + res, err := proxyApp.Query().Query(context.TODO(), &abci.RequestQuery{ Path: fmt.Sprintf("/p2p/filter/id/%s", p.ID()), }) if err != nil { diff --git a/proto/tendermint/abci/types.proto b/proto/tendermint/abci/types.proto index a03b6fbf2..241decdf1 100644 --- a/proto/tendermint/abci/types.proto +++ b/proto/tendermint/abci/types.proto @@ -6,16 +6,33 @@ option go_package = "github.com/tendermint/tendermint/abci/types"; // For more information on gogo.proto, see: // https://github.com/cosmos/gogoproto/blob/master/extensions.md import "tendermint/crypto/proof.proto"; -import "tendermint/types/types.proto"; import "tendermint/crypto/keys.proto"; import "tendermint/types/params.proto"; import "google/protobuf/timestamp.proto"; import "gogoproto/gogo.proto"; -// This file is copied from http://github.com/tendermint/abci // NOTE: When using custom types, mind the warnings. // https://github.com/cosmos/gogoproto/blob/master/custom_types.md#warnings-and-issues +service ABCI { + rpc Echo(RequestEcho) returns (ResponseEcho); + rpc Flush(RequestFlush) returns (ResponseFlush); + rpc Info(RequestInfo) returns (ResponseInfo); + rpc CheckTx(RequestCheckTx) returns (ResponseCheckTx); + rpc Query(RequestQuery) returns (ResponseQuery); + rpc Commit(RequestCommit) returns (ResponseCommit); + rpc InitChain(RequestInitChain) returns (ResponseInitChain); + rpc ListSnapshots(RequestListSnapshots) returns (ResponseListSnapshots); + rpc OfferSnapshot(RequestOfferSnapshot) returns (ResponseOfferSnapshot); + rpc LoadSnapshotChunk(RequestLoadSnapshotChunk) + returns (ResponseLoadSnapshotChunk); + rpc ApplySnapshotChunk(RequestApplySnapshotChunk) + returns (ResponseApplySnapshotChunk); + rpc PrepareProposal(RequestPrepareProposal) returns (ResponsePrepareProposal); + rpc ProcessProposal(RequestProcessProposal) returns (ResponseProcessProposal); + rpc FinalizeBlock(RequestFinalizeBlock) returns (ResponseFinalizeBlock); +} + //---------------------------------------- // Request types @@ -26,10 +43,7 @@ message Request { RequestInfo info = 3; RequestInitChain init_chain = 5; RequestQuery query = 6; - RequestBeginBlock begin_block = 7; RequestCheckTx check_tx = 8; - RequestDeliverTx deliver_tx = 9; - RequestEndBlock end_block = 10; RequestCommit commit = 11; RequestListSnapshots list_snapshots = 12; RequestOfferSnapshot offer_snapshot = 13; @@ -37,8 +51,9 @@ message Request { RequestApplySnapshotChunk apply_snapshot_chunk = 15; RequestPrepareProposal prepare_proposal = 16; RequestProcessProposal process_proposal = 17; + RequestFinalizeBlock finalize_block = 20; } - reserved 4; + reserved 4, 7, 9, 10; // SetOption, BeginBlock, DeliverTx, EndBlock } message RequestEcho { @@ -71,13 +86,6 @@ message RequestQuery { bool prove = 4; } -message RequestBeginBlock { - bytes hash = 1; - tendermint.types.Header header = 2 [(gogoproto.nullable) = false]; - CommitInfo last_commit_info = 3 [(gogoproto.nullable) = false]; - repeated Misbehavior byzantine_validators = 4 [(gogoproto.nullable) = false]; -} - enum CheckTxType { NEW = 0 [(gogoproto.enumvalue_customname) = "New"]; RECHECK = 1 [(gogoproto.enumvalue_customname) = "Recheck"]; @@ -88,14 +96,6 @@ message RequestCheckTx { CheckTxType type = 2; } -message RequestDeliverTx { - bytes tx = 1; -} - -message RequestEndBlock { - int64 height = 1; -} - message RequestCommit {} // lists available snapshots @@ -149,6 +149,19 @@ message RequestProcessProposal { bytes proposer_address = 8; } +message RequestFinalizeBlock { + repeated bytes txs = 1; + CommitInfo decided_last_commit = 2 [(gogoproto.nullable) = false]; + repeated Misbehavior misbehavior = 3 [(gogoproto.nullable) = false]; + // hash is the merkle root hash of the fields of the decided block. + bytes hash = 4; + int64 height = 5; + google.protobuf.Timestamp time = 6 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + bytes next_validators_hash = 7; + // proposer_address is the address of the public key of the original proposer of the block. + bytes proposer_address = 8; +} + //---------------------------------------- // Response types @@ -160,10 +173,7 @@ message Response { ResponseInfo info = 4; ResponseInitChain init_chain = 6; ResponseQuery query = 7; - ResponseBeginBlock begin_block = 8; ResponseCheckTx check_tx = 9; - ResponseDeliverTx deliver_tx = 10; - ResponseEndBlock end_block = 11; ResponseCommit commit = 12; ResponseListSnapshots list_snapshots = 13; ResponseOfferSnapshot offer_snapshot = 14; @@ -171,8 +181,9 @@ message Response { ResponseApplySnapshotChunk apply_snapshot_chunk = 16; ResponsePrepareProposal prepare_proposal = 17; ResponseProcessProposal process_proposal = 18; + ResponseFinalizeBlock finalize_block = 21; } - reserved 5; + reserved 5, 8, 10, 11; // SetOption, BeginBlock, DeliverTx, EndBlock } // nondeterministic @@ -215,11 +226,6 @@ message ResponseQuery { string codespace = 10; } -message ResponseBeginBlock { - repeated Event events = 1 - [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; -} - message ResponseCheckTx { uint32 code = 1; bytes data = 2; @@ -238,30 +244,8 @@ message ResponseCheckTx { string mempool_error = 11; } -message ResponseDeliverTx { - uint32 code = 1; - bytes data = 2; - string log = 3; // nondeterministic - string info = 4; // nondeterministic - int64 gas_wanted = 5 [json_name = "gas_wanted"]; - int64 gas_used = 6 [json_name = "gas_used"]; - repeated Event events = 7 [ - (gogoproto.nullable) = false, - (gogoproto.jsontag) = "events,omitempty" - ]; // nondeterministic - string codespace = 8; -} - -message ResponseEndBlock { - repeated ValidatorUpdate validator_updates = 1 [(gogoproto.nullable) = false]; - tendermint.types.ConsensusParams consensus_param_updates = 2; - repeated Event events = 3 - [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; -} - message ResponseCommit { - // reserve 1 - bytes data = 2; + reserved 1, 2; // data was previously returned here int64 retain_height = 3; } @@ -315,6 +299,22 @@ message ResponseProcessProposal { } } +message ResponseFinalizeBlock { + // set of block events emmitted as part of executing the block + repeated Event events = 1 + [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; + // the result of executing each transaction including the events + // the particular transction emitted. This should match the order + // of the transactions delivered in the block itself + repeated ExecTxResult tx_results = 2; + // a list of updates to the validator set. These will reflect the validator set at current height + 2. + repeated ValidatorUpdate validator_updates = 3 [(gogoproto.nullable) = false]; + // updates to the consensus params, if any. + tendermint.types.ConsensusParams consensus_param_updates = 4; + // agreed_app_data is the bytes that all nodes reach consensus upon in the following height. It is often the hash of the applications' state which can be used to confirm that execution of the transactions was deterministic. + bytes agreed_app_data = 5; +} + //---------------------------------------- // Misc. @@ -332,7 +332,7 @@ message ExtendedCommitInfo { } // Event allows application developers to attach additional information to -// ResponseBeginBlock, ResponseEndBlock, ResponseCheckTx and ResponseDeliverTx. +// ResponseFinalizeBlock and ResponseCheckTx. // Later, transactions may be queried using these events. message Event { string type = 1; @@ -349,14 +349,29 @@ message EventAttribute { bool index = 3; // nondeterministic } +// ExecTxResult contains results of executing one individual transaction. +// +// * Its structure is equivalent to #ResponseDeliverTx which will be deprecated/deleted +message ExecTxResult { + uint32 code = 1; + bytes data = 2; + string log = 3; // nondeterministic + string info = 4; // nondeterministic + int64 gas_wanted = 5; + int64 gas_used = 6; + repeated Event events = 7 + [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; // nondeterministic + string codespace = 8; +} + // TxResult contains results of executing the transaction. // // One usage is indexing transaction results. message TxResult { - int64 height = 1; - uint32 index = 2; - bytes tx = 3; - ResponseDeliverTx result = 4 [(gogoproto.nullable) = false]; + int64 height = 1; + uint32 index = 2; + bytes tx = 3; + ExecTxResult result = 4 [(gogoproto.nullable) = false]; } //---------------------------------------- @@ -418,27 +433,3 @@ message Snapshot { bytes hash = 4; // Arbitrary snapshot hash, equal only if identical bytes metadata = 5; // Arbitrary application metadata } - -//---------------------------------------- -// Service Definition - -service ABCIApplication { - rpc Echo(RequestEcho) returns (ResponseEcho); - rpc Flush(RequestFlush) returns (ResponseFlush); - rpc Info(RequestInfo) returns (ResponseInfo); - rpc DeliverTx(RequestDeliverTx) returns (ResponseDeliverTx); - rpc CheckTx(RequestCheckTx) returns (ResponseCheckTx); - rpc Query(RequestQuery) returns (ResponseQuery); - rpc Commit(RequestCommit) returns (ResponseCommit); - rpc InitChain(RequestInitChain) returns (ResponseInitChain); - rpc BeginBlock(RequestBeginBlock) returns (ResponseBeginBlock); - rpc EndBlock(RequestEndBlock) returns (ResponseEndBlock); - rpc ListSnapshots(RequestListSnapshots) returns (ResponseListSnapshots); - rpc OfferSnapshot(RequestOfferSnapshot) returns (ResponseOfferSnapshot); - rpc LoadSnapshotChunk(RequestLoadSnapshotChunk) - returns (ResponseLoadSnapshotChunk); - rpc ApplySnapshotChunk(RequestApplySnapshotChunk) - returns (ResponseApplySnapshotChunk); - rpc PrepareProposal(RequestPrepareProposal) returns (ResponsePrepareProposal); - rpc ProcessProposal(RequestProcessProposal) returns (ResponseProcessProposal); -} diff --git a/proto/tendermint/rpc/grpc/types.pb.go b/proto/tendermint/rpc/grpc/types.pb.go index 6d0fecf0b..4496379b9 100644 --- a/proto/tendermint/rpc/grpc/types.pb.go +++ b/proto/tendermint/rpc/grpc/types.pb.go @@ -145,8 +145,8 @@ func (m *ResponsePing) XXX_DiscardUnknown() { var xxx_messageInfo_ResponsePing proto.InternalMessageInfo type ResponseBroadcastTx struct { - CheckTx *types.ResponseCheckTx `protobuf:"bytes,1,opt,name=check_tx,json=checkTx,proto3" json:"check_tx,omitempty"` - DeliverTx *types.ResponseDeliverTx `protobuf:"bytes,2,opt,name=deliver_tx,json=deliverTx,proto3" json:"deliver_tx,omitempty"` + CheckTx *types.ResponseCheckTx `protobuf:"bytes,1,opt,name=check_tx,json=checkTx,proto3" json:"check_tx,omitempty"` + TxResult *types.ExecTxResult `protobuf:"bytes,2,opt,name=tx_result,json=txResult,proto3" json:"tx_result,omitempty"` } func (m *ResponseBroadcastTx) Reset() { *m = ResponseBroadcastTx{} } @@ -189,9 +189,9 @@ func (m *ResponseBroadcastTx) GetCheckTx() *types.ResponseCheckTx { return nil } -func (m *ResponseBroadcastTx) GetDeliverTx() *types.ResponseDeliverTx { +func (m *ResponseBroadcastTx) GetTxResult() *types.ExecTxResult { if m != nil { - return m.DeliverTx + return m.TxResult } return nil } @@ -206,7 +206,7 @@ func init() { func init() { proto.RegisterFile("tendermint/rpc/grpc/types.proto", fileDescriptor_0ffff5682c662b95) } var fileDescriptor_0ffff5682c662b95 = []byte{ - // 316 bytes of a gzipped FileDescriptorProto + // 320 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x2f, 0x49, 0xcd, 0x4b, 0x49, 0x2d, 0xca, 0xcd, 0xcc, 0x2b, 0xd1, 0x2f, 0x2a, 0x48, 0xd6, 0x4f, 0x07, 0x11, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0xc2, 0x08, 0x05, 0x7a, 0x45, 0x05, @@ -214,19 +214,19 @@ var fileDescriptor_0ffff5682c662b95 = []byte{ 0x72, 0x71, 0x07, 0xa5, 0x16, 0x96, 0xa6, 0x16, 0x97, 0x04, 0x64, 0xe6, 0xa5, 0x2b, 0xa9, 0x70, 0x09, 0x41, 0xb9, 0x4e, 0x45, 0xf9, 0x89, 0x29, 0xc9, 0x89, 0xc5, 0x25, 0x21, 0x15, 0x42, 0x7c, 0x5c, 0x4c, 0x25, 0x15, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x3c, 0x41, 0x4c, 0x25, 0x15, 0x4a, 0x7c, - 0x5c, 0x3c, 0x41, 0xa9, 0xc5, 0x05, 0xf9, 0x79, 0xc5, 0xa9, 0x60, 0x5d, 0x53, 0x19, 0xb9, 0x84, - 0x61, 0x02, 0xc8, 0xfa, 0xac, 0xb9, 0x38, 0x92, 0x33, 0x52, 0x93, 0xb3, 0xe3, 0xa1, 0xba, 0xb9, - 0x8d, 0x14, 0xf4, 0x90, 0x5c, 0x08, 0x72, 0x8c, 0x1e, 0x4c, 0x9f, 0x33, 0x48, 0x61, 0x48, 0x45, - 0x10, 0x7b, 0x32, 0x84, 0x21, 0xe4, 0xc8, 0xc5, 0x95, 0x92, 0x9a, 0x93, 0x59, 0x96, 0x5a, 0x04, - 0xd2, 0xce, 0x04, 0xd6, 0xae, 0x84, 0x53, 0xbb, 0x0b, 0x44, 0x69, 0x48, 0x45, 0x10, 0x67, 0x0a, - 0x8c, 0x69, 0xb4, 0x97, 0x91, 0x8b, 0x07, 0xee, 0x1e, 0xc7, 0x00, 0x4f, 0x21, 0x6f, 0x2e, 0x16, - 0x90, 0x83, 0x85, 0x50, 0x9c, 0x01, 0x0b, 0x28, 0x3d, 0xa4, 0x80, 0x90, 0x52, 0xc4, 0xa1, 0x02, - 0xe1, 0x6b, 0xa1, 0x04, 0x2e, 0x6e, 0x64, 0xcf, 0xaa, 0xe3, 0x33, 0x13, 0x49, 0xa1, 0x94, 0x06, - 0x5e, 0xa3, 0x91, 0x54, 0x3a, 0xf9, 0x9c, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, - 0x47, 0x72, 0x8c, 0x13, 0x1e, 0xcb, 0x31, 0x5c, 0x78, 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, 0x43, - 0x94, 0x51, 0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0xae, 0x3e, 0x52, 0xf4, 0x62, - 0x49, 0x1f, 0xd6, 0xc9, 0xf9, 0x45, 0xa9, 0x20, 0x46, 0x12, 0x1b, 0x38, 0xc6, 0x8d, 0x01, 0x01, - 0x00, 0x00, 0xff, 0xff, 0xf6, 0x4b, 0x02, 0xd8, 0x46, 0x02, 0x00, 0x00, + 0x5c, 0x3c, 0x41, 0xa9, 0xc5, 0x05, 0xf9, 0x79, 0xc5, 0xa9, 0x60, 0x5d, 0x7d, 0x8c, 0x5c, 0xc2, + 0x30, 0x01, 0x64, 0x7d, 0xd6, 0x5c, 0x1c, 0xc9, 0x19, 0xa9, 0xc9, 0xd9, 0xf1, 0x50, 0xdd, 0xdc, + 0x46, 0x0a, 0x7a, 0x48, 0x2e, 0x04, 0x39, 0x46, 0x0f, 0xa6, 0xcf, 0x19, 0xa4, 0x30, 0xa4, 0x22, + 0x88, 0x3d, 0x19, 0xc2, 0x10, 0xb2, 0xe2, 0xe2, 0x2c, 0xa9, 0x88, 0x2f, 0x4a, 0x2d, 0x2e, 0xcd, + 0x29, 0x91, 0x60, 0x02, 0xeb, 0x96, 0xc5, 0xd0, 0xed, 0x5a, 0x91, 0x9a, 0x1c, 0x52, 0x11, 0x04, + 0x56, 0x14, 0xc4, 0x51, 0x02, 0x65, 0x19, 0xed, 0x65, 0xe4, 0xe2, 0x81, 0x3b, 0xc4, 0x31, 0xc0, + 0x53, 0xc8, 0x9b, 0x8b, 0x05, 0xe4, 0x52, 0x21, 0x14, 0xfb, 0x61, 0x21, 0xa4, 0x87, 0x14, 0x02, + 0x52, 0x8a, 0x38, 0x54, 0x20, 0xbc, 0x2b, 0x94, 0xc0, 0xc5, 0x8d, 0xec, 0x4b, 0x75, 0x7c, 0x66, + 0x22, 0x29, 0x94, 0xd2, 0xc0, 0x6b, 0x34, 0x92, 0x4a, 0x27, 0x9f, 0x13, 0x8f, 0xe4, 0x18, 0x2f, + 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, + 0x6e, 0x3c, 0x96, 0x63, 0x88, 0x32, 0x4a, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, + 0xd5, 0x47, 0x8a, 0x57, 0x2c, 0x09, 0xc3, 0x3a, 0x39, 0xbf, 0x28, 0x15, 0xc4, 0x48, 0x62, 0x03, + 0x47, 0xb5, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0xdc, 0x93, 0xa5, 0x24, 0x3f, 0x02, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -441,9 +441,9 @@ func (m *ResponseBroadcastTx) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.DeliverTx != nil { + if m.TxResult != nil { { - size, err := m.DeliverTx.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.TxResult.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -520,8 +520,8 @@ func (m *ResponseBroadcastTx) Size() (n int) { l = m.CheckTx.Size() n += 1 + l + sovTypes(uint64(l)) } - if m.DeliverTx != nil { - l = m.DeliverTx.Size() + if m.TxResult != nil { + l = m.TxResult.Size() n += 1 + l + sovTypes(uint64(l)) } return n @@ -784,7 +784,7 @@ func (m *ResponseBroadcastTx) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DeliverTx", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field TxResult", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -811,10 +811,10 @@ func (m *ResponseBroadcastTx) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.DeliverTx == nil { - m.DeliverTx = &types.ResponseDeliverTx{} + if m.TxResult == nil { + m.TxResult = &types.ExecTxResult{} } - if err := m.DeliverTx.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.TxResult.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/proto/tendermint/rpc/grpc/types.proto b/proto/tendermint/rpc/grpc/types.proto index ee948a406..ce5612d6b 100644 --- a/proto/tendermint/rpc/grpc/types.proto +++ b/proto/tendermint/rpc/grpc/types.proto @@ -19,8 +19,8 @@ message RequestBroadcastTx { message ResponsePing {} message ResponseBroadcastTx { - tendermint.abci.ResponseCheckTx check_tx = 1; - tendermint.abci.ResponseDeliverTx deliver_tx = 2; + tendermint.abci.ResponseCheckTx check_tx = 1; + tendermint.abci.ExecTxResult tx_result = 2; } //---------------------------------------- diff --git a/proto/tendermint/state/types.pb.go b/proto/tendermint/state/types.pb.go index d5620344b..1ebdb1e28 100644 --- a/proto/tendermint/state/types.pb.go +++ b/proto/tendermint/state/types.pb.go @@ -30,27 +30,28 @@ var _ = time.Kitchen // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -// ABCIResponses retains the responses -// of the various ABCI calls during block processing. -// It is persisted to disk for each height before calling Commit. -type ABCIResponses struct { - DeliverTxs []*types.ResponseDeliverTx `protobuf:"bytes,1,rep,name=deliver_txs,json=deliverTxs,proto3" json:"deliver_txs,omitempty"` - EndBlock *types.ResponseEndBlock `protobuf:"bytes,2,opt,name=end_block,json=endBlock,proto3" json:"end_block,omitempty"` - BeginBlock *types.ResponseBeginBlock `protobuf:"bytes,3,opt,name=begin_block,json=beginBlock,proto3" json:"begin_block,omitempty"` +// LegacyABCIResponses retains the responses +// of the legacy ABCI calls during block processing. +// Note ReponseDeliverTx is renamed to ExecTxResult but they are semantically the same +// Kept for backwards compatibility for versions prior to v0.38 +type LegacyABCIResponses struct { + DeliverTxs []*types.ExecTxResult `protobuf:"bytes,1,rep,name=deliver_txs,json=deliverTxs,proto3" json:"deliver_txs,omitempty"` + EndBlock *ResponseEndBlock `protobuf:"bytes,2,opt,name=end_block,json=endBlock,proto3" json:"end_block,omitempty"` + BeginBlock *ResponseBeginBlock `protobuf:"bytes,3,opt,name=begin_block,json=beginBlock,proto3" json:"begin_block,omitempty"` } -func (m *ABCIResponses) Reset() { *m = ABCIResponses{} } -func (m *ABCIResponses) String() string { return proto.CompactTextString(m) } -func (*ABCIResponses) ProtoMessage() {} -func (*ABCIResponses) Descriptor() ([]byte, []int) { +func (m *LegacyABCIResponses) Reset() { *m = LegacyABCIResponses{} } +func (m *LegacyABCIResponses) String() string { return proto.CompactTextString(m) } +func (*LegacyABCIResponses) ProtoMessage() {} +func (*LegacyABCIResponses) Descriptor() ([]byte, []int) { return fileDescriptor_ccfacf933f22bf93, []int{0} } -func (m *ABCIResponses) XXX_Unmarshal(b []byte) error { +func (m *LegacyABCIResponses) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *ABCIResponses) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *LegacyABCIResponses) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_ABCIResponses.Marshal(b, m, deterministic) + return xxx_messageInfo_LegacyABCIResponses.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -60,39 +61,145 @@ func (m *ABCIResponses) XXX_Marshal(b []byte, deterministic bool) ([]byte, error return b[:n], nil } } -func (m *ABCIResponses) XXX_Merge(src proto.Message) { - xxx_messageInfo_ABCIResponses.Merge(m, src) +func (m *LegacyABCIResponses) XXX_Merge(src proto.Message) { + xxx_messageInfo_LegacyABCIResponses.Merge(m, src) } -func (m *ABCIResponses) XXX_Size() int { +func (m *LegacyABCIResponses) XXX_Size() int { return m.Size() } -func (m *ABCIResponses) XXX_DiscardUnknown() { - xxx_messageInfo_ABCIResponses.DiscardUnknown(m) +func (m *LegacyABCIResponses) XXX_DiscardUnknown() { + xxx_messageInfo_LegacyABCIResponses.DiscardUnknown(m) } -var xxx_messageInfo_ABCIResponses proto.InternalMessageInfo +var xxx_messageInfo_LegacyABCIResponses proto.InternalMessageInfo -func (m *ABCIResponses) GetDeliverTxs() []*types.ResponseDeliverTx { +func (m *LegacyABCIResponses) GetDeliverTxs() []*types.ExecTxResult { if m != nil { return m.DeliverTxs } return nil } -func (m *ABCIResponses) GetEndBlock() *types.ResponseEndBlock { +func (m *LegacyABCIResponses) GetEndBlock() *ResponseEndBlock { if m != nil { return m.EndBlock } return nil } -func (m *ABCIResponses) GetBeginBlock() *types.ResponseBeginBlock { +func (m *LegacyABCIResponses) GetBeginBlock() *ResponseBeginBlock { if m != nil { return m.BeginBlock } return nil } +// ResponseBeginBlock is kept for backwards compatibility for versions prior to v0.38 +type ResponseBeginBlock struct { + Events []types.Event `protobuf:"bytes,1,rep,name=events,proto3" json:"events,omitempty"` +} + +func (m *ResponseBeginBlock) Reset() { *m = ResponseBeginBlock{} } +func (m *ResponseBeginBlock) String() string { return proto.CompactTextString(m) } +func (*ResponseBeginBlock) ProtoMessage() {} +func (*ResponseBeginBlock) Descriptor() ([]byte, []int) { + return fileDescriptor_ccfacf933f22bf93, []int{1} +} +func (m *ResponseBeginBlock) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResponseBeginBlock) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ResponseBeginBlock.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ResponseBeginBlock) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResponseBeginBlock.Merge(m, src) +} +func (m *ResponseBeginBlock) XXX_Size() int { + return m.Size() +} +func (m *ResponseBeginBlock) XXX_DiscardUnknown() { + xxx_messageInfo_ResponseBeginBlock.DiscardUnknown(m) +} + +var xxx_messageInfo_ResponseBeginBlock proto.InternalMessageInfo + +func (m *ResponseBeginBlock) GetEvents() []types.Event { + if m != nil { + return m.Events + } + return nil +} + +// ResponseEndBlock is kept for backwards compatibility for versions prior to v0.38 +type ResponseEndBlock struct { + ValidatorUpdates []types.ValidatorUpdate `protobuf:"bytes,1,rep,name=validator_updates,json=validatorUpdates,proto3" json:"validator_updates"` + ConsensusParamUpdates *types1.ConsensusParams `protobuf:"bytes,2,opt,name=consensus_param_updates,json=consensusParamUpdates,proto3" json:"consensus_param_updates,omitempty"` + Events []types.Event `protobuf:"bytes,3,rep,name=events,proto3" json:"events,omitempty"` +} + +func (m *ResponseEndBlock) Reset() { *m = ResponseEndBlock{} } +func (m *ResponseEndBlock) String() string { return proto.CompactTextString(m) } +func (*ResponseEndBlock) ProtoMessage() {} +func (*ResponseEndBlock) Descriptor() ([]byte, []int) { + return fileDescriptor_ccfacf933f22bf93, []int{2} +} +func (m *ResponseEndBlock) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResponseEndBlock) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ResponseEndBlock.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ResponseEndBlock) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResponseEndBlock.Merge(m, src) +} +func (m *ResponseEndBlock) XXX_Size() int { + return m.Size() +} +func (m *ResponseEndBlock) XXX_DiscardUnknown() { + xxx_messageInfo_ResponseEndBlock.DiscardUnknown(m) +} + +var xxx_messageInfo_ResponseEndBlock proto.InternalMessageInfo + +func (m *ResponseEndBlock) GetValidatorUpdates() []types.ValidatorUpdate { + if m != nil { + return m.ValidatorUpdates + } + return nil +} + +func (m *ResponseEndBlock) GetConsensusParamUpdates() *types1.ConsensusParams { + if m != nil { + return m.ConsensusParamUpdates + } + return nil +} + +func (m *ResponseEndBlock) GetEvents() []types.Event { + if m != nil { + return m.Events + } + return nil +} + // ValidatorsInfo represents the latest validator set, or the last height it changed type ValidatorsInfo struct { ValidatorSet *types1.ValidatorSet `protobuf:"bytes,1,opt,name=validator_set,json=validatorSet,proto3" json:"validator_set,omitempty"` @@ -103,7 +210,7 @@ func (m *ValidatorsInfo) Reset() { *m = ValidatorsInfo{} } func (m *ValidatorsInfo) String() string { return proto.CompactTextString(m) } func (*ValidatorsInfo) ProtoMessage() {} func (*ValidatorsInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_ccfacf933f22bf93, []int{1} + return fileDescriptor_ccfacf933f22bf93, []int{3} } func (m *ValidatorsInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -156,7 +263,7 @@ func (m *ConsensusParamsInfo) Reset() { *m = ConsensusParamsInfo{} } func (m *ConsensusParamsInfo) String() string { return proto.CompactTextString(m) } func (*ConsensusParamsInfo) ProtoMessage() {} func (*ConsensusParamsInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_ccfacf933f22bf93, []int{2} + return fileDescriptor_ccfacf933f22bf93, []int{4} } func (m *ConsensusParamsInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -200,15 +307,16 @@ func (m *ConsensusParamsInfo) GetLastHeightChanged() int64 { } type ABCIResponsesInfo struct { - AbciResponses *ABCIResponses `protobuf:"bytes,1,opt,name=abci_responses,json=abciResponses,proto3" json:"abci_responses,omitempty"` - Height int64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"` + LegacyAbciResponses *LegacyABCIResponses `protobuf:"bytes,1,opt,name=legacy_abci_responses,json=legacyAbciResponses,proto3" json:"legacy_abci_responses,omitempty"` + Height int64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"` + ResponseFinalizeBlock *types.ResponseFinalizeBlock `protobuf:"bytes,3,opt,name=response_finalize_block,json=responseFinalizeBlock,proto3" json:"response_finalize_block,omitempty"` } func (m *ABCIResponsesInfo) Reset() { *m = ABCIResponsesInfo{} } func (m *ABCIResponsesInfo) String() string { return proto.CompactTextString(m) } func (*ABCIResponsesInfo) ProtoMessage() {} func (*ABCIResponsesInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_ccfacf933f22bf93, []int{3} + return fileDescriptor_ccfacf933f22bf93, []int{5} } func (m *ABCIResponsesInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -237,9 +345,9 @@ func (m *ABCIResponsesInfo) XXX_DiscardUnknown() { var xxx_messageInfo_ABCIResponsesInfo proto.InternalMessageInfo -func (m *ABCIResponsesInfo) GetAbciResponses() *ABCIResponses { +func (m *ABCIResponsesInfo) GetLegacyAbciResponses() *LegacyABCIResponses { if m != nil { - return m.AbciResponses + return m.LegacyAbciResponses } return nil } @@ -251,6 +359,13 @@ func (m *ABCIResponsesInfo) GetHeight() int64 { return 0 } +func (m *ABCIResponsesInfo) GetResponseFinalizeBlock() *types.ResponseFinalizeBlock { + if m != nil { + return m.ResponseFinalizeBlock + } + return nil +} + type Version struct { Consensus version.Consensus `protobuf:"bytes,1,opt,name=consensus,proto3" json:"consensus"` Software string `protobuf:"bytes,2,opt,name=software,proto3" json:"software,omitempty"` @@ -260,7 +375,7 @@ func (m *Version) Reset() { *m = Version{} } func (m *Version) String() string { return proto.CompactTextString(m) } func (*Version) ProtoMessage() {} func (*Version) Descriptor() ([]byte, []int) { - return fileDescriptor_ccfacf933f22bf93, []int{4} + return fileDescriptor_ccfacf933f22bf93, []int{6} } func (m *Version) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -336,7 +451,7 @@ func (m *State) Reset() { *m = State{} } func (m *State) String() string { return proto.CompactTextString(m) } func (*State) ProtoMessage() {} func (*State) Descriptor() ([]byte, []int) { - return fileDescriptor_ccfacf933f22bf93, []int{5} + return fileDescriptor_ccfacf933f22bf93, []int{7} } func (m *State) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -464,7 +579,9 @@ func (m *State) GetAppHash() []byte { } func init() { - proto.RegisterType((*ABCIResponses)(nil), "tendermint.state.ABCIResponses") + proto.RegisterType((*LegacyABCIResponses)(nil), "tendermint.state.LegacyABCIResponses") + proto.RegisterType((*ResponseBeginBlock)(nil), "tendermint.state.ResponseBeginBlock") + proto.RegisterType((*ResponseEndBlock)(nil), "tendermint.state.ResponseEndBlock") proto.RegisterType((*ValidatorsInfo)(nil), "tendermint.state.ValidatorsInfo") proto.RegisterType((*ConsensusParamsInfo)(nil), "tendermint.state.ConsensusParamsInfo") proto.RegisterType((*ABCIResponsesInfo)(nil), "tendermint.state.ABCIResponsesInfo") @@ -475,61 +592,71 @@ func init() { func init() { proto.RegisterFile("tendermint/state/types.proto", fileDescriptor_ccfacf933f22bf93) } var fileDescriptor_ccfacf933f22bf93 = []byte{ - // 805 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0xcd, 0x8e, 0xe3, 0x44, - 0x10, 0x8e, 0xc9, 0x6e, 0x7e, 0xca, 0x93, 0x64, 0xb7, 0x07, 0x21, 0x6f, 0x96, 0x75, 0xb2, 0xe1, - 0x47, 0x23, 0x0e, 0x8e, 0xb4, 0x1c, 0x10, 0x97, 0x95, 0xd6, 0x09, 0xb0, 0x91, 0x56, 0x08, 0x3c, - 0xa3, 0x39, 0x70, 0xb1, 0x3a, 0x71, 0x8f, 0x6d, 0x91, 0xd8, 0x96, 0xbb, 0x13, 0x86, 0x07, 0xe0, - 0x3e, 0x57, 0xde, 0x68, 0x8e, 0x73, 0x44, 0x1c, 0x06, 0xc8, 0xbc, 0x08, 0xea, 0x1f, 0xdb, 0x9d, - 0x84, 0x91, 0x06, 0xed, 0xad, 0x5d, 0xf5, 0xd5, 0x57, 0x5f, 0x55, 0x57, 0xb5, 0xe1, 0x63, 0x46, - 0x92, 0x80, 0xe4, 0xab, 0x38, 0x61, 0x63, 0xca, 0x30, 0x23, 0x63, 0xf6, 0x6b, 0x46, 0xa8, 0x93, - 0xe5, 0x29, 0x4b, 0xd1, 0x93, 0xca, 0xeb, 0x08, 0x6f, 0xff, 0xc3, 0x30, 0x0d, 0x53, 0xe1, 0x1c, - 0xf3, 0x93, 0xc4, 0xf5, 0x9f, 0x6b, 0x2c, 0x78, 0xbe, 0x88, 0x75, 0x92, 0xbe, 0x9e, 0x42, 0xd8, - 0x77, 0xbc, 0xc3, 0x03, 0xef, 0x06, 0x2f, 0xe3, 0x00, 0xb3, 0x34, 0x57, 0x88, 0x17, 0x07, 0x88, - 0x0c, 0xe7, 0x78, 0x55, 0x10, 0xd8, 0x9a, 0x7b, 0x43, 0x72, 0x1a, 0xa7, 0xc9, 0x4e, 0x82, 0x41, - 0x98, 0xa6, 0xe1, 0x92, 0x8c, 0xc5, 0xd7, 0x7c, 0x7d, 0x31, 0x66, 0xf1, 0x8a, 0x50, 0x86, 0x57, - 0x99, 0x04, 0x8c, 0xfe, 0x34, 0xa0, 0xf3, 0xc6, 0x9d, 0xcc, 0x3c, 0x42, 0xb3, 0x34, 0xa1, 0x84, - 0xa2, 0x09, 0x98, 0x01, 0x59, 0xc6, 0x1b, 0x92, 0xfb, 0xec, 0x92, 0x5a, 0xc6, 0xb0, 0x7e, 0x62, - 0xbe, 0x1a, 0x39, 0x5a, 0x33, 0x78, 0x91, 0x4e, 0x11, 0x30, 0x95, 0xd8, 0xb3, 0x4b, 0x0f, 0x82, - 0xe2, 0x48, 0xd1, 0x6b, 0x68, 0x93, 0x24, 0xf0, 0xe7, 0xcb, 0x74, 0xf1, 0xb3, 0xf5, 0xc1, 0xd0, - 0x38, 0x31, 0x5f, 0xbd, 0xbc, 0x97, 0xe2, 0x9b, 0x24, 0x70, 0x39, 0xd0, 0x6b, 0x11, 0x75, 0x42, - 0x53, 0x30, 0xe7, 0x24, 0x8c, 0x13, 0xc5, 0x50, 0x17, 0x0c, 0x9f, 0xdc, 0xcb, 0xe0, 0x72, 0xac, - 0xe4, 0x80, 0x79, 0x79, 0x1e, 0xfd, 0x66, 0x40, 0xf7, 0xbc, 0x68, 0x28, 0x9d, 0x25, 0x17, 0x29, - 0x9a, 0x40, 0xa7, 0x6c, 0xb1, 0x4f, 0x09, 0xb3, 0x0c, 0x41, 0x6d, 0xeb, 0xd4, 0xb2, 0x81, 0x65, - 0xe0, 0x29, 0x61, 0xde, 0xd1, 0x46, 0xfb, 0x42, 0x0e, 0x1c, 0x2f, 0x31, 0x65, 0x7e, 0x44, 0xe2, - 0x30, 0x62, 0xfe, 0x22, 0xc2, 0x49, 0x48, 0x02, 0x51, 0x67, 0xdd, 0x7b, 0xca, 0x5d, 0x6f, 0x85, - 0x67, 0x22, 0x1d, 0xa3, 0xdf, 0x0d, 0x38, 0x9e, 0x70, 0x9d, 0x09, 0x5d, 0xd3, 0x1f, 0xc4, 0xfd, - 0x09, 0x31, 0x1e, 0x3c, 0x59, 0x14, 0x66, 0x5f, 0xde, 0xab, 0xd2, 0xf3, 0xf2, 0x50, 0xcf, 0x1e, - 0x81, 0xfb, 0xe8, 0xfa, 0x76, 0x50, 0xf3, 0x7a, 0x8b, 0x5d, 0xf3, 0xff, 0xd6, 0x46, 0xe1, 0xe9, - 0xce, 0xfd, 0x0b, 0x61, 0xdf, 0x42, 0x97, 0xf7, 0xd7, 0xcf, 0x0b, 0xab, 0x92, 0x35, 0x70, 0xf6, - 0x77, 0xc2, 0xd9, 0x09, 0xf6, 0x3a, 0x3c, 0xac, 0x9a, 0xa5, 0x8f, 0xa0, 0x21, 0x75, 0xa8, 0xfc, - 0xea, 0x6b, 0x14, 0x41, 0xf3, 0x5c, 0x4e, 0x2b, 0x7a, 0x03, 0xed, 0xb2, 0x04, 0x95, 0xe5, 0x85, - 0x9e, 0x45, 0x4d, 0x75, 0x55, 0xbe, 0x2a, 0xbc, 0x8a, 0x42, 0x7d, 0x68, 0xd1, 0xf4, 0x82, 0xfd, - 0x82, 0x73, 0x22, 0xf2, 0xb4, 0xbd, 0xf2, 0x7b, 0xf4, 0x4f, 0x03, 0x1e, 0x9f, 0x72, 0xa1, 0xe8, - 0x6b, 0x68, 0x2a, 0x2e, 0x95, 0xe6, 0xd9, 0x61, 0x31, 0x4a, 0x94, 0x4a, 0x51, 0xe0, 0xd1, 0xe7, - 0xd0, 0x5a, 0x44, 0x38, 0x4e, 0xfc, 0x58, 0x36, 0xb2, 0xed, 0x9a, 0xdb, 0xdb, 0x41, 0x73, 0xc2, - 0x6d, 0xb3, 0xa9, 0xd7, 0x14, 0xce, 0x59, 0x80, 0x3e, 0x83, 0x6e, 0x9c, 0xc4, 0x2c, 0xc6, 0x4b, - 0xd5, 0x7e, 0xab, 0x2b, 0xca, 0xee, 0x28, 0xab, 0xec, 0x3c, 0xfa, 0x02, 0xc4, 0x3d, 0xc8, 0xd9, - 0x2e, 0x90, 0x75, 0x81, 0xec, 0x71, 0x87, 0x18, 0x5e, 0x85, 0xf5, 0xa0, 0xa3, 0x61, 0xe3, 0xc0, - 0x7a, 0x74, 0xa8, 0x5d, 0xce, 0x87, 0x88, 0x9a, 0x4d, 0xdd, 0x63, 0xae, 0x7d, 0x7b, 0x3b, 0x30, - 0xdf, 0x15, 0x54, 0xb3, 0xa9, 0x67, 0x96, 0xbc, 0xb3, 0x00, 0xbd, 0x83, 0x9e, 0xc6, 0xc9, 0x5f, - 0x04, 0xeb, 0xb1, 0x60, 0xed, 0x3b, 0xf2, 0xb9, 0x70, 0x8a, 0xe7, 0xc2, 0x39, 0x2b, 0x9e, 0x0b, - 0xb7, 0xc5, 0x69, 0xaf, 0xfe, 0x1a, 0x18, 0x5e, 0xa7, 0xe4, 0xe2, 0x5e, 0xf4, 0x1d, 0xf4, 0x12, - 0x72, 0xc9, 0xfc, 0x72, 0x43, 0xa8, 0xd5, 0x78, 0xd0, 0x4e, 0x75, 0x79, 0x58, 0xb5, 0x9e, 0xe8, - 0x35, 0x80, 0xc6, 0xd1, 0x7c, 0x10, 0x87, 0x16, 0xc1, 0x85, 0x88, 0xb2, 0x34, 0x92, 0xd6, 0xc3, - 0x84, 0xf0, 0x30, 0x4d, 0xc8, 0x04, 0x6c, 0x7d, 0x85, 0x2a, 0xbe, 0x72, 0x9b, 0xda, 0xe2, 0xb2, - 0x9e, 0x57, 0xdb, 0x54, 0x45, 0xab, 0xbd, 0xfa, 0xcf, 0xdd, 0x86, 0xf7, 0xdc, 0xed, 0xef, 0xe1, - 0xd3, 0x9d, 0xdd, 0xde, 0xe3, 0x2f, 0xe5, 0x99, 0x42, 0xde, 0x50, 0x5b, 0xf6, 0x5d, 0xa2, 0x42, - 0x63, 0x31, 0x88, 0x39, 0xa1, 0xeb, 0x25, 0xa3, 0x7e, 0x84, 0x69, 0x64, 0x1d, 0x0d, 0x8d, 0x93, - 0x23, 0x39, 0x88, 0x9e, 0xb4, 0xbf, 0xc5, 0x34, 0x42, 0xcf, 0xa0, 0x85, 0xb3, 0x4c, 0x42, 0x3a, - 0x02, 0xd2, 0xc4, 0x59, 0xc6, 0x5d, 0xee, 0x8f, 0xd7, 0x5b, 0xdb, 0xb8, 0xd9, 0xda, 0xc6, 0xdf, - 0x5b, 0xdb, 0xb8, 0xba, 0xb3, 0x6b, 0x37, 0x77, 0x76, 0xed, 0x8f, 0x3b, 0xbb, 0xf6, 0xd3, 0x57, - 0x61, 0xcc, 0xa2, 0xf5, 0xdc, 0x59, 0xa4, 0xab, 0xb1, 0xfe, 0x23, 0xab, 0x8e, 0xf2, 0x6f, 0xba, - 0xff, 0x1f, 0x9e, 0x37, 0x84, 0xfd, 0xcb, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x2b, 0x1a, 0xb9, - 0x2e, 0xa2, 0x07, 0x00, 0x00, + // 961 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x4b, 0x6f, 0xdb, 0x46, + 0x17, 0x35, 0xa3, 0x44, 0x8f, 0x2b, 0xcb, 0x96, 0x47, 0x9f, 0x13, 0x45, 0xf9, 0x22, 0xa9, 0x42, + 0x12, 0x18, 0x45, 0x41, 0x01, 0xe9, 0xa2, 0xe8, 0x26, 0x85, 0x25, 0xbb, 0xb5, 0x00, 0xa3, 0x68, + 0x69, 0x37, 0x40, 0xba, 0x08, 0x31, 0x22, 0xc7, 0xd2, 0xa0, 0x12, 0x49, 0x70, 0x46, 0xaa, 0xdc, + 0x7d, 0x77, 0x5d, 0x64, 0xdb, 0x7f, 0x94, 0x65, 0x96, 0xdd, 0xd4, 0x6d, 0x65, 0xa0, 0x8b, 0xfe, + 0x8a, 0x62, 0x1e, 0x7c, 0x89, 0x2e, 0xea, 0x22, 0x3b, 0x72, 0xee, 0xb9, 0xe7, 0x9e, 0x7b, 0x66, + 0xee, 0x90, 0xf0, 0x7f, 0x4e, 0x3c, 0x97, 0x84, 0x73, 0xea, 0xf1, 0x3e, 0xe3, 0x98, 0x93, 0x3e, + 0xbf, 0x0c, 0x08, 0x33, 0x83, 0xd0, 0xe7, 0x3e, 0xaa, 0x27, 0x51, 0x53, 0x46, 0x5b, 0xff, 0x9b, + 0xf8, 0x13, 0x5f, 0x06, 0xfb, 0xe2, 0x49, 0xe1, 0x5a, 0x8f, 0x52, 0x2c, 0x78, 0xec, 0xd0, 0x34, + 0x49, 0x2b, 0x5d, 0x42, 0xae, 0x67, 0xa2, 0xdd, 0x5c, 0x74, 0x89, 0x67, 0xd4, 0xc5, 0xdc, 0x0f, + 0x35, 0xe2, 0x71, 0x0e, 0x11, 0xe0, 0x10, 0xcf, 0x23, 0x82, 0x76, 0x2a, 0xbc, 0x24, 0x21, 0xa3, + 0xbe, 0x97, 0x29, 0xd0, 0x99, 0xf8, 0xfe, 0x64, 0x46, 0xfa, 0xf2, 0x6d, 0xbc, 0xb8, 0xe8, 0x73, + 0x3a, 0x27, 0x8c, 0xe3, 0x79, 0xa0, 0x00, 0xbd, 0x5f, 0x0d, 0x68, 0x9c, 0x92, 0x09, 0x76, 0x2e, + 0x0f, 0x07, 0xc3, 0x91, 0x45, 0x58, 0xe0, 0x7b, 0x8c, 0x30, 0xf4, 0x02, 0xaa, 0x2e, 0x99, 0xd1, + 0x25, 0x09, 0x6d, 0xbe, 0x62, 0x4d, 0xa3, 0x5b, 0x38, 0xa8, 0x3e, 0x7f, 0x6c, 0xa6, 0x2c, 0x11, + 0xad, 0x9a, 0xc7, 0x2b, 0xe2, 0x9c, 0xaf, 0x2c, 0xc2, 0x16, 0x33, 0x6e, 0x81, 0xce, 0x38, 0x5f, + 0x31, 0xf4, 0x19, 0x54, 0x88, 0xe7, 0xda, 0xe3, 0x99, 0xef, 0x7c, 0xd7, 0xbc, 0xd3, 0x35, 0x0e, + 0xaa, 0xcf, 0x7b, 0xe6, 0xa6, 0xa1, 0x66, 0x54, 0xef, 0xd8, 0x73, 0x07, 0x02, 0x69, 0x95, 0x89, + 0x7e, 0x42, 0xc7, 0x50, 0x1d, 0x93, 0x09, 0xf5, 0x34, 0x45, 0x41, 0x52, 0x3c, 0xf9, 0x67, 0x8a, + 0x81, 0x00, 0x2b, 0x12, 0x18, 0xc7, 0xcf, 0xbd, 0xd7, 0x80, 0xf2, 0x08, 0x74, 0x02, 0x45, 0xb2, + 0x24, 0x1e, 0x8f, 0x1a, 0xbb, 0x9f, 0x6f, 0x4c, 0x84, 0x07, 0xcd, 0xb7, 0x57, 0x9d, 0xad, 0xbf, + 0xae, 0x3a, 0x75, 0x85, 0xfe, 0xc8, 0x9f, 0x53, 0x4e, 0xe6, 0x01, 0xbf, 0xb4, 0x74, 0x7e, 0xef, + 0xa7, 0x3b, 0x50, 0xdf, 0xec, 0x02, 0x9d, 0xc1, 0x5e, 0xbc, 0x8f, 0xf6, 0x22, 0x70, 0x31, 0x27, + 0x51, 0xa5, 0x6e, 0xae, 0xd2, 0xcb, 0x08, 0xf9, 0x8d, 0x04, 0x0e, 0xee, 0x8a, 0x9a, 0x56, 0x7d, + 0x99, 0x5d, 0x66, 0xe8, 0x15, 0x3c, 0x70, 0x44, 0x15, 0x8f, 0x2d, 0x98, 0x2d, 0x0f, 0x41, 0x4c, + 0xad, 0xfc, 0xfd, 0x20, 0x4d, 0xad, 0x0e, 0xc1, 0x30, 0x4a, 0xf8, 0x4a, 0x1e, 0x1a, 0x6b, 0xdf, + 0xc9, 0x2c, 0x44, 0xd4, 0x89, 0x1d, 0x85, 0xf7, 0xb4, 0xe3, 0x47, 0x03, 0x76, 0xe2, 0x86, 0xd8, + 0xc8, 0xbb, 0xf0, 0xd1, 0x10, 0x6a, 0x89, 0x19, 0x8c, 0xf0, 0xa6, 0x21, 0xd5, 0xb6, 0xf3, 0x6a, + 0xe3, 0xc4, 0x33, 0xc2, 0xad, 0xed, 0x65, 0xea, 0x0d, 0x99, 0xd0, 0x98, 0x61, 0xc6, 0xed, 0x29, + 0xa1, 0x93, 0x29, 0xb7, 0x9d, 0x29, 0xf6, 0x26, 0xc4, 0x95, 0x8d, 0x17, 0xac, 0x3d, 0x11, 0x3a, + 0x91, 0x91, 0xa1, 0x0a, 0xf4, 0x7e, 0x36, 0xa0, 0xb1, 0xd1, 0xbc, 0x14, 0x63, 0x41, 0x7d, 0xc3, + 0x44, 0xa6, 0xf5, 0xfc, 0xbb, 0x7b, 0x7a, 0x67, 0x76, 0xb3, 0x1e, 0xb2, 0xff, 0xac, 0xed, 0x4f, + 0x03, 0xf6, 0x32, 0xc3, 0x26, 0x95, 0xbd, 0x82, 0xfd, 0x99, 0x9c, 0x43, 0x5b, 0x18, 0x6e, 0x87, + 0x51, 0x50, 0xcb, 0x7b, 0x9a, 0x3f, 0xf9, 0x37, 0x8c, 0xad, 0xd5, 0x50, 0x1c, 0x87, 0x63, 0x87, + 0x26, 0xb3, 0x7c, 0x1f, 0x8a, 0x4a, 0x9b, 0xd6, 0xa4, 0xdf, 0xd0, 0x6b, 0x78, 0x10, 0x95, 0xb1, + 0x2f, 0xa8, 0x87, 0x67, 0xf4, 0x07, 0x92, 0x19, 0xb7, 0x67, 0xb9, 0x73, 0x10, 0x91, 0x7e, 0xae, + 0xe1, 0x6a, 0xe0, 0xf6, 0xc3, 0x9b, 0x96, 0x7b, 0x53, 0x28, 0xbd, 0x54, 0x77, 0x12, 0x3a, 0x84, + 0x4a, 0x6c, 0x9b, 0xee, 0x28, 0x73, 0x99, 0xe8, 0xbb, 0x2b, 0xb1, 0x5c, 0x9b, 0x9d, 0x64, 0xa1, + 0x16, 0x94, 0x99, 0x7f, 0xc1, 0xbf, 0xc7, 0x21, 0x91, 0x7d, 0x54, 0xac, 0xf8, 0xbd, 0xf7, 0x47, + 0x11, 0xee, 0x9d, 0x09, 0x53, 0xd0, 0xa7, 0x50, 0xd2, 0x5c, 0xba, 0xcc, 0xc3, 0xbc, 0x71, 0x5a, + 0x94, 0x2e, 0x11, 0xe1, 0xd1, 0x33, 0x28, 0x3b, 0x53, 0x4c, 0x3d, 0x9b, 0xaa, 0xcd, 0xab, 0x0c, + 0xaa, 0xeb, 0xab, 0x4e, 0x69, 0x28, 0xd6, 0x46, 0x47, 0x56, 0x49, 0x06, 0x47, 0x2e, 0x7a, 0x0a, + 0x3b, 0xd4, 0xa3, 0x9c, 0xe2, 0x99, 0xde, 0xf2, 0xe6, 0x8e, 0xb4, 0xb5, 0xa6, 0x57, 0xd5, 0x6e, + 0xa3, 0x0f, 0x41, 0xee, 0xbd, 0x32, 0x34, 0x42, 0x16, 0x24, 0x72, 0x57, 0x04, 0xa4, 0x47, 0x1a, + 0x6b, 0x41, 0x2d, 0x85, 0xa5, 0x6e, 0xf3, 0x6e, 0x5e, 0xbb, 0x3a, 0x93, 0x32, 0x6b, 0x74, 0x34, + 0x68, 0x08, 0xed, 0xeb, 0xab, 0x4e, 0xf5, 0x34, 0xa2, 0x1a, 0x1d, 0x59, 0xd5, 0x98, 0x77, 0xe4, + 0xa2, 0x53, 0xd8, 0x4d, 0x71, 0x8a, 0x7b, 0xbf, 0x79, 0x4f, 0xb2, 0xb6, 0x4c, 0xf5, 0x51, 0x30, + 0xa3, 0x8f, 0x82, 0x79, 0x1e, 0x7d, 0x14, 0x06, 0x65, 0x41, 0xfb, 0xe6, 0xb7, 0x8e, 0x61, 0xd5, + 0x62, 0x2e, 0x11, 0x45, 0x5f, 0xc0, 0xae, 0x47, 0x56, 0xdc, 0x8e, 0xa7, 0x92, 0x35, 0x8b, 0xb7, + 0x9a, 0xe3, 0x1d, 0x91, 0x96, 0x5c, 0x09, 0xe8, 0x05, 0x40, 0x8a, 0xa3, 0x74, 0x2b, 0x8e, 0x54, + 0x86, 0x10, 0x22, 0xdb, 0x4a, 0x91, 0x94, 0x6f, 0x27, 0x44, 0xa4, 0xa5, 0x84, 0x0c, 0xa1, 0x9d, + 0x1e, 0xdb, 0x84, 0x2f, 0x9e, 0xe0, 0x8a, 0xdc, 0xac, 0x47, 0xc9, 0x04, 0x27, 0xd9, 0x7a, 0x96, + 0x6f, 0xbc, 0x4f, 0xe0, 0x3d, 0xef, 0x93, 0x2f, 0xe1, 0x49, 0xe6, 0x3e, 0xd9, 0xe0, 0x8f, 0xe5, + 0x55, 0xa5, 0xbc, 0x6e, 0xea, 0x82, 0xc9, 0x12, 0x45, 0x1a, 0xa3, 0x83, 0x18, 0xca, 0xaf, 0x34, + 0xb3, 0xa7, 0x98, 0x4d, 0x9b, 0xdb, 0x5d, 0xe3, 0x60, 0x5b, 0x1d, 0x44, 0xf5, 0xf5, 0x66, 0x27, + 0x98, 0x4d, 0xd1, 0x43, 0x28, 0xe3, 0x20, 0x50, 0x90, 0x9a, 0x84, 0x94, 0x70, 0x10, 0x88, 0xd0, + 0xe0, 0xeb, 0xb7, 0xeb, 0xb6, 0xf1, 0x6e, 0xdd, 0x36, 0x7e, 0x5f, 0xb7, 0x8d, 0x37, 0xd7, 0xed, + 0xad, 0x77, 0xd7, 0xed, 0xad, 0x5f, 0xae, 0xdb, 0x5b, 0xdf, 0x7e, 0x32, 0xa1, 0x7c, 0xba, 0x18, + 0x9b, 0x8e, 0x3f, 0xef, 0xa7, 0x7f, 0x57, 0x92, 0x47, 0xf5, 0xcf, 0xb4, 0xf9, 0xb7, 0x35, 0x2e, + 0xca, 0xf5, 0x8f, 0xff, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xc3, 0x86, 0xc8, 0x78, 0x88, 0x09, 0x00, + 0x00, } -func (m *ABCIResponses) Marshal() (dAtA []byte, err error) { +func (m *LegacyABCIResponses) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -539,12 +666,12 @@ func (m *ABCIResponses) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ABCIResponses) MarshalTo(dAtA []byte) (int, error) { +func (m *LegacyABCIResponses) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ABCIResponses) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *LegacyABCIResponses) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -590,6 +717,106 @@ func (m *ABCIResponses) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ResponseBeginBlock) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResponseBeginBlock) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResponseBeginBlock) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Events) > 0 { + for iNdEx := len(m.Events) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Events[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *ResponseEndBlock) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResponseEndBlock) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResponseEndBlock) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Events) > 0 { + for iNdEx := len(m.Events) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Events[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if m.ConsensusParamUpdates != nil { + { + size, err := m.ConsensusParamUpdates.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.ValidatorUpdates) > 0 { + for iNdEx := len(m.ValidatorUpdates) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ValidatorUpdates[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func (m *ValidatorsInfo) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -688,14 +915,26 @@ func (m *ABCIResponsesInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.ResponseFinalizeBlock != nil { + { + size, err := m.ResponseFinalizeBlock.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } if m.Height != 0 { i = encodeVarintTypes(dAtA, i, uint64(m.Height)) i-- dAtA[i] = 0x10 } - if m.AbciResponses != nil { + if m.LegacyAbciResponses != nil { { - size, err := m.AbciResponses.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.LegacyAbciResponses.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -843,12 +1082,12 @@ func (m *State) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x32 } - n11, err11 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.LastBlockTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.LastBlockTime):]) - if err11 != nil { - return 0, err11 + n13, err13 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.LastBlockTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.LastBlockTime):]) + if err13 != nil { + return 0, err13 } - i -= n11 - i = encodeVarintTypes(dAtA, i, uint64(n11)) + i -= n13 + i = encodeVarintTypes(dAtA, i, uint64(n13)) i-- dAtA[i] = 0x2a { @@ -897,7 +1136,7 @@ func encodeVarintTypes(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } -func (m *ABCIResponses) Size() (n int) { +func (m *LegacyABCIResponses) Size() (n int) { if m == nil { return 0 } @@ -920,6 +1159,46 @@ func (m *ABCIResponses) Size() (n int) { return n } +func (m *ResponseBeginBlock) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Events) > 0 { + for _, e := range m.Events { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + return n +} + +func (m *ResponseEndBlock) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ValidatorUpdates) > 0 { + for _, e := range m.ValidatorUpdates { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + if m.ConsensusParamUpdates != nil { + l = m.ConsensusParamUpdates.Size() + n += 1 + l + sovTypes(uint64(l)) + } + if len(m.Events) > 0 { + for _, e := range m.Events { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + return n +} + func (m *ValidatorsInfo) Size() (n int) { if m == nil { return 0 @@ -956,13 +1235,17 @@ func (m *ABCIResponsesInfo) Size() (n int) { } var l int _ = l - if m.AbciResponses != nil { - l = m.AbciResponses.Size() + if m.LegacyAbciResponses != nil { + l = m.LegacyAbciResponses.Size() n += 1 + l + sovTypes(uint64(l)) } if m.Height != 0 { n += 1 + sovTypes(uint64(m.Height)) } + if m.ResponseFinalizeBlock != nil { + l = m.ResponseFinalizeBlock.Size() + n += 1 + l + sovTypes(uint64(l)) + } return n } @@ -1040,7 +1323,7 @@ func sovTypes(x uint64) (n int) { func sozTypes(x uint64) (n int) { return sovTypes(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *ABCIResponses) Unmarshal(dAtA []byte) error { +func (m *LegacyABCIResponses) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1063,10 +1346,10 @@ func (m *ABCIResponses) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ABCIResponses: wiretype end group for non-group") + return fmt.Errorf("proto: LegacyABCIResponses: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ABCIResponses: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: LegacyABCIResponses: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -1098,7 +1381,7 @@ func (m *ABCIResponses) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.DeliverTxs = append(m.DeliverTxs, &types.ResponseDeliverTx{}) + m.DeliverTxs = append(m.DeliverTxs, &types.ExecTxResult{}) if err := m.DeliverTxs[len(m.DeliverTxs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -1133,7 +1416,7 @@ func (m *ABCIResponses) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.EndBlock == nil { - m.EndBlock = &types.ResponseEndBlock{} + m.EndBlock = &ResponseEndBlock{} } if err := m.EndBlock.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -1169,7 +1452,7 @@ func (m *ABCIResponses) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.BeginBlock == nil { - m.BeginBlock = &types.ResponseBeginBlock{} + m.BeginBlock = &ResponseBeginBlock{} } if err := m.BeginBlock.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -1196,6 +1479,244 @@ func (m *ABCIResponses) Unmarshal(dAtA []byte) error { } return nil } +func (m *ResponseBeginBlock) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResponseBeginBlock: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResponseBeginBlock: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Events", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Events = append(m.Events, types.Event{}) + if err := m.Events[len(m.Events)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResponseEndBlock) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResponseEndBlock: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResponseEndBlock: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorUpdates", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ValidatorUpdates = append(m.ValidatorUpdates, types.ValidatorUpdate{}) + if err := m.ValidatorUpdates[len(m.ValidatorUpdates)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConsensusParamUpdates", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ConsensusParamUpdates == nil { + m.ConsensusParamUpdates = &types1.ConsensusParams{} + } + if err := m.ConsensusParamUpdates.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Events", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Events = append(m.Events, types.Event{}) + if err := m.Events[len(m.Events)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *ValidatorsInfo) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -1434,7 +1955,7 @@ func (m *ABCIResponsesInfo) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AbciResponses", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field LegacyAbciResponses", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -1461,10 +1982,10 @@ func (m *ABCIResponsesInfo) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.AbciResponses == nil { - m.AbciResponses = &ABCIResponses{} + if m.LegacyAbciResponses == nil { + m.LegacyAbciResponses = &LegacyABCIResponses{} } - if err := m.AbciResponses.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.LegacyAbciResponses.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1487,6 +2008,42 @@ func (m *ABCIResponsesInfo) Unmarshal(dAtA []byte) error { break } } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResponseFinalizeBlock", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ResponseFinalizeBlock == nil { + m.ResponseFinalizeBlock = &types.ResponseFinalizeBlock{} + } + if err := m.ResponseFinalizeBlock.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) diff --git a/proto/tendermint/state/types.proto b/proto/tendermint/state/types.proto index f3fdc0ef3..552328c38 100644 --- a/proto/tendermint/state/types.proto +++ b/proto/tendermint/state/types.proto @@ -11,13 +11,28 @@ import "tendermint/types/params.proto"; import "tendermint/version/types.proto"; import "google/protobuf/timestamp.proto"; -// ABCIResponses retains the responses -// of the various ABCI calls during block processing. -// It is persisted to disk for each height before calling Commit. -message ABCIResponses { - repeated tendermint.abci.ResponseDeliverTx deliver_txs = 1; - tendermint.abci.ResponseEndBlock end_block = 2; - tendermint.abci.ResponseBeginBlock begin_block = 3; +// LegacyABCIResponses retains the responses +// of the legacy ABCI calls during block processing. +// Note ReponseDeliverTx is renamed to ExecTxResult but they are semantically the same +// Kept for backwards compatibility for versions prior to v0.38 +message LegacyABCIResponses { + repeated tendermint.abci.ExecTxResult deliver_txs = 1; + ResponseEndBlock end_block = 2; + ResponseBeginBlock begin_block = 3; +} + +// ResponseBeginBlock is kept for backwards compatibility for versions prior to v0.38 +message ResponseBeginBlock { + repeated tendermint.abci.Event events = 1 + [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; +} + +// ResponseEndBlock is kept for backwards compatibility for versions prior to v0.38 +message ResponseEndBlock { + repeated tendermint.abci.ValidatorUpdate validator_updates = 1 [(gogoproto.nullable) = false]; + tendermint.types.ConsensusParams consensus_param_updates = 2; + repeated tendermint.abci.Event events = 3 + [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; } // ValidatorsInfo represents the latest validator set, or the last height it changed @@ -33,8 +48,9 @@ message ConsensusParamsInfo { } message ABCIResponsesInfo { - ABCIResponses abci_responses = 1; - int64 height = 2; + LegacyABCIResponses legacy_abci_responses = 1; + int64 height = 2; + abci.ResponseFinalizeBlock response_finalize_block = 3; } message Version { diff --git a/proxy/app_conn.go b/proxy/app_conn.go index 912085fa0..7a0efef61 100644 --- a/proxy/app_conn.go +++ b/proxy/app_conn.go @@ -1,6 +1,7 @@ package proxy import ( + "context" "time" "github.com/go-kit/kit/metrics" @@ -15,44 +16,38 @@ import ( // Enforce which abci msgs can be sent on a connection at the type level type AppConnConsensus interface { - SetResponseCallback(abcicli.Callback) Error() error - - InitChainSync(types.RequestInitChain) (*types.ResponseInitChain, error) - PrepareProposalSync(types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) - ProcessProposalSync(types.RequestProcessProposal) (*types.ResponseProcessProposal, error) - BeginBlockSync(types.RequestBeginBlock) (*types.ResponseBeginBlock, error) - DeliverTxAsync(types.RequestDeliverTx) *abcicli.ReqRes - EndBlockSync(types.RequestEndBlock) (*types.ResponseEndBlock, error) - CommitSync() (*types.ResponseCommit, error) + InitChain(context.Context, *types.RequestInitChain) (*types.ResponseInitChain, error) + PrepareProposal(context.Context, *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) + ProcessProposal(context.Context, *types.RequestProcessProposal) (*types.ResponseProcessProposal, error) + FinalizeBlock(context.Context, *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) + Commit(context.Context) (*types.ResponseCommit, error) } type AppConnMempool interface { SetResponseCallback(abcicli.Callback) Error() error - CheckTxAsync(types.RequestCheckTx) *abcicli.ReqRes - CheckTxSync(types.RequestCheckTx) (*types.ResponseCheckTx, error) - - FlushAsync() *abcicli.ReqRes - FlushSync() error + CheckTx(context.Context, *types.RequestCheckTx) (*types.ResponseCheckTx, error) + CheckTxAsync(context.Context, *types.RequestCheckTx) (*abcicli.ReqRes, error) + Flush(context.Context) error } type AppConnQuery interface { Error() error - EchoSync(string) (*types.ResponseEcho, error) - InfoSync(types.RequestInfo) (*types.ResponseInfo, error) - QuerySync(types.RequestQuery) (*types.ResponseQuery, error) + 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(types.RequestListSnapshots) (*types.ResponseListSnapshots, error) - OfferSnapshotSync(types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) - LoadSnapshotChunkSync(types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) - ApplySnapshotChunkSync(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) } //----------------------------------------------------------------------------------------- @@ -72,48 +67,34 @@ func NewAppConnConsensus(appConn abcicli.Client, metrics *Metrics) AppConnConsen } } -func (app *appConnConsensus) SetResponseCallback(cb abcicli.Callback) { - app.appConn.SetResponseCallback(cb) -} - func (app *appConnConsensus) Error() error { return app.appConn.Error() } -func (app *appConnConsensus) InitChainSync(req types.RequestInitChain) (*types.ResponseInitChain, error) { - defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "init_chain", "type", "sync"))() - return app.appConn.InitChainSync(req) +func (app *appConnConsensus) InitChain(ctx context.Context, req *types.RequestInitChain) (*types.ResponseInitChain, error) { + defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "init_chain"))() + return app.appConn.InitChain(ctx, req) } -func (app *appConnConsensus) PrepareProposalSync( - req types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { - defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "prepare_proposal", "type", "sync"))() - return app.appConn.PrepareProposalSync(req) +func (app *appConnConsensus) PrepareProposal(ctx context.Context, + req *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { + defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "prepare_proposal"))() + return app.appConn.PrepareProposal(ctx, req) } -func (app *appConnConsensus) ProcessProposalSync(req types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { - defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "process_proposal", "type", "sync"))() - return app.appConn.ProcessProposalSync(req) +func (app *appConnConsensus) ProcessProposal(ctx context.Context, req *types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { + defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "process_proposal"))() + return app.appConn.ProcessProposal(ctx, req) } -func (app *appConnConsensus) BeginBlockSync(req types.RequestBeginBlock) (*types.ResponseBeginBlock, error) { - defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "begin_block", "type", "sync"))() - return app.appConn.BeginBlockSync(req) -} - -func (app *appConnConsensus) DeliverTxAsync(req types.RequestDeliverTx) *abcicli.ReqRes { +func (app *appConnConsensus) FinalizeBlock(ctx context.Context, req *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "deliver_tx", "type", "async"))() - return app.appConn.DeliverTxAsync(req) + return app.appConn.FinalizeBlock(ctx, req) } -func (app *appConnConsensus) EndBlockSync(req types.RequestEndBlock) (*types.ResponseEndBlock, error) { - defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "end_block", "type", "sync"))() - return app.appConn.EndBlockSync(req) -} - -func (app *appConnConsensus) CommitSync() (*types.ResponseCommit, error) { - defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "commit", "type", "sync"))() - return app.appConn.CommitSync() +func (app *appConnConsensus) Commit(ctx context.Context) (*types.ResponseCommit, error) { + defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "commit"))() + return app.appConn.Commit(ctx, &types.RequestCommit{}) } //------------------------------------------------ @@ -139,24 +120,19 @@ func (app *appConnMempool) Error() error { return app.appConn.Error() } -func (app *appConnMempool) FlushAsync() *abcicli.ReqRes { - defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "flush", "type", "async"))() - return app.appConn.FlushAsync() +func (app *appConnMempool) Flush(ctx context.Context) error { + defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "flush"))() + return app.appConn.Flush(ctx) } -func (app *appConnMempool) FlushSync() error { - defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "flush", "type", "sync"))() - return app.appConn.FlushSync() -} - -func (app *appConnMempool) CheckTxAsync(req types.RequestCheckTx) *abcicli.ReqRes { - defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "check_tx", "type", "async"))() - return app.appConn.CheckTxAsync(req) -} - -func (app *appConnMempool) CheckTxSync(req types.RequestCheckTx) (*types.ResponseCheckTx, error) { +func (app *appConnMempool) CheckTx(ctx context.Context, req *types.RequestCheckTx) (*types.ResponseCheckTx, error) { defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "check_tx", "type", "sync"))() - return app.appConn.CheckTxSync(req) + return app.appConn.CheckTx(ctx, req) +} + +func (app *appConnMempool) CheckTxAsync(ctx context.Context, req *types.RequestCheckTx) (*abcicli.ReqRes, error) { + defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "check_tx", "type", "async"))() + return app.appConn.CheckTxAsync(ctx, req) } //------------------------------------------------ @@ -178,19 +154,19 @@ func (app *appConnQuery) Error() error { return app.appConn.Error() } -func (app *appConnQuery) EchoSync(msg string) (*types.ResponseEcho, error) { - defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "echo", "type", "sync"))() - return app.appConn.EchoSync(msg) +func (app *appConnQuery) Echo(ctx context.Context, msg string) (*types.ResponseEcho, error) { + defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "echo"))() + return app.appConn.Echo(ctx, msg) } -func (app *appConnQuery) InfoSync(req types.RequestInfo) (*types.ResponseInfo, error) { - defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "info", "type", "sync"))() - return app.appConn.InfoSync(req) +func (app *appConnQuery) Info(ctx context.Context, req *types.RequestInfo) (*types.ResponseInfo, error) { + defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "info"))() + return app.appConn.Info(ctx, req) } -func (app *appConnQuery) QuerySync(reqQuery types.RequestQuery) (*types.ResponseQuery, error) { - defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "query", "type", "sync"))() - return app.appConn.QuerySync(reqQuery) +func (app *appConnQuery) Query(ctx context.Context, req *types.RequestQuery) (*types.ResponseQuery, error) { + defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "query"))() + return app.appConn.Query(ctx, req) } //------------------------------------------------ @@ -212,26 +188,24 @@ func (app *appConnSnapshot) Error() error { return app.appConn.Error() } -func (app *appConnSnapshot) ListSnapshotsSync(req types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { - defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "list_snapshots", "type", "sync"))() - return app.appConn.ListSnapshotsSync(req) +func (app *appConnSnapshot) ListSnapshots(ctx context.Context, req *types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { + defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "list_snapshots"))() + return app.appConn.ListSnapshots(ctx, req) } -func (app *appConnSnapshot) OfferSnapshotSync(req types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { - defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "offer_snapshot", "type", "sync"))() - return app.appConn.OfferSnapshotSync(req) +func (app *appConnSnapshot) OfferSnapshot(ctx context.Context, req *types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { + defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "offer_snapshot"))() + return app.appConn.OfferSnapshot(ctx, req) } -func (app *appConnSnapshot) LoadSnapshotChunkSync( - req types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { - defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "load_snapshot_chunk", "type", "sync"))() - return app.appConn.LoadSnapshotChunkSync(req) +func (app *appConnSnapshot) LoadSnapshotChunk(ctx context.Context, req *types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { + defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "load_snapshot_chunk"))() + return app.appConn.LoadSnapshotChunk(ctx, req) } -func (app *appConnSnapshot) ApplySnapshotChunkSync( - req types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { - defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "apply_snapshot_chunk", "type", "sync"))() - return app.appConn.ApplySnapshotChunkSync(req) +func (app *appConnSnapshot) ApplySnapshotChunk(ctx context.Context, req *types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { + defer addTimeSample(app.metrics.MethodTimingSeconds.With("method", "apply_snapshot_chunk"))() + return app.appConn.ApplySnapshotChunk(ctx, req) } // addTimeSample returns a function that, when called, adds an observation to m. diff --git a/proxy/app_conn_test.go b/proxy/app_conn_test.go index 683fe47e0..37db543b0 100644 --- a/proxy/app_conn_test.go +++ b/proxy/app_conn_test.go @@ -1,48 +1,17 @@ package proxy import ( + "context" "fmt" - "strings" "testing" - abcicli "github.com/tendermint/tendermint/abci/client" "github.com/tendermint/tendermint/abci/example/kvstore" "github.com/tendermint/tendermint/abci/server" - "github.com/tendermint/tendermint/abci/types" + abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/libs/log" tmrand "github.com/tendermint/tendermint/libs/rand" ) -//---------------------------------------- - -type AppConnTest interface { - EchoAsync(string) *abcicli.ReqRes - FlushSync() error - InfoSync(types.RequestInfo) (*types.ResponseInfo, error) -} - -type appConnTest struct { - appConn abcicli.Client -} - -func NewAppConnTest(appConn abcicli.Client) AppConnTest { - return &appConnTest{appConn} -} - -func (app *appConnTest) EchoAsync(msg string) *abcicli.ReqRes { - return app.appConn.EchoAsync(msg) -} - -func (app *appConnTest) FlushSync() error { - return app.appConn.FlushSync() -} - -func (app *appConnTest) InfoSync(req types.RequestInfo) (*types.ResponseInfo, error) { - return app.appConn.InfoSync(req) -} - -//---------------------------------------- - var SOCKET = "socket" func TestEcho(t *testing.T) { @@ -50,7 +19,7 @@ func TestEcho(t *testing.T) { clientCreator := NewRemoteClientCreator(sockPath, SOCKET, true) // Start server - s := server.NewSocketServer(sockPath, kvstore.NewApplication()) + s := server.NewSocketServer(sockPath, kvstore.NewInMemoryApplication()) s.SetLogger(log.TestingLogger().With("module", "abci-server")) if err := s.Start(); err != nil { t.Fatalf("Error starting socket server: %v", err.Error()) @@ -71,13 +40,16 @@ func TestEcho(t *testing.T) { t.Fatalf("Error starting ABCI client: %v", err.Error()) } - proxy := NewAppConnTest(cli) + proxy := NewAppConnMempool(cli, NopMetrics()) t.Log("Connected") for i := 0; i < 1000; i++ { - proxy.EchoAsync(fmt.Sprintf("echo-%v", i)) + _, err = proxy.CheckTx(context.Background(), &abci.RequestCheckTx{Tx: []byte(fmt.Sprintf("echo-%v", i))}) + if err != nil { + t.Fatal(err) + } } - if err := proxy.FlushSync(); err != nil { + if err := proxy.Flush(context.Background()); err != nil { t.Error(err) } } @@ -88,7 +60,7 @@ func BenchmarkEcho(b *testing.B) { clientCreator := NewRemoteClientCreator(sockPath, SOCKET, true) // Start server - s := server.NewSocketServer(sockPath, kvstore.NewApplication()) + s := server.NewSocketServer(sockPath, kvstore.NewInMemoryApplication()) s.SetLogger(log.TestingLogger().With("module", "abci-server")) if err := s.Start(); err != nil { b.Fatalf("Error starting socket server: %v", err.Error()) @@ -109,57 +81,19 @@ func BenchmarkEcho(b *testing.B) { b.Fatalf("Error starting ABCI client: %v", err.Error()) } - proxy := NewAppConnTest(cli) + proxy := NewAppConnMempool(cli, NopMetrics()) b.Log("Connected") - echoString := strings.Repeat(" ", 200) b.StartTimer() // Start benchmarking tests for i := 0; i < b.N; i++ { - proxy.EchoAsync(echoString) + _, err = proxy.CheckTx(context.Background(), &abci.RequestCheckTx{Tx: []byte("hello")}) + if err != nil { + b.Error(err) + } } - if err := proxy.FlushSync(); err != nil { + if err := proxy.Flush(context.Background()); err != nil { b.Error(err) } b.StopTimer() - // info := proxy.InfoSync(types.RequestInfo{""}) - // b.Log("N: ", b.N, info) -} - -func TestInfo(t *testing.T) { - sockPath := fmt.Sprintf("unix:///tmp/echo_%v.sock", tmrand.Str(6)) - clientCreator := NewRemoteClientCreator(sockPath, SOCKET, true) - - // Start server - s := server.NewSocketServer(sockPath, kvstore.NewApplication()) - s.SetLogger(log.TestingLogger().With("module", "abci-server")) - if err := s.Start(); err != nil { - t.Fatalf("Error starting socket server: %v", err.Error()) - } - t.Cleanup(func() { - if err := s.Stop(); err != nil { - t.Error(err) - } - }) - - // Start client - cli, err := clientCreator.NewABCIClient() - if err != nil { - t.Fatalf("Error creating ABCI client: %v", err.Error()) - } - cli.SetLogger(log.TestingLogger().With("module", "abci-client")) - if err := cli.Start(); err != nil { - t.Fatalf("Error starting ABCI client: %v", err.Error()) - } - - proxy := NewAppConnTest(cli) - t.Log("Connected") - - resInfo, err := proxy.InfoSync(RequestInfo) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - if resInfo.Data != "{\"size\":0}" { - t.Error("Expected ResponseInfo with one element '{\"size\":0}' but got something else") - } } diff --git a/proxy/client.go b/proxy/client.go index 8fc9917ae..0a77659cc 100644 --- a/proxy/client.go +++ b/proxy/client.go @@ -94,9 +94,9 @@ func (r *remoteClientCreator) NewABCIClient() (abcicli.Client, error) { func DefaultClientCreator(addr, transport, dbDir string) ClientCreator { switch addr { case "kvstore": - return NewLocalClientCreator(kvstore.NewApplication()) + return NewLocalClientCreator(kvstore.NewInMemoryApplication()) case "persistent_kvstore": - return NewLocalClientCreator(kvstore.NewPersistentKVStoreApplication(dbDir)) + return NewLocalClientCreator(kvstore.NewPersistentApplication(dbDir)) case "e2e": app, err := e2e.NewApplication(e2e.DefaultConfig(dbDir)) if err != nil { diff --git a/proxy/mocks/app_conn_consensus.go b/proxy/mocks/app_conn_consensus.go index eccf74fc3..6c1abcef6 100644 --- a/proxy/mocks/app_conn_consensus.go +++ b/proxy/mocks/app_conn_consensus.go @@ -3,8 +3,9 @@ package mocks import ( + context "context" + mock "github.com/stretchr/testify/mock" - abcicli "github.com/tendermint/tendermint/abci/client" types "github.com/tendermint/tendermint/abci/types" ) @@ -14,36 +15,13 @@ type AppConnConsensus struct { mock.Mock } -// BeginBlockSync provides a mock function with given fields: _a0 -func (_m *AppConnConsensus) BeginBlockSync(_a0 types.RequestBeginBlock) (*types.ResponseBeginBlock, error) { +// 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.ResponseBeginBlock - if rf, ok := ret.Get(0).(func(types.RequestBeginBlock) *types.ResponseBeginBlock); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.ResponseBeginBlock) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(types.RequestBeginBlock) error); ok { - r1 = rf(_a0) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// CommitSync provides a mock function with given fields: -func (_m *AppConnConsensus) CommitSync() (*types.ResponseCommit, error) { - ret := _m.Called() - var r0 *types.ResponseCommit - if rf, ok := ret.Get(0).(func() *types.ResponseCommit); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(context.Context) *types.ResponseCommit); ok { + r0 = rf(_a0) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseCommit) @@ -51,46 +29,7 @@ func (_m *AppConnConsensus) CommitSync() (*types.ResponseCommit, error) { } var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DeliverTxAsync provides a mock function with given fields: _a0 -func (_m *AppConnConsensus) DeliverTxAsync(_a0 types.RequestDeliverTx) *abcicli.ReqRes { - ret := _m.Called(_a0) - - var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestDeliverTx) *abcicli.ReqRes); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abcicli.ReqRes) - } - } - - return r0 -} - -// EndBlockSync provides a mock function with given fields: _a0 -func (_m *AppConnConsensus) EndBlockSync(_a0 types.RequestEndBlock) (*types.ResponseEndBlock, error) { - ret := _m.Called(_a0) - - var r0 *types.ResponseEndBlock - if rf, ok := ret.Get(0).(func(types.RequestEndBlock) *types.ResponseEndBlock); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.ResponseEndBlock) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(types.RequestEndBlock) error); ok { + if rf, ok := ret.Get(1).(func(context.Context) error); ok { r1 = rf(_a0) } else { r1 = ret.Error(1) @@ -113,13 +52,36 @@ func (_m *AppConnConsensus) Error() error { return r0 } -// InitChainSync provides a mock function with given fields: _a0 -func (_m *AppConnConsensus) InitChainSync(_a0 types.RequestInitChain) (*types.ResponseInitChain, error) { - ret := _m.Called(_a0) +// FinalizeBlock provides a mock function with given fields: _a0, _a1 +func (_m *AppConnConsensus) FinalizeBlock(_a0 context.Context, _a1 *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { + ret := _m.Called(_a0, _a1) + + var r0 *types.ResponseFinalizeBlock + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestFinalizeBlock) *types.ResponseFinalizeBlock); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseFinalizeBlock) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestFinalizeBlock) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// 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 - if rf, ok := ret.Get(0).(func(types.RequestInitChain) *types.ResponseInitChain); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestInitChain) *types.ResponseInitChain); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseInitChain) @@ -127,8 +89,8 @@ func (_m *AppConnConsensus) InitChainSync(_a0 types.RequestInitChain) (*types.Re } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestInitChain) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestInitChain) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -136,13 +98,13 @@ func (_m *AppConnConsensus) InitChainSync(_a0 types.RequestInitChain) (*types.Re return r0, r1 } -// PrepareProposalSync provides a mock function with given fields: _a0 -func (_m *AppConnConsensus) PrepareProposalSync(_a0 types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { - ret := _m.Called(_a0) +// PrepareProposal provides a mock function with given fields: _a0, _a1 +func (_m *AppConnConsensus) PrepareProposal(_a0 context.Context, _a1 *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponsePrepareProposal - if rf, ok := ret.Get(0).(func(types.RequestPrepareProposal) *types.ResponsePrepareProposal); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestPrepareProposal) *types.ResponsePrepareProposal); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponsePrepareProposal) @@ -150,8 +112,8 @@ func (_m *AppConnConsensus) PrepareProposalSync(_a0 types.RequestPrepareProposal } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestPrepareProposal) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestPrepareProposal) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -159,13 +121,13 @@ func (_m *AppConnConsensus) PrepareProposalSync(_a0 types.RequestPrepareProposal return r0, r1 } -// ProcessProposalSync provides a mock function with given fields: _a0 -func (_m *AppConnConsensus) ProcessProposalSync(_a0 types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { - ret := _m.Called(_a0) +// ProcessProposal provides a mock function with given fields: _a0, _a1 +func (_m *AppConnConsensus) ProcessProposal(_a0 context.Context, _a1 *types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { + ret := _m.Called(_a0, _a1) var r0 *types.ResponseProcessProposal - if rf, ok := ret.Get(0).(func(types.RequestProcessProposal) *types.ResponseProcessProposal); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestProcessProposal) *types.ResponseProcessProposal); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseProcessProposal) @@ -173,8 +135,8 @@ func (_m *AppConnConsensus) ProcessProposalSync(_a0 types.RequestProcessProposal } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestProcessProposal) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestProcessProposal) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -182,11 +144,6 @@ func (_m *AppConnConsensus) ProcessProposalSync(_a0 types.RequestProcessProposal return r0, r1 } -// SetResponseCallback provides a mock function with given fields: _a0 -func (_m *AppConnConsensus) SetResponseCallback(_a0 abcicli.Callback) { - _m.Called(_a0) -} - type mockConstructorTestingTNewAppConnConsensus interface { mock.TestingT Cleanup(func()) diff --git a/proxy/mocks/app_conn_mempool.go b/proxy/mocks/app_conn_mempool.go index 05e23dd43..0ce564199 100644 --- a/proxy/mocks/app_conn_mempool.go +++ b/proxy/mocks/app_conn_mempool.go @@ -3,9 +3,12 @@ package mocks import ( - mock "github.com/stretchr/testify/mock" + context "context" + abcicli "github.com/tendermint/tendermint/abci/client" + mock "github.com/stretchr/testify/mock" + types "github.com/tendermint/tendermint/abci/types" ) @@ -14,29 +17,13 @@ type AppConnMempool struct { mock.Mock } -// CheckTxAsync provides a mock function with given fields: _a0 -func (_m *AppConnMempool) CheckTxAsync(_a0 types.RequestCheckTx) *abcicli.ReqRes { - ret := _m.Called(_a0) - - var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestCheckTx) *abcicli.ReqRes); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abcicli.ReqRes) - } - } - - return r0 -} - -// CheckTxSync provides a mock function with given fields: _a0 -func (_m *AppConnMempool) CheckTxSync(_a0 types.RequestCheckTx) (*types.ResponseCheckTx, error) { - ret := _m.Called(_a0) +// 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(types.RequestCheckTx) *types.ResponseCheckTx); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestCheckTx) *types.ResponseCheckTx); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseCheckTx) @@ -44,8 +31,31 @@ func (_m *AppConnMempool) CheckTxSync(_a0 types.RequestCheckTx) (*types.Response } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestCheckTx) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestCheckTx) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CheckTxAsync provides a mock function with given fields: _a0, _a1 +func (_m *AppConnMempool) CheckTxAsync(_a0 context.Context, _a1 *types.RequestCheckTx) (*abcicli.ReqRes, error) { + ret := _m.Called(_a0, _a1) + + var r0 *abcicli.ReqRes + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestCheckTx) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*abcicli.ReqRes) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestCheckTx) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -67,29 +77,13 @@ func (_m *AppConnMempool) Error() error { return r0 } -// FlushAsync provides a mock function with given fields: -func (_m *AppConnMempool) FlushAsync() *abcicli.ReqRes { - ret := _m.Called() - - var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func() *abcicli.ReqRes); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*abcicli.ReqRes) - } - } - - return r0 -} - -// FlushSync provides a mock function with given fields: -func (_m *AppConnMempool) FlushSync() error { - ret := _m.Called() +// 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() error); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(_a0) } else { r0 = ret.Error(0) } @@ -97,11 +91,6 @@ func (_m *AppConnMempool) FlushSync() error { return r0 } -// SetResponseCallback provides a mock function with given fields: _a0 -func (_m *AppConnMempool) SetResponseCallback(_a0 abcicli.Callback) { - _m.Called(_a0) -} - type mockConstructorTestingTNewAppConnMempool interface { mock.TestingT Cleanup(func()) diff --git a/proxy/mocks/app_conn_query.go b/proxy/mocks/app_conn_query.go index 544ab765e..f6de46fa7 100644 --- a/proxy/mocks/app_conn_query.go +++ b/proxy/mocks/app_conn_query.go @@ -3,6 +3,8 @@ package mocks import ( + context "context" + mock "github.com/stretchr/testify/mock" types "github.com/tendermint/tendermint/abci/types" @@ -13,13 +15,13 @@ type AppConnQuery struct { mock.Mock } -// EchoSync provides a mock function with given fields: _a0 -func (_m *AppConnQuery) EchoSync(_a0 string) (*types.ResponseEcho, error) { - ret := _m.Called(_a0) +// 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 - if rf, ok := ret.Get(0).(func(string) *types.ResponseEcho); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, string) *types.ResponseEcho); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseEcho) @@ -27,8 +29,8 @@ func (_m *AppConnQuery) EchoSync(_a0 string) (*types.ResponseEcho, error) { } var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -50,13 +52,13 @@ func (_m *AppConnQuery) Error() error { return r0 } -// InfoSync provides a mock function with given fields: _a0 -func (_m *AppConnQuery) InfoSync(_a0 types.RequestInfo) (*types.ResponseInfo, error) { - ret := _m.Called(_a0) +// 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 - if rf, ok := ret.Get(0).(func(types.RequestInfo) *types.ResponseInfo); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestInfo) *types.ResponseInfo); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseInfo) @@ -64,8 +66,8 @@ func (_m *AppConnQuery) InfoSync(_a0 types.RequestInfo) (*types.ResponseInfo, er } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestInfo) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestInfo) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -73,13 +75,13 @@ func (_m *AppConnQuery) InfoSync(_a0 types.RequestInfo) (*types.ResponseInfo, er return r0, r1 } -// QuerySync provides a mock function with given fields: _a0 -func (_m *AppConnQuery) QuerySync(_a0 types.RequestQuery) (*types.ResponseQuery, error) { - ret := _m.Called(_a0) +// 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 - if rf, ok := ret.Get(0).(func(types.RequestQuery) *types.ResponseQuery); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestQuery) *types.ResponseQuery); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseQuery) @@ -87,8 +89,8 @@ func (_m *AppConnQuery) QuerySync(_a0 types.RequestQuery) (*types.ResponseQuery, } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestQuery) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestQuery) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } diff --git a/proxy/mocks/app_conn_snapshot.go b/proxy/mocks/app_conn_snapshot.go index e3d5cb6cd..368e24f5f 100644 --- a/proxy/mocks/app_conn_snapshot.go +++ b/proxy/mocks/app_conn_snapshot.go @@ -3,6 +3,8 @@ package mocks import ( + context "context" + mock "github.com/stretchr/testify/mock" types "github.com/tendermint/tendermint/abci/types" @@ -13,13 +15,13 @@ type AppConnSnapshot struct { mock.Mock } -// ApplySnapshotChunkSync provides a mock function with given fields: _a0 -func (_m *AppConnSnapshot) ApplySnapshotChunkSync(_a0 types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { - ret := _m.Called(_a0) +// 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 - if rf, ok := ret.Get(0).(func(types.RequestApplySnapshotChunk) *types.ResponseApplySnapshotChunk); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestApplySnapshotChunk) *types.ResponseApplySnapshotChunk); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseApplySnapshotChunk) @@ -27,8 +29,8 @@ func (_m *AppConnSnapshot) ApplySnapshotChunkSync(_a0 types.RequestApplySnapshot } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestApplySnapshotChunk) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestApplySnapshotChunk) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -50,13 +52,13 @@ func (_m *AppConnSnapshot) Error() error { return r0 } -// ListSnapshotsSync provides a mock function with given fields: _a0 -func (_m *AppConnSnapshot) ListSnapshotsSync(_a0 types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { - ret := _m.Called(_a0) +// 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 - if rf, ok := ret.Get(0).(func(types.RequestListSnapshots) *types.ResponseListSnapshots); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestListSnapshots) *types.ResponseListSnapshots); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseListSnapshots) @@ -64,8 +66,8 @@ func (_m *AppConnSnapshot) ListSnapshotsSync(_a0 types.RequestListSnapshots) (*t } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestListSnapshots) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestListSnapshots) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -73,13 +75,13 @@ func (_m *AppConnSnapshot) ListSnapshotsSync(_a0 types.RequestListSnapshots) (*t return r0, r1 } -// LoadSnapshotChunkSync provides a mock function with given fields: _a0 -func (_m *AppConnSnapshot) LoadSnapshotChunkSync(_a0 types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { - ret := _m.Called(_a0) +// 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 - if rf, ok := ret.Get(0).(func(types.RequestLoadSnapshotChunk) *types.ResponseLoadSnapshotChunk); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestLoadSnapshotChunk) *types.ResponseLoadSnapshotChunk); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseLoadSnapshotChunk) @@ -87,8 +89,8 @@ func (_m *AppConnSnapshot) LoadSnapshotChunkSync(_a0 types.RequestLoadSnapshotCh } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestLoadSnapshotChunk) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestLoadSnapshotChunk) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } @@ -96,13 +98,13 @@ func (_m *AppConnSnapshot) LoadSnapshotChunkSync(_a0 types.RequestLoadSnapshotCh return r0, r1 } -// OfferSnapshotSync provides a mock function with given fields: _a0 -func (_m *AppConnSnapshot) OfferSnapshotSync(_a0 types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { - ret := _m.Called(_a0) +// 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 - if rf, ok := ret.Get(0).(func(types.RequestOfferSnapshot) *types.ResponseOfferSnapshot); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestOfferSnapshot) *types.ResponseOfferSnapshot); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseOfferSnapshot) @@ -110,8 +112,8 @@ func (_m *AppConnSnapshot) OfferSnapshotSync(_a0 types.RequestOfferSnapshot) (*t } var r1 error - if rf, ok := ret.Get(1).(func(types.RequestOfferSnapshot) error); ok { - r1 = rf(_a0) + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestOfferSnapshot) error); ok { + r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) } diff --git a/proxy/version.go b/proxy/version.go index 110757028..119a0acd1 100644 --- a/proxy/version.go +++ b/proxy/version.go @@ -8,7 +8,7 @@ import ( // RequestInfo contains all the information for sending // the abci.RequestInfo message during handshake with the app. // It contains only compile-time version information. -var RequestInfo = abci.RequestInfo{ +var RequestInfo = &abci.RequestInfo{ Version: version.TMCoreSemVer, BlockVersion: version.BlockProtocol, P2PVersion: version.P2PProtocol, diff --git a/rpc/client/event_test.go b/rpc/client/event_test.go index 5734d6c1b..0905dc7a8 100644 --- a/rpc/client/event_test.go +++ b/rpc/client/event_test.go @@ -156,12 +156,6 @@ func testTxEventsSent(t *testing.T, broadcastMethod string) { } } -// Test HTTPClient resubscribes upon disconnect && subscription error. -// Test Local client resubscribes upon subscription error. -func TestClientsResubscribe(t *testing.T) { - // TODO(melekes) -} - func TestHTTPReturnsErrorIfClientIsNotRunning(t *testing.T) { c := getHTTPClient() diff --git a/rpc/client/examples_test.go b/rpc/client/examples_test.go index 474aba1b6..4b38727a3 100644 --- a/rpc/client/examples_test.go +++ b/rpc/client/examples_test.go @@ -14,7 +14,7 @@ import ( func ExampleHTTP_simple() { // Start a tendermint node (and kvstore) in the background to test against - app := kvstore.NewApplication() + app := kvstore.NewInMemoryApplication() node := rpctest.StartTendermint(app, rpctest.SuppressStdout, rpctest.RecreateConfig) defer rpctest.StopTendermint(node) @@ -36,7 +36,7 @@ func ExampleHTTP_simple() { if err != nil { log.Fatal(err) } - if bres.CheckTx.IsErr() || bres.DeliverTx.IsErr() { + if bres.CheckTx.IsErr() || bres.TxResult.IsErr() { log.Fatal("BroadcastTxCommit transaction failed") } @@ -67,7 +67,7 @@ func ExampleHTTP_simple() { func ExampleHTTP_batching() { // Start a tendermint node (and kvstore) in the background to test against - app := kvstore.NewApplication() + app := kvstore.NewInMemoryApplication() node := rpctest.StartTendermint(app, rpctest.SuppressStdout, rpctest.RecreateConfig) // Create our RPC client diff --git a/rpc/client/interface.go b/rpc/client/interface.go index 92783634c..bc3df8f15 100644 --- a/rpc/client/interface.go +++ b/rpc/client/interface.go @@ -74,7 +74,7 @@ type SignClient interface { Tx(ctx context.Context, hash []byte, prove bool) (*ctypes.ResultTx, error) // TxSearch defines a method to search for a paginated set of transactions by - // DeliverTx event search criteria. + // transaction event search criteria. TxSearch( ctx context.Context, query string, @@ -83,8 +83,8 @@ type SignClient interface { orderBy string, ) (*ctypes.ResultTxSearch, error) - // BlockSearch defines a method to search for a paginated set of blocks by - // BeginBlock and EndBlock event search criteria. + // BlockSearch defines a method to search for a paginated set of blocks based + // from FinalizeBlock event search criteria. BlockSearch( ctx context.Context, query string, diff --git a/rpc/client/main_test.go b/rpc/client/main_test.go index 4c0534868..dbdb989c9 100644 --- a/rpc/client/main_test.go +++ b/rpc/client/main_test.go @@ -18,7 +18,7 @@ func TestMain(m *testing.M) { panic(err) } - app := kvstore.NewPersistentKVStoreApplication(dir) + app := kvstore.NewPersistentApplication(dir) node = rpctest.StartTendermint(app) code := m.Run() diff --git a/rpc/client/mock/abci.go b/rpc/client/mock/abci.go deleted file mode 100644 index 0737deec0..000000000 --- a/rpc/client/mock/abci.go +++ /dev/null @@ -1,241 +0,0 @@ -package mock - -import ( - "context" - - abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/libs/bytes" - "github.com/tendermint/tendermint/proxy" - "github.com/tendermint/tendermint/rpc/client" - ctypes "github.com/tendermint/tendermint/rpc/core/types" - "github.com/tendermint/tendermint/types" -) - -// ABCIApp will send all abci related request to the named app, -// so you can test app behavior from a client without needing -// an entire tendermint node -type ABCIApp struct { - App abci.Application -} - -var ( - _ client.ABCIClient = ABCIApp{} - _ client.ABCIClient = ABCIMock{} - _ client.ABCIClient = (*ABCIRecorder)(nil) -) - -func (a ABCIApp) ABCIInfo(ctx context.Context) (*ctypes.ResultABCIInfo, error) { - return &ctypes.ResultABCIInfo{Response: a.App.Info(proxy.RequestInfo)}, nil -} - -func (a ABCIApp) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error) { - return a.ABCIQueryWithOptions(ctx, path, data, client.DefaultABCIQueryOptions) -} - -func (a ABCIApp) ABCIQueryWithOptions( - ctx context.Context, - path string, - data bytes.HexBytes, - opts client.ABCIQueryOptions) (*ctypes.ResultABCIQuery, error) { - q := a.App.Query(abci.RequestQuery{ - Data: data, - Path: path, - Height: opts.Height, - Prove: opts.Prove, - }) - return &ctypes.ResultABCIQuery{Response: q}, nil -} - -// NOTE: Caller should call a.App.Commit() separately, -// this function does not actually wait for a commit. -// TODO: Make it wait for a commit and set res.Height appropriately. -func (a ABCIApp) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) { - res := ctypes.ResultBroadcastTxCommit{} - res.CheckTx = a.App.CheckTx(abci.RequestCheckTx{Tx: tx}) - if res.CheckTx.IsErr() { - return &res, nil - } - res.DeliverTx = a.App.DeliverTx(abci.RequestDeliverTx{Tx: tx}) - res.Height = -1 // TODO - return &res, nil -} - -func (a ABCIApp) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) { - c := a.App.CheckTx(abci.RequestCheckTx{Tx: tx}) - // and this gets written in a background thread... - if !c.IsErr() { - go func() { a.App.DeliverTx(abci.RequestDeliverTx{Tx: tx}) }() - } - return &ctypes.ResultBroadcastTx{ - Code: c.Code, - Data: c.Data, - Log: c.Log, - Codespace: c.Codespace, - Hash: tx.Hash(), - }, nil -} - -func (a ABCIApp) BroadcastTxSync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) { - c := a.App.CheckTx(abci.RequestCheckTx{Tx: tx}) - // and this gets written in a background thread... - if !c.IsErr() { - go func() { a.App.DeliverTx(abci.RequestDeliverTx{Tx: tx}) }() - } - return &ctypes.ResultBroadcastTx{ - Code: c.Code, - Data: c.Data, - Log: c.Log, - Codespace: c.Codespace, - Hash: tx.Hash(), - }, nil -} - -// ABCIMock will send all abci related request to the named app, -// so you can test app behavior from a client without needing -// an entire tendermint node -type ABCIMock struct { - Info Call - Query Call - BroadcastCommit Call - Broadcast Call -} - -func (m ABCIMock) ABCIInfo(ctx context.Context) (*ctypes.ResultABCIInfo, error) { - res, err := m.Info.GetResponse(nil) - if err != nil { - return nil, err - } - return &ctypes.ResultABCIInfo{Response: res.(abci.ResponseInfo)}, nil -} - -func (m ABCIMock) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error) { - return m.ABCIQueryWithOptions(ctx, path, data, client.DefaultABCIQueryOptions) -} - -func (m ABCIMock) ABCIQueryWithOptions( - ctx context.Context, - path string, - data bytes.HexBytes, - opts client.ABCIQueryOptions) (*ctypes.ResultABCIQuery, error) { - res, err := m.Query.GetResponse(QueryArgs{path, data, opts.Height, opts.Prove}) - if err != nil { - return nil, err - } - resQuery := res.(abci.ResponseQuery) - return &ctypes.ResultABCIQuery{Response: resQuery}, nil -} - -func (m ABCIMock) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) { - res, err := m.BroadcastCommit.GetResponse(tx) - if err != nil { - return nil, err - } - return res.(*ctypes.ResultBroadcastTxCommit), nil -} - -func (m ABCIMock) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) { - res, err := m.Broadcast.GetResponse(tx) - if err != nil { - return nil, err - } - return res.(*ctypes.ResultBroadcastTx), nil -} - -func (m ABCIMock) BroadcastTxSync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) { - res, err := m.Broadcast.GetResponse(tx) - if err != nil { - return nil, err - } - return res.(*ctypes.ResultBroadcastTx), nil -} - -// ABCIRecorder can wrap another type (ABCIApp, ABCIMock, or Client) -// and record all ABCI related calls. -type ABCIRecorder struct { - Client client.ABCIClient - Calls []Call -} - -func NewABCIRecorder(client client.ABCIClient) *ABCIRecorder { - return &ABCIRecorder{ - Client: client, - Calls: []Call{}, - } -} - -type QueryArgs struct { - Path string - Data bytes.HexBytes - Height int64 - Prove bool -} - -func (r *ABCIRecorder) addCall(call Call) { - r.Calls = append(r.Calls, call) -} - -func (r *ABCIRecorder) ABCIInfo(ctx context.Context) (*ctypes.ResultABCIInfo, error) { - res, err := r.Client.ABCIInfo(ctx) - r.addCall(Call{ - Name: "abci_info", - Response: res, - Error: err, - }) - return res, err -} - -func (r *ABCIRecorder) ABCIQuery( - ctx context.Context, - path string, - data bytes.HexBytes, -) (*ctypes.ResultABCIQuery, error) { - return r.ABCIQueryWithOptions(ctx, path, data, client.DefaultABCIQueryOptions) -} - -func (r *ABCIRecorder) ABCIQueryWithOptions( - ctx context.Context, - path string, - data bytes.HexBytes, - opts client.ABCIQueryOptions) (*ctypes.ResultABCIQuery, error) { - res, err := r.Client.ABCIQueryWithOptions(ctx, path, data, opts) - r.addCall(Call{ - Name: "abci_query", - Args: QueryArgs{path, data, opts.Height, opts.Prove}, - Response: res, - Error: err, - }) - return res, err -} - -func (r *ABCIRecorder) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) { - res, err := r.Client.BroadcastTxCommit(ctx, tx) - r.addCall(Call{ - Name: "broadcast_tx_commit", - Args: tx, - Response: res, - Error: err, - }) - return res, err -} - -func (r *ABCIRecorder) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) { - res, err := r.Client.BroadcastTxAsync(ctx, tx) - r.addCall(Call{ - Name: "broadcast_tx_async", - Args: tx, - Response: res, - Error: err, - }) - return res, err -} - -func (r *ABCIRecorder) BroadcastTxSync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) { - res, err := r.Client.BroadcastTxSync(ctx, tx) - r.addCall(Call{ - Name: "broadcast_tx_sync", - Args: tx, - Response: res, - Error: err, - }) - return res, err -} diff --git a/rpc/client/mock/abci_test.go b/rpc/client/mock/abci_test.go deleted file mode 100644 index d164b275a..000000000 --- a/rpc/client/mock/abci_test.go +++ /dev/null @@ -1,199 +0,0 @@ -package mock_test - -import ( - "context" - "errors" - "fmt" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/tendermint/tendermint/abci/example/kvstore" - abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/libs/bytes" - "github.com/tendermint/tendermint/rpc/client" - "github.com/tendermint/tendermint/rpc/client/mock" - ctypes "github.com/tendermint/tendermint/rpc/core/types" - "github.com/tendermint/tendermint/types" -) - -func TestABCIMock(t *testing.T) { - assert, require := assert.New(t), require.New(t) - - key, value := []byte("foo"), []byte("bar") - height := int64(10) - goodTx := types.Tx{0x01, 0xff} - badTx := types.Tx{0x12, 0x21} - - m := mock.ABCIMock{ - Info: mock.Call{Error: errors.New("foobar")}, - Query: mock.Call{Response: abci.ResponseQuery{ - Key: key, - Value: value, - Height: height, - }}, - // Broadcast commit depends on call - BroadcastCommit: mock.Call{ - Args: goodTx, - Response: &ctypes.ResultBroadcastTxCommit{ - CheckTx: abci.ResponseCheckTx{Data: bytes.HexBytes("stand")}, - DeliverTx: abci.ResponseDeliverTx{Data: bytes.HexBytes("deliver")}, - }, - Error: errors.New("bad tx"), - }, - Broadcast: mock.Call{Error: errors.New("must commit")}, - } - - // now, let's try to make some calls - _, err := m.ABCIInfo(context.Background()) - require.NotNil(err) - assert.Equal("foobar", err.Error()) - - // query always returns the response - _query, err := m.ABCIQueryWithOptions(context.Background(), "/", nil, client.ABCIQueryOptions{Prove: false}) - query := _query.Response - require.Nil(err) - require.NotNil(query) - assert.EqualValues(key, query.Key) - assert.EqualValues(value, query.Value) - assert.Equal(height, query.Height) - - // non-commit calls always return errors - _, err = m.BroadcastTxSync(context.Background(), goodTx) - require.NotNil(err) - assert.Equal("must commit", err.Error()) - _, err = m.BroadcastTxAsync(context.Background(), goodTx) - require.NotNil(err) - assert.Equal("must commit", err.Error()) - - // commit depends on the input - _, err = m.BroadcastTxCommit(context.Background(), badTx) - require.NotNil(err) - assert.Equal("bad tx", err.Error()) - bres, err := m.BroadcastTxCommit(context.Background(), goodTx) - require.Nil(err, "%+v", err) - assert.EqualValues(0, bres.CheckTx.Code) - assert.EqualValues("stand", bres.CheckTx.Data) - assert.EqualValues("deliver", bres.DeliverTx.Data) -} - -func TestABCIRecorder(t *testing.T) { - assert, require := assert.New(t), require.New(t) - - // This mock returns errors on everything but Query - m := mock.ABCIMock{ - Info: mock.Call{Response: abci.ResponseInfo{ - Data: "data", - Version: "v0.9.9", - }}, - Query: mock.Call{Error: errors.New("query")}, - Broadcast: mock.Call{Error: errors.New("broadcast")}, - BroadcastCommit: mock.Call{Error: errors.New("broadcast_commit")}, - } - r := mock.NewABCIRecorder(m) - - require.Equal(0, len(r.Calls)) - - _, err := r.ABCIInfo(context.Background()) - assert.Nil(err, "expected no err on info") - - _, err = r.ABCIQueryWithOptions( - context.Background(), - "path", - bytes.HexBytes("data"), - client.ABCIQueryOptions{Prove: false}, - ) - assert.NotNil(err, "expected error on query") - require.Equal(2, len(r.Calls)) - - info := r.Calls[0] - assert.Equal("abci_info", info.Name) - assert.Nil(info.Error) - assert.Nil(info.Args) - require.NotNil(info.Response) - ir, ok := info.Response.(*ctypes.ResultABCIInfo) - require.True(ok) - assert.Equal("data", ir.Response.Data) - assert.Equal("v0.9.9", ir.Response.Version) - - query := r.Calls[1] - assert.Equal("abci_query", query.Name) - assert.Nil(query.Response) - require.NotNil(query.Error) - assert.Equal("query", query.Error.Error()) - require.NotNil(query.Args) - qa, ok := query.Args.(mock.QueryArgs) - require.True(ok) - assert.Equal("path", qa.Path) - assert.EqualValues("data", qa.Data) - assert.False(qa.Prove) - - // now add some broadcasts (should all err) - txs := []types.Tx{{1}, {2}, {3}} - _, err = r.BroadcastTxCommit(context.Background(), txs[0]) - assert.NotNil(err, "expected err on broadcast") - _, err = r.BroadcastTxSync(context.Background(), txs[1]) - assert.NotNil(err, "expected err on broadcast") - _, err = r.BroadcastTxAsync(context.Background(), txs[2]) - assert.NotNil(err, "expected err on broadcast") - - require.Equal(5, len(r.Calls)) - - bc := r.Calls[2] - assert.Equal("broadcast_tx_commit", bc.Name) - assert.Nil(bc.Response) - require.NotNil(bc.Error) - assert.EqualValues(bc.Args, txs[0]) - - bs := r.Calls[3] - assert.Equal("broadcast_tx_sync", bs.Name) - assert.Nil(bs.Response) - require.NotNil(bs.Error) - assert.EqualValues(bs.Args, txs[1]) - - ba := r.Calls[4] - assert.Equal("broadcast_tx_async", ba.Name) - assert.Nil(ba.Response) - require.NotNil(ba.Error) - assert.EqualValues(ba.Args, txs[2]) -} - -func TestABCIApp(t *testing.T) { - assert, require := assert.New(t), require.New(t) - app := kvstore.NewApplication() - m := mock.ABCIApp{app} - - // get some info - info, err := m.ABCIInfo(context.Background()) - require.Nil(err) - assert.Equal(`{"size":0}`, info.Response.GetData()) - - // add a key - key, value := "foo", "bar" - tx := fmt.Sprintf("%s=%s", key, value) - res, err := m.BroadcastTxCommit(context.Background(), types.Tx(tx)) - require.Nil(err) - assert.True(res.CheckTx.IsOK()) - require.NotNil(res.DeliverTx) - assert.True(res.DeliverTx.IsOK()) - - // commit - // TODO: This may not be necessary in the future - if res.Height == -1 { - m.App.Commit() - } - - // check the key - _qres, err := m.ABCIQueryWithOptions( - context.Background(), - "/key", - bytes.HexBytes(key), - client.ABCIQueryOptions{Prove: true}, - ) - qres := _qres.Response - require.Nil(err) - assert.EqualValues(value, qres.Value) - - // XXX Check proof -} diff --git a/rpc/client/rpc_test.go b/rpc/client/rpc_test.go index 4b8b11f98..2140f88be 100644 --- a/rpc/client/rpc_test.go +++ b/rpc/client/rpc_test.go @@ -252,7 +252,7 @@ func TestAppCalls(t *testing.T) { k, v, tx := MakeTxKV() bres, err := c.BroadcastTxCommit(context.Background(), tx) require.NoError(err) - require.True(bres.DeliverTx.IsOK()) + require.True(bres.TxResult.IsOK()) txh := bres.Height apph := txh + 1 // this is where the tx will be applied to the state @@ -368,7 +368,7 @@ func TestBroadcastTxCommit(t *testing.T) { bres, err := c.BroadcastTxCommit(context.Background(), tx) require.Nil(err, "%d: %+v", i, err) require.True(bres.CheckTx.IsOK()) - require.True(bres.DeliverTx.IsOK()) + require.True(bres.TxResult.IsOK()) require.Equal(0, mempool.Size()) } @@ -377,9 +377,9 @@ func TestBroadcastTxCommit(t *testing.T) { func TestUnconfirmedTxs(t *testing.T) { _, _, tx := MakeTxKV() - ch := make(chan *abci.Response, 1) + ch := make(chan *abci.ResponseCheckTx, 1) mempool := node.Mempool() - err := mempool.CheckTx(tx, func(resp *abci.Response) { ch <- resp }, mempl.TxInfo{}) + err := mempool.CheckTx(tx, func(resp *abci.ResponseCheckTx) { ch <- resp }, mempl.TxInfo{}) require.NoError(t, err) // wait for tx to arrive in mempoool. @@ -407,9 +407,9 @@ func TestUnconfirmedTxs(t *testing.T) { func TestNumUnconfirmedTxs(t *testing.T) { _, _, tx := MakeTxKV() - ch := make(chan *abci.Response, 1) + ch := make(chan *abci.ResponseCheckTx, 1) mempool := node.Mempool() - err := mempool.CheckTx(tx, func(resp *abci.Response) { ch <- resp }, mempl.TxInfo{}) + err := mempool.CheckTx(tx, func(resp *abci.ResponseCheckTx) { ch <- resp }, mempl.TxInfo{}) require.NoError(t, err) // wait for tx to arrive in mempoool. diff --git a/rpc/core/abci.go b/rpc/core/abci.go index d1f7193be..a3a46df6e 100644 --- a/rpc/core/abci.go +++ b/rpc/core/abci.go @@ -1,6 +1,8 @@ package core import ( + "context" + abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/libs/bytes" "github.com/tendermint/tendermint/proxy" @@ -17,7 +19,7 @@ func ABCIQuery( height int64, prove bool, ) (*ctypes.ResultABCIQuery, error) { - resQuery, err := env.ProxyAppQuery.QuerySync(abci.RequestQuery{ + resQuery, err := env.ProxyAppQuery.Query(context.TODO(), &abci.RequestQuery{ Path: path, Data: data, Height: height, @@ -33,7 +35,7 @@ func ABCIQuery( // ABCIInfo gets some info about the application. // More: https://docs.tendermint.com/main/rpc/#/ABCI/abci_info func ABCIInfo(ctx *rpctypes.Context) (*ctypes.ResultABCIInfo, error) { - resInfo, err := env.ProxyAppQuery.InfoSync(proxy.RequestInfo) + resInfo, err := env.ProxyAppQuery.Info(context.TODO(), proxy.RequestInfo) if err != nil { return nil, err } diff --git a/rpc/core/blocks.go b/rpc/core/blocks.go index 5d277218f..08568f5fb 100644 --- a/rpc/core/blocks.go +++ b/rpc/core/blocks.go @@ -177,23 +177,22 @@ func BlockResults(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultBlockR return nil, err } - results, err := env.StateStore.LoadABCIResponses(height) + results, err := env.StateStore.LoadFinalizeBlockResponse(height) if err != nil { return nil, err } return &ctypes.ResultBlockResults{ Height: height, - TxsResults: results.DeliverTxs, - BeginBlockEvents: results.BeginBlock.Events, - EndBlockEvents: results.EndBlock.Events, - ValidatorUpdates: results.EndBlock.ValidatorUpdates, - ConsensusParamUpdates: results.EndBlock.ConsensusParamUpdates, + TxsResults: results.TxResults, + FinalizeBlockEvents: results.Events, + ValidatorUpdates: results.ValidatorUpdates, + ConsensusParamUpdates: results.ConsensusParamUpdates, }, nil } -// BlockSearch searches for a paginated set of blocks matching BeginBlock and -// EndBlock event search criteria. +// BlockSearch searches for a paginated set of blocks matching +// FinalizeBlock event search criteria. func BlockSearch( ctx *rpctypes.Context, query string, diff --git a/rpc/core/blocks_test.go b/rpc/core/blocks_test.go index 71311076c..8256920d9 100644 --- a/rpc/core/blocks_test.go +++ b/rpc/core/blocks_test.go @@ -10,7 +10,6 @@ import ( dbm "github.com/tendermint/tm-db" abci "github.com/tendermint/tendermint/abci/types" - tmstate "github.com/tendermint/tendermint/proto/tendermint/state" ctypes "github.com/tendermint/tendermint/rpc/core/types" rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types" sm "github.com/tendermint/tendermint/state" @@ -70,21 +69,19 @@ func TestBlockchainInfo(t *testing.T) { } func TestBlockResults(t *testing.T) { - results := &tmstate.ABCIResponses{ - DeliverTxs: []*abci.ResponseDeliverTx{ + results := &abci.ResponseFinalizeBlock{ + TxResults: []*abci.ExecTxResult{ {Code: 0, Data: []byte{0x01}, Log: "ok"}, {Code: 0, Data: []byte{0x02}, Log: "ok"}, {Code: 1, Log: "not ok"}, }, - EndBlock: &abci.ResponseEndBlock{}, - BeginBlock: &abci.ResponseBeginBlock{}, } env = &Environment{} env.StateStore = sm.NewStore(dbm.NewMemDB(), sm.StoreOptions{ DiscardABCIResponses: false, }) - err := env.StateStore.SaveABCIResponses(100, results) + err := env.StateStore.SaveFinalizeBlockResponse(100, results) require.NoError(t, err) mockstore := &mocks.BlockStore{} mockstore.On("Height").Return(int64(100)) @@ -101,11 +98,10 @@ func TestBlockResults(t *testing.T) { {101, true, nil}, {100, false, &ctypes.ResultBlockResults{ Height: 100, - TxsResults: results.DeliverTxs, - BeginBlockEvents: results.BeginBlock.Events, - EndBlockEvents: results.EndBlock.Events, - ValidatorUpdates: results.EndBlock.ValidatorUpdates, - ConsensusParamUpdates: results.EndBlock.ConsensusParamUpdates, + TxsResults: results.TxResults, + FinalizeBlockEvents: results.Events, + ValidatorUpdates: results.ValidatorUpdates, + ConsensusParamUpdates: results.ConsensusParamUpdates, }}, } diff --git a/rpc/core/mempool.go b/rpc/core/mempool.go index 69b87dd5c..8c6683ff1 100644 --- a/rpc/core/mempool.go +++ b/rpc/core/mempool.go @@ -17,7 +17,7 @@ import ( // NOTE: tx should be signed, but this is only checked at the app level (not by Tendermint!) // BroadcastTxAsync returns right away, with no response. Does not wait for -// CheckTx nor DeliverTx results. +// CheckTx nor transcation results. // More: https://docs.tendermint.com/main/rpc/#/Tx/broadcast_tx_async func BroadcastTxAsync(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) { err := env.Mempool.CheckTx(tx, nil, mempl.TxInfo{}) @@ -29,11 +29,11 @@ func BroadcastTxAsync(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadca } // BroadcastTxSync returns with the response from CheckTx. Does not wait for -// DeliverTx result. +// the transaction result. // More: https://docs.tendermint.com/main/rpc/#/Tx/broadcast_tx_sync func BroadcastTxSync(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) { - resCh := make(chan *abci.Response, 1) - err := env.Mempool.CheckTx(tx, func(res *abci.Response) { + resCh := make(chan *abci.ResponseCheckTx, 1) + err := env.Mempool.CheckTx(tx, func(res *abci.ResponseCheckTx) { select { case <-ctx.Context().Done(): case resCh <- res: @@ -48,18 +48,17 @@ func BroadcastTxSync(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcas case <-ctx.Context().Done(): return nil, fmt.Errorf("broadcast confirmation not received: %w", ctx.Context().Err()) case res := <-resCh: - r := res.GetCheckTx() return &ctypes.ResultBroadcastTx{ - Code: r.Code, - Data: r.Data, - Log: r.Log, - Codespace: r.Codespace, + Code: res.Code, + Data: res.Data, + Log: res.Log, + Codespace: res.Codespace, Hash: tx.Hash(), }, nil } } -// BroadcastTxCommit returns with the responses from CheckTx and DeliverTx. +// BroadcastTxCommit returns with the responses from CheckTx and ExecTxResult. // More: https://docs.tendermint.com/main/rpc/#/Tx/broadcast_tx_commit func BroadcastTxCommit(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) { subscriber := ctx.RemoteAddr() @@ -74,7 +73,7 @@ func BroadcastTxCommit(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadc subCtx, cancel := context.WithTimeout(ctx.Context(), SubscribeTimeout) defer cancel() q := types.EventQueryTxFor(tx) - deliverTxSub, err := env.EventBus.Subscribe(subCtx, subscriber, q) + txSub, err := env.EventBus.Subscribe(subCtx, subscriber, q) if err != nil { err = fmt.Errorf("failed to subscribe to tx: %w", err) env.Logger.Error("Error on broadcast_tx_commit", "err", err) @@ -87,8 +86,8 @@ func BroadcastTxCommit(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadc }() // Broadcast tx and wait for CheckTx result - checkTxResCh := make(chan *abci.Response, 1) - err = env.Mempool.CheckTx(tx, func(res *abci.Response) { + checkTxResCh := make(chan *abci.ResponseCheckTx, 1) + err = env.Mempool.CheckTx(tx, func(res *abci.ResponseCheckTx) { select { case <-ctx.Context().Done(): case checkTxResCh <- res: @@ -101,47 +100,46 @@ func BroadcastTxCommit(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadc select { case <-ctx.Context().Done(): return nil, fmt.Errorf("broadcast confirmation not received: %w", ctx.Context().Err()) - case checkTxResMsg := <-checkTxResCh: - checkTxRes := checkTxResMsg.GetCheckTx() + case checkTxRes := <-checkTxResCh: if checkTxRes.Code != abci.CodeTypeOK { return &ctypes.ResultBroadcastTxCommit{ - CheckTx: *checkTxRes, - DeliverTx: abci.ResponseDeliverTx{}, - Hash: tx.Hash(), + CheckTx: *checkTxRes, + TxResult: abci.ExecTxResult{}, + Hash: tx.Hash(), }, nil } // Wait for the tx to be included in a block or timeout. select { - case msg := <-deliverTxSub.Out(): // The tx was included in a block. - deliverTxRes := msg.Data().(types.EventDataTx) + case msg := <-txSub.Out(): // The tx was included in a block. + txResultEvent := msg.Data().(types.EventDataTx) return &ctypes.ResultBroadcastTxCommit{ - CheckTx: *checkTxRes, - DeliverTx: deliverTxRes.Result, - Hash: tx.Hash(), - Height: deliverTxRes.Height, + CheckTx: *checkTxRes, + TxResult: txResultEvent.Result, + Hash: tx.Hash(), + Height: txResultEvent.Height, }, nil - case <-deliverTxSub.Cancelled(): + case <-txSub.Cancelled(): var reason string - if deliverTxSub.Err() == nil { + if txSub.Err() == nil { reason = "Tendermint exited" } else { - reason = deliverTxSub.Err().Error() + reason = txSub.Err().Error() } - err = fmt.Errorf("deliverTxSub was canceled (reason: %s)", reason) + err = fmt.Errorf("txSub was canceled (reason: %s)", reason) env.Logger.Error("Error on broadcastTxCommit", "err", err) return &ctypes.ResultBroadcastTxCommit{ - CheckTx: *checkTxRes, - DeliverTx: abci.ResponseDeliverTx{}, - Hash: tx.Hash(), + CheckTx: *checkTxRes, + TxResult: abci.ExecTxResult{}, + Hash: tx.Hash(), }, err case <-time.After(env.Config.TimeoutBroadcastTxCommit): err = errors.New("timed out waiting for tx to be included in a block") env.Logger.Error("Error on broadcastTxCommit", "err", err) return &ctypes.ResultBroadcastTxCommit{ - CheckTx: *checkTxRes, - DeliverTx: abci.ResponseDeliverTx{}, - Hash: tx.Hash(), + CheckTx: *checkTxRes, + TxResult: abci.ExecTxResult{}, + Hash: tx.Hash(), }, err } } @@ -175,7 +173,7 @@ func NumUnconfirmedTxs(ctx *rpctypes.Context) (*ctypes.ResultUnconfirmedTxs, err // be added to the mempool either. // More: https://docs.tendermint.com/main/rpc/#/Tx/check_tx func CheckTx(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultCheckTx, error) { - res, err := env.ProxyAppMempool.CheckTxSync(abci.RequestCheckTx{Tx: tx}) + res, err := env.ProxyAppMempool.CheckTx(context.TODO(), &abci.RequestCheckTx{Tx: tx}) if err != nil { return nil, err } diff --git a/rpc/core/types/responses.go b/rpc/core/types/responses.go index 6da818890..e63271bd0 100644 --- a/rpc/core/types/responses.go +++ b/rpc/core/types/responses.go @@ -52,12 +52,12 @@ type ResultCommit struct { // ABCI results from a block type ResultBlockResults struct { - Height int64 `json:"height"` - TxsResults []*abci.ResponseDeliverTx `json:"txs_results"` - BeginBlockEvents []abci.Event `json:"begin_block_events"` - EndBlockEvents []abci.Event `json:"end_block_events"` - ValidatorUpdates []abci.ValidatorUpdate `json:"validator_updates"` - ConsensusParamUpdates *tmproto.ConsensusParams `json:"consensus_param_updates"` + Height int64 `json:"height"` + TxsResults []*abci.ExecTxResult `json:"txs_results"` + FinalizeBlockEvents []abci.Event `json:"finalize_block_events"` + ValidatorUpdates []abci.ValidatorUpdate `json:"validator_updates"` + ConsensusParamUpdates *tmproto.ConsensusParams `json:"consensus_param_updates"` + AgreedAppData []byte `json:"agreed_app_data"` } // NewResultCommit is a helper to initialize the ResultCommit with @@ -181,12 +181,12 @@ type ResultBroadcastTx struct { Hash bytes.HexBytes `json:"hash"` } -// CheckTx and DeliverTx results +// CheckTx and ExecTx results type ResultBroadcastTxCommit struct { - CheckTx abci.ResponseCheckTx `json:"check_tx"` - DeliverTx abci.ResponseDeliverTx `json:"deliver_tx"` - Hash bytes.HexBytes `json:"hash"` - Height int64 `json:"height"` + CheckTx abci.ResponseCheckTx `json:"check_tx"` + TxResult abci.ExecTxResult `json:"tx_result"` + Hash bytes.HexBytes `json:"hash"` + Height int64 `json:"height"` } // ResultCheckTx wraps abci.ResponseCheckTx. @@ -196,12 +196,12 @@ type ResultCheckTx struct { // Result of querying for a tx type ResultTx struct { - Hash bytes.HexBytes `json:"hash"` - Height int64 `json:"height"` - Index uint32 `json:"index"` - TxResult abci.ResponseDeliverTx `json:"tx_result"` - Tx types.Tx `json:"tx"` - Proof types.TxProof `json:"proof,omitempty"` + Hash bytes.HexBytes `json:"hash"` + Height int64 `json:"height"` + Index uint32 `json:"index"` + TxResult abci.ExecTxResult `json:"tx_result"` + Tx types.Tx `json:"tx"` + Proof types.TxProof `json:"proof,omitempty"` } // Result of searching for txs diff --git a/rpc/grpc/api.go b/rpc/grpc/api.go index 62c6b66c1..59f8dd5c9 100644 --- a/rpc/grpc/api.go +++ b/rpc/grpc/api.go @@ -30,10 +30,10 @@ func (bapi *broadcastAPI) BroadcastTx(ctx context.Context, req *RequestBroadcast Data: res.CheckTx.Data, Log: res.CheckTx.Log, }, - DeliverTx: &abci.ResponseDeliverTx{ - Code: res.DeliverTx.Code, - Data: res.DeliverTx.Data, - Log: res.DeliverTx.Log, + TxResult: &abci.ExecTxResult{ + Code: res.TxResult.Code, + Data: res.TxResult.Data, + Log: res.TxResult.Log, }, }, nil } diff --git a/rpc/grpc/grpc_test.go b/rpc/grpc/grpc_test.go index 5049d06c2..ecc3494cc 100644 --- a/rpc/grpc/grpc_test.go +++ b/rpc/grpc/grpc_test.go @@ -14,7 +14,7 @@ import ( func TestMain(m *testing.M) { // start a tendermint node in the background to test against - app := kvstore.NewApplication() + app := kvstore.NewInMemoryApplication() node := rpctest.StartTendermint(app) code := m.Run() @@ -27,9 +27,9 @@ func TestMain(m *testing.M) { func TestBroadcastTx(t *testing.T) { res, err := rpctest.GetGRPCClient().BroadcastTx( context.Background(), - &core_grpc.RequestBroadcastTx{Tx: []byte("this is a tx")}, + &core_grpc.RequestBroadcastTx{Tx: kvstore.NewTx("hello", "world")}, ) require.NoError(t, err) require.EqualValues(t, 0, res.CheckTx.Code) - require.EqualValues(t, 0, res.DeliverTx.Code) + require.EqualValues(t, 0, res.TxResult.Code) } diff --git a/rpc/grpc/types.pb.go b/rpc/grpc/types.pb.go index 6d0fecf0b..4496379b9 100644 --- a/rpc/grpc/types.pb.go +++ b/rpc/grpc/types.pb.go @@ -145,8 +145,8 @@ func (m *ResponsePing) XXX_DiscardUnknown() { var xxx_messageInfo_ResponsePing proto.InternalMessageInfo type ResponseBroadcastTx struct { - CheckTx *types.ResponseCheckTx `protobuf:"bytes,1,opt,name=check_tx,json=checkTx,proto3" json:"check_tx,omitempty"` - DeliverTx *types.ResponseDeliverTx `protobuf:"bytes,2,opt,name=deliver_tx,json=deliverTx,proto3" json:"deliver_tx,omitempty"` + CheckTx *types.ResponseCheckTx `protobuf:"bytes,1,opt,name=check_tx,json=checkTx,proto3" json:"check_tx,omitempty"` + TxResult *types.ExecTxResult `protobuf:"bytes,2,opt,name=tx_result,json=txResult,proto3" json:"tx_result,omitempty"` } func (m *ResponseBroadcastTx) Reset() { *m = ResponseBroadcastTx{} } @@ -189,9 +189,9 @@ func (m *ResponseBroadcastTx) GetCheckTx() *types.ResponseCheckTx { return nil } -func (m *ResponseBroadcastTx) GetDeliverTx() *types.ResponseDeliverTx { +func (m *ResponseBroadcastTx) GetTxResult() *types.ExecTxResult { if m != nil { - return m.DeliverTx + return m.TxResult } return nil } @@ -206,7 +206,7 @@ func init() { func init() { proto.RegisterFile("tendermint/rpc/grpc/types.proto", fileDescriptor_0ffff5682c662b95) } var fileDescriptor_0ffff5682c662b95 = []byte{ - // 316 bytes of a gzipped FileDescriptorProto + // 320 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x2f, 0x49, 0xcd, 0x4b, 0x49, 0x2d, 0xca, 0xcd, 0xcc, 0x2b, 0xd1, 0x2f, 0x2a, 0x48, 0xd6, 0x4f, 0x07, 0x11, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0xc2, 0x08, 0x05, 0x7a, 0x45, 0x05, @@ -214,19 +214,19 @@ var fileDescriptor_0ffff5682c662b95 = []byte{ 0x72, 0x71, 0x07, 0xa5, 0x16, 0x96, 0xa6, 0x16, 0x97, 0x04, 0x64, 0xe6, 0xa5, 0x2b, 0xa9, 0x70, 0x09, 0x41, 0xb9, 0x4e, 0x45, 0xf9, 0x89, 0x29, 0xc9, 0x89, 0xc5, 0x25, 0x21, 0x15, 0x42, 0x7c, 0x5c, 0x4c, 0x25, 0x15, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x3c, 0x41, 0x4c, 0x25, 0x15, 0x4a, 0x7c, - 0x5c, 0x3c, 0x41, 0xa9, 0xc5, 0x05, 0xf9, 0x79, 0xc5, 0xa9, 0x60, 0x5d, 0x53, 0x19, 0xb9, 0x84, - 0x61, 0x02, 0xc8, 0xfa, 0xac, 0xb9, 0x38, 0x92, 0x33, 0x52, 0x93, 0xb3, 0xe3, 0xa1, 0xba, 0xb9, - 0x8d, 0x14, 0xf4, 0x90, 0x5c, 0x08, 0x72, 0x8c, 0x1e, 0x4c, 0x9f, 0x33, 0x48, 0x61, 0x48, 0x45, - 0x10, 0x7b, 0x32, 0x84, 0x21, 0xe4, 0xc8, 0xc5, 0x95, 0x92, 0x9a, 0x93, 0x59, 0x96, 0x5a, 0x04, - 0xd2, 0xce, 0x04, 0xd6, 0xae, 0x84, 0x53, 0xbb, 0x0b, 0x44, 0x69, 0x48, 0x45, 0x10, 0x67, 0x0a, - 0x8c, 0x69, 0xb4, 0x97, 0x91, 0x8b, 0x07, 0xee, 0x1e, 0xc7, 0x00, 0x4f, 0x21, 0x6f, 0x2e, 0x16, - 0x90, 0x83, 0x85, 0x50, 0x9c, 0x01, 0x0b, 0x28, 0x3d, 0xa4, 0x80, 0x90, 0x52, 0xc4, 0xa1, 0x02, - 0xe1, 0x6b, 0xa1, 0x04, 0x2e, 0x6e, 0x64, 0xcf, 0xaa, 0xe3, 0x33, 0x13, 0x49, 0xa1, 0x94, 0x06, - 0x5e, 0xa3, 0x91, 0x54, 0x3a, 0xf9, 0x9c, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, - 0x47, 0x72, 0x8c, 0x13, 0x1e, 0xcb, 0x31, 0x5c, 0x78, 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, 0x43, - 0x94, 0x51, 0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0xae, 0x3e, 0x52, 0xf4, 0x62, - 0x49, 0x1f, 0xd6, 0xc9, 0xf9, 0x45, 0xa9, 0x20, 0x46, 0x12, 0x1b, 0x38, 0xc6, 0x8d, 0x01, 0x01, - 0x00, 0x00, 0xff, 0xff, 0xf6, 0x4b, 0x02, 0xd8, 0x46, 0x02, 0x00, 0x00, + 0x5c, 0x3c, 0x41, 0xa9, 0xc5, 0x05, 0xf9, 0x79, 0xc5, 0xa9, 0x60, 0x5d, 0x7d, 0x8c, 0x5c, 0xc2, + 0x30, 0x01, 0x64, 0x7d, 0xd6, 0x5c, 0x1c, 0xc9, 0x19, 0xa9, 0xc9, 0xd9, 0xf1, 0x50, 0xdd, 0xdc, + 0x46, 0x0a, 0x7a, 0x48, 0x2e, 0x04, 0x39, 0x46, 0x0f, 0xa6, 0xcf, 0x19, 0xa4, 0x30, 0xa4, 0x22, + 0x88, 0x3d, 0x19, 0xc2, 0x10, 0xb2, 0xe2, 0xe2, 0x2c, 0xa9, 0x88, 0x2f, 0x4a, 0x2d, 0x2e, 0xcd, + 0x29, 0x91, 0x60, 0x02, 0xeb, 0x96, 0xc5, 0xd0, 0xed, 0x5a, 0x91, 0x9a, 0x1c, 0x52, 0x11, 0x04, + 0x56, 0x14, 0xc4, 0x51, 0x02, 0x65, 0x19, 0xed, 0x65, 0xe4, 0xe2, 0x81, 0x3b, 0xc4, 0x31, 0xc0, + 0x53, 0xc8, 0x9b, 0x8b, 0x05, 0xe4, 0x52, 0x21, 0x14, 0xfb, 0x61, 0x21, 0xa4, 0x87, 0x14, 0x02, + 0x52, 0x8a, 0x38, 0x54, 0x20, 0xbc, 0x2b, 0x94, 0xc0, 0xc5, 0x8d, 0xec, 0x4b, 0x75, 0x7c, 0x66, + 0x22, 0x29, 0x94, 0xd2, 0xc0, 0x6b, 0x34, 0x92, 0x4a, 0x27, 0x9f, 0x13, 0x8f, 0xe4, 0x18, 0x2f, + 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, + 0x6e, 0x3c, 0x96, 0x63, 0x88, 0x32, 0x4a, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, + 0xd5, 0x47, 0x8a, 0x57, 0x2c, 0x09, 0xc3, 0x3a, 0x39, 0xbf, 0x28, 0x15, 0xc4, 0x48, 0x62, 0x03, + 0x47, 0xb5, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0xdc, 0x93, 0xa5, 0x24, 0x3f, 0x02, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -441,9 +441,9 @@ func (m *ResponseBroadcastTx) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.DeliverTx != nil { + if m.TxResult != nil { { - size, err := m.DeliverTx.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.TxResult.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -520,8 +520,8 @@ func (m *ResponseBroadcastTx) Size() (n int) { l = m.CheckTx.Size() n += 1 + l + sovTypes(uint64(l)) } - if m.DeliverTx != nil { - l = m.DeliverTx.Size() + if m.TxResult != nil { + l = m.TxResult.Size() n += 1 + l + sovTypes(uint64(l)) } return n @@ -784,7 +784,7 @@ func (m *ResponseBroadcastTx) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DeliverTx", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field TxResult", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -811,10 +811,10 @@ func (m *ResponseBroadcastTx) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.DeliverTx == nil { - m.DeliverTx = &types.ResponseDeliverTx{} + if m.TxResult == nil { + m.TxResult = &types.ExecTxResult{} } - if err := m.DeliverTx.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.TxResult.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/state/errors.go b/state/errors.go index 38c581f7d..f9e74336e 100644 --- a/state/errors.go +++ b/state/errors.go @@ -103,4 +103,4 @@ func (e ErrNoABCIResponsesForHeight) Error() string { return fmt.Sprintf("could not find results for height #%d", e.Height) } -var ErrABCIResponsesNotPersisted = errors.New("node is not persisting abci responses") +var ErrFinalizeBlockResponsesNotPersisted = errors.New("node is not persisting finalize block responses") diff --git a/state/execution.go b/state/execution.go index 234d81c0f..8ef696975 100644 --- a/state/execution.go +++ b/state/execution.go @@ -1,7 +1,7 @@ package state import ( - "errors" + "context" "fmt" "time" @@ -10,7 +10,6 @@ import ( "github.com/tendermint/tendermint/libs/fail" "github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/mempool" - tmstate "github.com/tendermint/tendermint/proto/tendermint/state" "github.com/tendermint/tendermint/proxy" "github.com/tendermint/tendermint/types" ) @@ -117,8 +116,8 @@ func (blockExec *BlockExecutor) CreateProposalBlock( block := state.MakeBlock(height, txs, commit, evidence, proposerAddr) localLastCommit := buildLastCommitInfo(block, blockExec.store, state.InitialHeight) - rpp, err := blockExec.proxyApp.PrepareProposalSync( - abci.RequestPrepareProposal{ + rpp, err := blockExec.proxyApp.PrepareProposal(context.TODO(), + &abci.RequestPrepareProposal{ MaxTxBytes: maxDataBytes, Txs: block.Txs.ToSliceOfBytes(), LocalLastCommit: extendedCommitInfo(localLastCommit, votes), @@ -153,7 +152,7 @@ func (blockExec *BlockExecutor) ProcessProposal( block *types.Block, state State, ) (bool, error) { - resp, err := blockExec.proxyApp.ProcessProposalSync(abci.RequestProcessProposal{ + resp, err := blockExec.proxyApp.ProcessProposal(context.TODO(), &abci.RequestProcessProposal{ Hash: block.Header.Hash(), Height: block.Header.Height, Time: block.Header.Time, @@ -199,33 +198,48 @@ func (blockExec *BlockExecutor) ApplyBlock( return state, ErrInvalidBlock(err) } + commitInfo := buildLastCommitInfo(block, blockExec.store, state.InitialHeight) + startTime := time.Now().UnixNano() - abciResponses, err := execBlockOnProxyApp( - blockExec.logger, blockExec.proxyApp, block, blockExec.store, state.InitialHeight, - ) + abciResponse, err := blockExec.proxyApp.FinalizeBlock(context.TODO(), &abci.RequestFinalizeBlock{ + Hash: block.Hash(), + NextValidatorsHash: block.NextValidatorsHash, + ProposerAddress: block.ProposerAddress, + Height: block.Height, + DecidedLastCommit: commitInfo, + Misbehavior: block.Evidence.Evidence.ToABCI(), + Txs: block.Txs.ToSliceOfBytes(), + }) endTime := time.Now().UnixNano() blockExec.metrics.BlockProcessingTime.Observe(float64(endTime-startTime) / 1000000) if err != nil { - return state, ErrProxyAppConn(err) + blockExec.logger.Error("error in proxyAppConn.FinalizeBlock", "err", err) + return state, err } + // Assert that the application correctly returned tx results for each of the transactions provided in the block + if len(block.Data.Txs) != len(abciResponse.TxResults) { + return state, fmt.Errorf("expected tx results length to match size of transactions in block. Expected %d, got %d", len(block.Data.Txs), len(abciResponse.TxResults)) + } + + blockExec.logger.Info("executed block", "height", block.Height, "agreed_app_data", abciResponse.AgreedAppData) + fail.Fail() // XXX // Save the results before we commit. - if err := blockExec.store.SaveABCIResponses(block.Height, abciResponses); err != nil { + if err := blockExec.store.SaveFinalizeBlockResponse(block.Height, abciResponse); err != nil { return state, err } fail.Fail() // XXX // validate the validator updates and convert to tendermint types - abciValUpdates := abciResponses.EndBlock.ValidatorUpdates - err = validateValidatorUpdates(abciValUpdates, state.ConsensusParams.Validator) + err = validateValidatorUpdates(abciResponse.ValidatorUpdates, state.ConsensusParams.Validator) if err != nil { return state, fmt.Errorf("error in validator updates: %v", err) } - validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciValUpdates) + validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponse.ValidatorUpdates) if err != nil { return state, err } @@ -233,18 +247,18 @@ func (blockExec *BlockExecutor) ApplyBlock( blockExec.logger.Debug("updates to validators", "updates", types.ValidatorListString(validatorUpdates)) blockExec.metrics.ValidatorSetUpdates.Add(1) } - if abciResponses.EndBlock.ConsensusParamUpdates != nil { + if abciResponse.ConsensusParamUpdates != nil { blockExec.metrics.ConsensusParamUpdates.Add(1) } // Update the state with the block and responses. - state, err = updateState(state, blockID, &block.Header, abciResponses, validatorUpdates) + state, err = updateState(state, blockID, &block.Header, abciResponse, validatorUpdates) if err != nil { return state, fmt.Errorf("commit failed for application: %v", err) } // Lock mempool, commit app state, update mempoool. - appHash, retainHeight, err := blockExec.Commit(state, block, abciResponses.DeliverTxs) + retainHeight, err := blockExec.Commit(state, block, abciResponse) if err != nil { return state, fmt.Errorf("commit failed for application: %v", err) } @@ -255,7 +269,7 @@ func (blockExec *BlockExecutor) ApplyBlock( fail.Fail() // XXX // Update the app hash and save the state. - state.AppHash = appHash + state.AppHash = abciResponse.AgreedAppData if err := blockExec.store.Save(state); err != nil { return state, err } @@ -274,7 +288,7 @@ func (blockExec *BlockExecutor) ApplyBlock( // Events are fired after everything else. // NOTE: if we crash between Commit and Save, events wont be fired during replay - fireEvents(blockExec.logger, blockExec.eventBus, block, abciResponses, validatorUpdates) + fireEvents(blockExec.logger, blockExec.eventBus, block, blockID, abciResponse, validatorUpdates) return state, nil } @@ -288,8 +302,8 @@ func (blockExec *BlockExecutor) ApplyBlock( func (blockExec *BlockExecutor) Commit( state State, block *types.Block, - deliverTxResponses []*abci.ResponseDeliverTx, -) ([]byte, int64, error) { + abciResponse *abci.ResponseFinalizeBlock, +) (int64, error) { blockExec.mempool.Lock() defer blockExec.mempool.Unlock() @@ -298,114 +312,37 @@ func (blockExec *BlockExecutor) Commit( err := blockExec.mempool.FlushAppConn() if err != nil { blockExec.logger.Error("client error during mempool.FlushAppConn", "err", err) - return nil, 0, err + return 0, err } // Commit block, get hash back - res, err := blockExec.proxyApp.CommitSync() + res, err := blockExec.proxyApp.Commit(context.TODO()) if err != nil { blockExec.logger.Error("client error during proxyAppConn.CommitSync", "err", err) - return nil, 0, err + return 0, err } // ResponseCommit has no error code - just data blockExec.logger.Info( "committed state", "height", block.Height, - "num_txs", len(block.Txs), - "app_hash", fmt.Sprintf("%X", res.Data), ) // Update mempool. err = blockExec.mempool.Update( block.Height, block.Txs, - deliverTxResponses, + abciResponse.TxResults, TxPreCheck(state), TxPostCheck(state), ) - return res.Data, res.RetainHeight, err + return res.RetainHeight, err } //--------------------------------------------------------- // Helper functions for executing blocks and updating state -// Executes block's transactions on proxyAppConn. -// Returns a list of transaction results and updates to the validator set -func execBlockOnProxyApp( - logger log.Logger, - proxyAppConn proxy.AppConnConsensus, - block *types.Block, - store Store, - initialHeight int64, -) (*tmstate.ABCIResponses, error) { - var validTxs, invalidTxs = 0, 0 - - txIndex := 0 - abciResponses := new(tmstate.ABCIResponses) - 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 := buildLastCommitInfo(block, store, initialHeight) - - // Begin block - var err error - pbh := block.Header.ToProto() - if pbh == nil { - return nil, errors.New("nil header") - } - - abciResponses.BeginBlock, err = proxyAppConn.BeginBlockSync(abci.RequestBeginBlock{ - Hash: block.Hash(), - Header: *pbh, - LastCommitInfo: commitInfo, - ByzantineValidators: block.Evidence.Evidence.ToABCI(), - }) - if err != nil { - logger.Error("error in proxyAppConn.BeginBlock", "err", err) - return nil, err - } - - // run txs of block - for _, tx := range block.Txs { - proxyAppConn.DeliverTxAsync(abci.RequestDeliverTx{Tx: tx}) - if err := proxyAppConn.Error(); err != nil { - return nil, err - } - } - - // End block. - abciResponses.EndBlock, err = proxyAppConn.EndBlockSync(abci.RequestEndBlock{Height: block.Height}) - if err != nil { - logger.Error("error in proxyAppConn.EndBlock", "err", err) - return nil, err - } - - logger.Info("executed block", "height", block.Height, "num_valid_txs", validTxs, "num_invalid_txs", invalidTxs) - return abciResponses, nil -} - func buildLastCommitInfo(block *types.Block, store Store, initialHeight int64) abci.CommitInfo { if block.Height == initialHeight { // there is no last commit for the initial height. @@ -495,7 +432,7 @@ func updateState( state State, blockID types.BlockID, header *types.Header, - abciResponses *tmstate.ABCIResponses, + abciResponse *abci.ResponseFinalizeBlock, validatorUpdates []*types.Validator, ) (State, error) { @@ -503,7 +440,7 @@ func updateState( // and update s.LastValidators and s.Validators. nValSet := state.NextValidators.Copy() - // Update the validator set with the latest abciResponses. + // Update the validator set with the latest abciResponse. lastHeightValsChanged := state.LastHeightValidatorsChanged if len(validatorUpdates) > 0 { err := nValSet.UpdateWithChangeSet(validatorUpdates) @@ -517,12 +454,12 @@ func updateState( // Update validator proposer priority and set state variables. nValSet.IncrementProposerPriority(1) - // Update the params with the latest abciResponses. + // Update the params with the latest abciResponse. nextParams := state.ConsensusParams lastHeightParamsChanged := state.LastHeightConsensusParamsChanged - if abciResponses.EndBlock.ConsensusParamUpdates != nil { + if abciResponse.ConsensusParamUpdates != nil { // NOTE: must not mutate s.ConsensusParams - nextParams = state.ConsensusParams.Update(abciResponses.EndBlock.ConsensusParamUpdates) + nextParams = state.ConsensusParams.Update(abciResponse.ConsensusParamUpdates) err := nextParams.ValidateBasic() if err != nil { return state, fmt.Errorf("error updating consensus params: %v", err) @@ -551,7 +488,7 @@ func updateState( LastHeightValidatorsChanged: lastHeightValsChanged, ConsensusParams: nextParams, LastHeightConsensusParamsChanged: lastHeightParamsChanged, - LastResultsHash: ABCIResponsesResultsHash(abciResponses), + LastResultsHash: TxResultsHash(abciResponse.TxResults), AppHash: nil, }, nil } @@ -563,26 +500,32 @@ func fireEvents( logger log.Logger, eventBus types.BlockEventPublisher, block *types.Block, - abciResponses *tmstate.ABCIResponses, + blockID types.BlockID, + abciResponse *abci.ResponseFinalizeBlock, validatorUpdates []*types.Validator, ) { if err := eventBus.PublishEventNewBlock(types.EventDataNewBlock{ - Block: block, - ResultBeginBlock: *abciResponses.BeginBlock, - ResultEndBlock: *abciResponses.EndBlock, + Block: block, + BlockID: blockID, + ResultFinalizeBlock: *abciResponse, }); err != nil { logger.Error("failed publishing new block", "err", err) } if err := eventBus.PublishEventNewBlockHeader(types.EventDataNewBlockHeader{ - Header: block.Header, - NumTxs: int64(len(block.Txs)), - ResultBeginBlock: *abciResponses.BeginBlock, - ResultEndBlock: *abciResponses.EndBlock, + Header: block.Header, }); err != nil { logger.Error("failed publishing new block header", "err", err) } + if err := eventBus.PublishEventNewBlockEvents(types.EventDataNewBlockEvents{ + Height: block.Height, + Events: abciResponse.Events, + NumTxs: int64(len(block.Txs)), + }); err != nil { + logger.Error("failed publishing new block events", "err", err) + } + if len(block.Evidence.Evidence) != 0 { for _, ev := range block.Evidence.Evidence { if err := eventBus.PublishEventNewEvidence(types.EventDataNewEvidence{ @@ -599,7 +542,7 @@ func fireEvents( Height: block.Height, Index: uint32(i), Tx: tx, - Result: *(abciResponses.DeliverTxs[i]), + Result: *(abciResponse.TxResults[i]), }}); err != nil { logger.Error("failed publishing event TX", "err", err) } @@ -625,21 +568,37 @@ func ExecCommitBlock( store Store, initialHeight int64, ) ([]byte, error) { - _, err := execBlockOnProxyApp(logger, appConnConsensus, block, store, initialHeight) + commitInfo := buildLastCommitInfo(block, store, initialHeight) + + resp, err := appConnConsensus.FinalizeBlock(context.TODO(), &abci.RequestFinalizeBlock{ + Hash: block.Hash(), + NextValidatorsHash: block.NextValidatorsHash, + ProposerAddress: block.ProposerAddress, + Height: block.Height, + DecidedLastCommit: commitInfo, + Misbehavior: block.Evidence.Evidence.ToABCI(), + Txs: block.Txs.ToSliceOfBytes(), + }) if err != nil { - logger.Error("failed executing block on proxy app", "height", block.Height, "err", err) + logger.Error("error in proxyAppConn.FinalizeBlock", "err", err) return nil, err } + // Assert that the application correctly returned tx results for each of the transactions provided in the block + if len(block.Data.Txs) != len(resp.TxResults) { + return nil, fmt.Errorf("expected tx results length to match size of transactions in block. Expected %d, got %d", len(block.Data.Txs), len(resp.TxResults)) + } + + logger.Info("executed block", "height", block.Height, "agreed_app_data", resp.AgreedAppData) + // Commit block, get hash back - res, err := appConnConsensus.CommitSync() + _, err = appConnConsensus.Commit(context.TODO()) if err != nil { - logger.Error("client error during proxyAppConn.CommitSync", "err", res) + logger.Error("client error during proxyAppConn.CommitSync", "err", err) return nil, err } - // ResponseCommit has no error or log, just data - return res.Data, nil + return resp.AgreedAppData, nil } func (blockExec *BlockExecutor) pruneBlocks(retainHeight int64, state State) (uint64, error) { diff --git a/state/execution_test.go b/state/execution_test.go index 3299413c9..3f5c40554 100644 --- a/state/execution_test.go +++ b/state/execution_test.go @@ -77,13 +77,90 @@ func TestApplyBlock(t *testing.T) { assert.EqualValues(t, 1, state.Version.Consensus.App, "App version wasn't updated") } -// TestBeginBlockValidators ensures we send absent validators list. -func TestBeginBlockValidators(t *testing.T) { +// TestFinalizeBlockDecidedLastCommit ensures we correctly send the +// DecidedLastCommit to the application. The test ensures that the +// DecidedLastCommit properly reflects which validators signed the preceding +// block. +func TestFinalizeBlockDecidedLastCommit(t *testing.T) { app := &testApp{} cc := proxy.NewLocalClientCreator(app) proxyApp := proxy.NewAppConns(cc, proxy.NopMetrics()) err := proxyApp.Start() - require.Nil(t, err) + require.NoError(t, err) + defer proxyApp.Stop() //nolint:errcheck // ignore for tests + + state, stateDB, privVals := makeState(7, 1) + stateStore := sm.NewStore(stateDB, sm.StoreOptions{ + DiscardABCIResponses: false, + }) + absentSig := types.NewCommitSigAbsent() + + testCases := []struct { + name string + absentCommitSigs map[int]bool + }{ + {"none absent", map[int]bool{}}, + {"one absent", map[int]bool{1: true}}, + {"multiple absent", map[int]bool{1: true, 3: true}}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + blockStore := store.NewBlockStore(dbm.NewMemDB()) + evpool := &mocks.EvidencePool{} + evpool.On("PendingEvidence", mock.Anything).Return([]types.Evidence{}, 0) + evpool.On("Update", mock.Anything, mock.Anything).Return() + evpool.On("CheckEvidence", mock.Anything).Return(nil) + mp := &mpmocks.Mempool{} + mp.On("Lock").Return() + mp.On("Unlock").Return() + mp.On("FlushAppConn", mock.Anything).Return(nil) + mp.On("Update", + mock.Anything, + mock.Anything, + mock.Anything, + mock.Anything, + mock.Anything, + mock.Anything, + mock.Anything).Return(nil) + + eventBus := types.NewEventBus() + require.NoError(t, eventBus.Start()) + + blockExec := sm.NewBlockExecutor(stateStore, log.NewNopLogger(), proxyApp.Consensus(), mp, evpool, blockStore) + state, _, lastCommit, err := makeAndCommitGoodBlock(state, 1, new(types.Commit), state.NextValidators.Validators[0].Address, blockExec, privVals, nil) + require.NoError(t, err) + + for idx, isAbsent := range tc.absentCommitSigs { + if isAbsent { + lastCommit.Signatures[idx] = absentSig + } + } + + // block for height 2 + block := makeBlock(state, 2, lastCommit) + bps, err := block.MakePartSet(testPartSize) + require.NoError(t, err) + blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()} + _, err = blockExec.ApplyBlock(state, blockID, block) + require.NoError(t, err) + + // -> app receives a list of validators with a bool indicating if they signed + for i, v := range app.CommitVotes { + _, absent := tc.absentCommitSigs[i] + assert.Equal(t, !absent, v.SignedLastBlock) + } + }) + } +} + +// TestFinalizeBlockValidators ensures we send absent validators list. +func TestFinalizeBlockValidators(t *testing.T) { + app := &testApp{} + cc := proxy.NewLocalClientCreator(app) + proxyApp := proxy.NewAppConns(cc, proxy.NopMetrics()) + err := proxyApp.Start() + require.NoError(t, err) defer proxyApp.Stop() //nolint:errcheck // no need to check error again state, stateDB, _ := makeState(2, 2) @@ -142,13 +219,13 @@ func TestBeginBlockValidators(t *testing.T) { } } -// TestBeginBlockByzantineValidators ensures we send byzantine validators list. -func TestBeginBlockByzantineValidators(t *testing.T) { +// TestFinalizeBlockMisbehavior ensures we send misbehavior list. +func TestFinalizeBlockMisbehavior(t *testing.T) { app := &testApp{} cc := proxy.NewLocalClientCreator(app) proxyApp := proxy.NewAppConns(cc, proxy.NopMetrics()) err := proxyApp.Start() - require.Nil(t, err) + require.NoError(t, err) defer proxyApp.Stop() //nolint:errcheck // ignore for tests state, stateDB, privVals := makeState(1, 1) @@ -247,8 +324,8 @@ func TestBeginBlockByzantineValidators(t *testing.T) { blockID = types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()} - state, err = blockExec.ApplyBlock(state, blockID, block) - require.Nil(t, err) + _, err = blockExec.ApplyBlock(state, blockID, block) + require.NoError(t, err) // TODO check state and mempool assert.Equal(t, abciMb, app.Misbehavior) @@ -259,8 +336,8 @@ func TestProcessProposal(t *testing.T) { txs := test.MakeNTxs(height, 10) logger := log.NewNopLogger() - app := abcimocks.NewBaseMock() - app.On("ProcessProposal", mock.Anything).Return(abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}) + app := &abcimocks.Application{} + app.On("ProcessProposal", mock.Anything, mock.Anything).Return(&abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}, nil) cc := proxy.NewLocalClientCreator(app) proxyApp := proxy.NewAppConns(cc, proxy.NopMetrics()) @@ -316,7 +393,7 @@ func TestProcessProposal(t *testing.T) { }) block1.Txs = txs - expectedRpp := abci.RequestProcessProposal{ + expectedRpp := &abci.RequestProcessProposal{ Txs: block1.Txs.ToSliceOfBytes(), Hash: block1.Hash(), Height: block1.Header.Height, @@ -334,7 +411,7 @@ func TestProcessProposal(t *testing.T) { require.NoError(t, err) require.True(t, acceptBlock) app.AssertExpectations(t) - app.AssertCalled(t, "ProcessProposal", expectedRpp) + app.AssertCalled(t, "ProcessProposal", context.TODO(), expectedRpp) } func TestValidateValidatorUpdates(t *testing.T) { @@ -467,13 +544,13 @@ func TestUpdateValidators(t *testing.T) { } } -// TestEndBlockValidatorUpdates ensures we update validator set and send an event. -func TestEndBlockValidatorUpdates(t *testing.T) { +// TestFinalizeBlockValidatorUpdates ensures we update validator set and send an event. +func TestFinalizeBlockValidatorUpdates(t *testing.T) { app := &testApp{} cc := proxy.NewLocalClientCreator(app) proxyApp := proxy.NewAppConns(cc, proxy.NopMetrics()) err := proxyApp.Start() - require.Nil(t, err) + require.NoError(t, err) defer proxyApp.Stop() //nolint:errcheck // ignore for tests state, stateDB, _ := makeState(1, 1) @@ -530,7 +607,7 @@ func TestEndBlockValidatorUpdates(t *testing.T) { } state, err = blockExec.ApplyBlock(state, blockID, block) - require.Nil(t, err) + require.NoError(t, err) // test new validator was added to NextValidators if assert.Equal(t, state.Validators.Size()+1, state.NextValidators.Size()) { idx, _ := state.NextValidators.GetByAddress(pubkey.Address()) @@ -555,14 +632,14 @@ func TestEndBlockValidatorUpdates(t *testing.T) { } } -// TestEndBlockValidatorUpdatesResultingInEmptySet checks that processing validator updates that +// TestFinalizeBlockValidatorUpdatesResultingInEmptySet checks that processing validator updates that // would result in empty set causes no panic, an error is raised and NextValidators is not updated -func TestEndBlockValidatorUpdatesResultingInEmptySet(t *testing.T) { +func TestFinalizeBlockValidatorUpdatesResultingInEmptySet(t *testing.T) { app := &testApp{} cc := proxy.NewLocalClientCreator(app) proxyApp := proxy.NewAppConns(cc, proxy.NopMetrics()) err := proxyApp.Start() - require.Nil(t, err) + require.NoError(t, err) defer proxyApp.Stop() //nolint:errcheck // ignore for tests state, stateDB, _ := makeState(1, 1) @@ -592,14 +669,14 @@ func TestEndBlockValidatorUpdatesResultingInEmptySet(t *testing.T) { } assert.NotPanics(t, func() { state, err = blockExec.ApplyBlock(state, blockID, block) }) - assert.NotNil(t, err) + assert.Error(t, err) assert.NotEmpty(t, state.NextValidators.Validators) } func TestEmptyPrepareProposal(t *testing.T) { const height = 2 - app := abcimocks.NewBaseMock() + app := &abci.BaseApplication{} cc := proxy.NewLocalClientCreator(app) proxyApp := proxy.NewAppConns(cc, proxy.NopMetrics()) err := proxyApp.Start() @@ -654,12 +731,12 @@ func TestPrepareProposalTxsAllIncluded(t *testing.T) { txs := test.MakeNTxs(height, 10) mp := &mpmocks.Mempool{} - mp.On("ReapMaxBytesMaxGas", mock.Anything, mock.Anything).Return(types.Txs(txs[2:])) + mp.On("ReapMaxBytesMaxGas", mock.Anything, mock.Anything).Return(txs[2:]) - app := abcimocks.NewBaseMock() - app.On("PrepareProposal", mock.Anything).Return(abci.ResponsePrepareProposal{ - Txs: types.Txs(txs).ToSliceOfBytes(), - }) + app := &abcimocks.Application{} + app.On("PrepareProposal", mock.Anything, mock.Anything).Return(&abci.ResponsePrepareProposal{ + Txs: txs.ToSliceOfBytes(), + }, nil) cc := proxy.NewLocalClientCreator(app) proxyApp := proxy.NewAppConns(cc, proxy.NopMetrics()) err := proxyApp.Start() @@ -703,15 +780,15 @@ func TestPrepareProposalReorderTxs(t *testing.T) { txs := test.MakeNTxs(height, 10) mp := &mpmocks.Mempool{} - mp.On("ReapMaxBytesMaxGas", mock.Anything, mock.Anything).Return(types.Txs(txs)) + mp.On("ReapMaxBytesMaxGas", mock.Anything, mock.Anything).Return(txs) txs = txs[2:] txs = append(txs[len(txs)/2:], txs[:len(txs)/2]...) - app := abcimocks.NewBaseMock() - app.On("PrepareProposal", mock.Anything).Return(abci.ResponsePrepareProposal{ - Txs: types.Txs(txs).ToSliceOfBytes(), - }) + app := &abcimocks.Application{} + app.On("PrepareProposal", mock.Anything, mock.Anything).Return(&abci.ResponsePrepareProposal{ + Txs: txs.ToSliceOfBytes(), + }, nil) cc := proxy.NewLocalClientCreator(app) proxyApp := proxy.NewAppConns(cc, proxy.NopMetrics()) @@ -761,12 +838,12 @@ func TestPrepareProposalErrorOnTooManyTxs(t *testing.T) { maxDataBytes := types.MaxDataBytes(state.ConsensusParams.Block.MaxBytes, 0, nValidators) txs := test.MakeNTxs(height, maxDataBytes/bytesPerTx+2) // +2 so that tx don't fit mp := &mpmocks.Mempool{} - mp.On("ReapMaxBytesMaxGas", mock.Anything, mock.Anything).Return(types.Txs(txs)) + mp.On("ReapMaxBytesMaxGas", mock.Anything, mock.Anything).Return(txs) - app := abcimocks.NewBaseMock() - app.On("PrepareProposal", mock.Anything).Return(abci.ResponsePrepareProposal{ - Txs: types.Txs(txs).ToSliceOfBytes(), - }) + app := &abcimocks.Application{} + app.On("PrepareProposal", mock.Anything, mock.Anything).Return(&abci.ResponsePrepareProposal{ + Txs: txs.ToSliceOfBytes(), + }, nil) cc := proxy.NewLocalClientCreator(app) proxyApp := proxy.NewAppConns(cc, proxy.NopMetrics()) @@ -809,13 +886,13 @@ func TestPrepareProposalErrorOnPrepareProposalError(t *testing.T) { txs := test.MakeNTxs(height, 10) mp := &mpmocks.Mempool{} - mp.On("ReapMaxBytesMaxGas", mock.Anything, mock.Anything).Return(types.Txs(txs)) + mp.On("ReapMaxBytesMaxGas", mock.Anything, mock.Anything).Return(txs) cm := &abciclientmocks.Client{} cm.On("SetLogger", mock.Anything).Return() cm.On("Start").Return(nil) cm.On("Quit").Return(nil) - cm.On("PrepareProposalSync", mock.Anything).Return(nil, errors.New("an injected error")).Once() + cm.On("PrepareProposal", mock.Anything, mock.Anything).Return(nil, errors.New("an injected error")).Once() cm.On("Stop").Return(nil) cc := &pmocks.ClientCreator{} cc.On("NewABCIClient").Return(cm, nil) diff --git a/state/export_test.go b/state/export_test.go index 7ab180916..331cfb3b7 100644 --- a/state/export_test.go +++ b/state/export_test.go @@ -4,7 +4,6 @@ import ( dbm "github.com/tendermint/tm-db" abci "github.com/tendermint/tendermint/abci/types" - tmstate "github.com/tendermint/tendermint/proto/tendermint/state" "github.com/tendermint/tendermint/types" ) @@ -27,10 +26,10 @@ func UpdateState( state State, blockID types.BlockID, header *types.Header, - abciResponses *tmstate.ABCIResponses, + resp *abci.ResponseFinalizeBlock, validatorUpdates []*types.Validator, ) (State, error) { - return updateState(state, blockID, header, abciResponses, validatorUpdates) + return updateState(state, blockID, header, resp, validatorUpdates) } // ValidateValidatorUpdates is an alias for validateValidatorUpdates exported diff --git a/state/helpers_test.go b/state/helpers_test.go index a965a6661..f1d5c971e 100644 --- a/state/helpers_test.go +++ b/state/helpers_test.go @@ -2,6 +2,7 @@ package state_test import ( "bytes" + "context" "fmt" "testing" "time" @@ -12,7 +13,6 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/internal/test" - tmstate "github.com/tendermint/tendermint/proto/tendermint/state" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/proxy" sm "github.com/tendermint/tendermint/state" @@ -153,21 +153,16 @@ func makeHeaderPartsResponsesValPubKeyChange( t *testing.T, state sm.State, pubkey crypto.PubKey, -) (types.Header, types.BlockID, *tmstate.ABCIResponses) { +) (types.Header, types.BlockID, *abci.ResponseFinalizeBlock) { block := makeBlock(state, state.LastBlockHeight+1, new(types.Commit)) - abciResponses := &tmstate.ABCIResponses{ - BeginBlock: &abci.ResponseBeginBlock{}, - EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil}, - } + abciResponses := &abci.ResponseFinalizeBlock{} // If the pubkey is new, remove the old and add the new. _, val := state.NextValidators.GetByIndex(0) if !bytes.Equal(pubkey.Bytes(), val.PubKey.Bytes()) { - abciResponses.EndBlock = &abci.ResponseEndBlock{ - ValidatorUpdates: []abci.ValidatorUpdate{ - types.TM2PB.NewValidatorUpdate(val.PubKey, 0), - types.TM2PB.NewValidatorUpdate(pubkey, 10), - }, + abciResponses.ValidatorUpdates = []abci.ValidatorUpdate{ + types.TM2PB.NewValidatorUpdate(val.PubKey, 0), + types.TM2PB.NewValidatorUpdate(pubkey, 10), } } @@ -178,21 +173,16 @@ func makeHeaderPartsResponsesValPowerChange( t *testing.T, state sm.State, power int64, -) (types.Header, types.BlockID, *tmstate.ABCIResponses) { +) (types.Header, types.BlockID, *abci.ResponseFinalizeBlock) { block := makeBlock(state, state.LastBlockHeight+1, new(types.Commit)) - abciResponses := &tmstate.ABCIResponses{ - BeginBlock: &abci.ResponseBeginBlock{}, - EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil}, - } + abciResponses := &abci.ResponseFinalizeBlock{} // If the pubkey is new, remove the old and add the new. _, val := state.NextValidators.GetByIndex(0) if val.VotingPower != power { - abciResponses.EndBlock = &abci.ResponseEndBlock{ - ValidatorUpdates: []abci.ValidatorUpdate{ - types.TM2PB.NewValidatorUpdate(val.PubKey, power), - }, + abciResponses.ValidatorUpdates = []abci.ValidatorUpdate{ + types.TM2PB.NewValidatorUpdate(val.PubKey, power), } } @@ -203,12 +193,11 @@ func makeHeaderPartsResponsesParams( t *testing.T, state sm.State, params tmproto.ConsensusParams, -) (types.Header, types.BlockID, *tmstate.ABCIResponses) { +) (types.Header, types.BlockID, *abci.ResponseFinalizeBlock) { block := makeBlock(state, state.LastBlockHeight+1, new(types.Commit)) - abciResponses := &tmstate.ABCIResponses{ - BeginBlock: &abci.ResponseBeginBlock{}, - EndBlock: &abci.ResponseEndBlock{ConsensusParamUpdates: ¶ms}, + abciResponses := &abci.ResponseFinalizeBlock{ + ConsensusParamUpdates: ¶ms, } return block.Header, types.BlockID{Hash: block.Hash(), PartSetHeader: types.PartSetHeader{}}, abciResponses } @@ -238,49 +227,40 @@ type testApp struct { CommitVotes []abci.VoteInfo Misbehavior []abci.Misbehavior ValidatorUpdates []abci.ValidatorUpdate + AgreedAppData []byte } var _ abci.Application = (*testApp)(nil) -func (app *testApp) Info(req abci.RequestInfo) (resInfo abci.ResponseInfo) { - return abci.ResponseInfo{} -} +func (app *testApp) FinalizeBlock(_ context.Context, req *abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { + app.CommitVotes = req.DecidedLastCommit.Votes + app.Misbehavior = req.Misbehavior + txResults := make([]*abci.ExecTxResult, len(req.Txs)) + for idx := range req.Txs { + txResults[idx] = &abci.ExecTxResult{ + Code: abci.CodeTypeOK, + } + } -func (app *testApp) BeginBlock(req abci.RequestBeginBlock) abci.ResponseBeginBlock { - app.CommitVotes = req.LastCommitInfo.Votes - app.Misbehavior = req.ByzantineValidators - return abci.ResponseBeginBlock{} -} - -func (app *testApp) EndBlock(req abci.RequestEndBlock) abci.ResponseEndBlock { - return abci.ResponseEndBlock{ + return &abci.ResponseFinalizeBlock{ ValidatorUpdates: app.ValidatorUpdates, ConsensusParamUpdates: &tmproto.ConsensusParams{ Version: &tmproto.VersionParams{ - App: 1}}} + App: 1}}, + TxResults: txResults, + AgreedAppData: app.AgreedAppData, + }, nil } -func (app *testApp) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx { - return abci.ResponseDeliverTx{Events: []abci.Event{}} +func (app *testApp) Commit(_ context.Context, _ *abci.RequestCommit) (*abci.ResponseCommit, error) { + return &abci.ResponseCommit{RetainHeight: 1}, nil } -func (app *testApp) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx { - return abci.ResponseCheckTx{} -} - -func (app *testApp) Commit() abci.ResponseCommit { - return abci.ResponseCommit{RetainHeight: 1} -} - -func (app *testApp) Query(reqQuery abci.RequestQuery) (resQuery abci.ResponseQuery) { - return -} - -func (app *testApp) ProcessProposal(req abci.RequestProcessProposal) abci.ResponseProcessProposal { +func (app *testApp) ProcessProposal(_ context.Context, req *abci.RequestProcessProposal) (*abci.ResponseProcessProposal, error) { for _, tx := range req.Txs { if len(tx) == 0 { - return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT} + return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}, nil } } - return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT} + return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}, nil } diff --git a/state/indexer/block.go b/state/indexer/block.go index 9c4bb0e54..96328dca0 100644 --- a/state/indexer/block.go +++ b/state/indexer/block.go @@ -15,10 +15,10 @@ type BlockIndexer interface { // upon database query failure. Has(height int64) (bool, error) - // Index indexes BeginBlock and EndBlock events for a given block by its height. - Index(types.EventDataNewBlockHeader) error + // Index indexes FinalizeBlock events for a given block by its height. + Index(types.EventDataNewBlockEvents) error - // Search performs a query for block heights that match a given BeginBlock - // and Endblock event search criteria. + // Search performs a query for block heights that match a given FinalizeBlock + // event search criteria. Search(ctx context.Context, q *query.Query) ([]int64, error) } diff --git a/state/indexer/block/kv/kv.go b/state/indexer/block/kv/kv.go index 83f16d674..b31684119 100644 --- a/state/indexer/block/kv/kv.go +++ b/state/indexer/block/kv/kv.go @@ -20,7 +20,7 @@ import ( var _ indexer.BlockIndexer = (*BlockerIndexer)(nil) -// BlockerIndexer implements a block indexer, indexing BeginBlock and EndBlock +// BlockerIndexer implements a block indexer, indexing FinalizeBlock // events with an underlying KV store. Block events are indexed by their height, // such that matching search criteria returns the respective block height(s). type BlockerIndexer struct { @@ -44,17 +44,16 @@ func (idx *BlockerIndexer) Has(height int64) (bool, error) { return idx.store.Has(key) } -// Index indexes BeginBlock and EndBlock events for a given block by its height. +// Index indexes FinalizeBlock events for a given block by its height. // The following is indexed: // // primary key: encode(block.height | height) => encode(height) -// BeginBlock events: encode(eventType.eventAttr|eventValue|height|begin_block) => encode(height) -// EndBlock events: encode(eventType.eventAttr|eventValue|height|end_block) => encode(height) -func (idx *BlockerIndexer) Index(bh types.EventDataNewBlockHeader) error { +// FinalizeBlock events: encode(eventType.eventAttr|eventValue|height|finalize_block) => encode(height) +func (idx *BlockerIndexer) Index(bh types.EventDataNewBlockEvents) error { batch := idx.store.NewBatch() defer batch.Close() - height := bh.Header.Height + height := bh.Height // 1. index by height key, err := heightKey(height) @@ -65,21 +64,16 @@ func (idx *BlockerIndexer) Index(bh types.EventDataNewBlockHeader) error { return err } - // 2. index BeginBlock events - if err := idx.indexEvents(batch, bh.ResultBeginBlock.Events, "begin_block", height); err != nil { - return fmt.Errorf("failed to index BeginBlock events: %w", err) - } - - // 3. index EndBlock events - if err := idx.indexEvents(batch, bh.ResultEndBlock.Events, "end_block", height); err != nil { - return fmt.Errorf("failed to index EndBlock events: %w", err) + // 2. index block events + if err := idx.indexEvents(batch, bh.Events, "finalize_block", height); err != nil { + return fmt.Errorf("failed to index FinalizeBlock events: %w", err) } return batch.WriteSync() } -// Search performs a query for block heights that match a given BeginBlock -// and Endblock event search criteria. The given query can match against zero, +// Search performs a query for block heights that match a given FinalizeBlock +// event search criteria. The given query can match against zero, // one or more block heights. In the case of height queries, i.e. block.height=H, // if the height is indexed, that height alone will be returned. An error and // nil slice is returned. Otherwise, a non-nil slice and nil error is returned. diff --git a/state/indexer/block/kv/kv_test.go b/state/indexer/block/kv/kv_test.go index 1e96063fe..930ec9e4e 100644 --- a/state/indexer/block/kv/kv_test.go +++ b/state/indexer/block/kv/kv_test.go @@ -18,32 +18,26 @@ func TestBlockIndexer(t *testing.T) { store := db.NewPrefixDB(db.NewMemDB(), []byte("block_events")) indexer := blockidxkv.New(store) - require.NoError(t, indexer.Index(types.EventDataNewBlockHeader{ - Header: types.Header{Height: 1}, - ResultBeginBlock: abci.ResponseBeginBlock{ - Events: []abci.Event{ - { - Type: "begin_event", - Attributes: []abci.EventAttribute{ - { - Key: "proposer", - Value: "FCAA001", - Index: true, - }, + require.NoError(t, indexer.Index(types.EventDataNewBlockEvents{ + Height: 1, + Events: []abci.Event{ + { + Type: "begin_event", + Attributes: []abci.EventAttribute{ + { + Key: "proposer", + Value: "FCAA001", + Index: true, }, }, }, - }, - ResultEndBlock: abci.ResponseEndBlock{ - Events: []abci.Event{ - { - Type: "end_event", - Attributes: []abci.EventAttribute{ - { - Key: "foo", - Value: "100", - Index: true, - }, + { + Type: "end_event", + Attributes: []abci.EventAttribute{ + { + Key: "foo", + Value: "100", + Index: true, }, }, }, @@ -56,32 +50,26 @@ func TestBlockIndexer(t *testing.T) { index = true } - require.NoError(t, indexer.Index(types.EventDataNewBlockHeader{ - Header: types.Header{Height: int64(i)}, - ResultBeginBlock: abci.ResponseBeginBlock{ - Events: []abci.Event{ - { - Type: "begin_event", - Attributes: []abci.EventAttribute{ - { - Key: "proposer", - Value: "FCAA001", - Index: true, - }, + require.NoError(t, indexer.Index(types.EventDataNewBlockEvents{ + Height: int64(i), + Events: []abci.Event{ + { + Type: "begin_event", + Attributes: []abci.EventAttribute{ + { + Key: "proposer", + Value: "FCAA001", + Index: true, }, }, }, - }, - ResultEndBlock: abci.ResponseEndBlock{ - Events: []abci.Event{ - { - Type: "end_event", - Attributes: []abci.EventAttribute{ - { - Key: "foo", - Value: fmt.Sprintf("%d", i), - Index: index, - }, + { + Type: "end_event", + Attributes: []abci.EventAttribute{ + { + Key: "foo", + Value: fmt.Sprintf("%d", i), + Index: index, }, }, }, diff --git a/state/indexer/block/null/null.go b/state/indexer/block/null/null.go index d36d8680e..131c6412f 100644 --- a/state/indexer/block/null/null.go +++ b/state/indexer/block/null/null.go @@ -18,7 +18,7 @@ func (idx *BlockerIndexer) Has(height int64) (bool, error) { return false, errors.New(`indexing is disabled (set 'tx_index = "kv"' in config)`) } -func (idx *BlockerIndexer) Index(types.EventDataNewBlockHeader) error { +func (idx *BlockerIndexer) Index(types.EventDataNewBlockEvents) error { return nil } diff --git a/state/indexer/mocks/block_indexer.go b/state/indexer/mocks/block_indexer.go index 2c0f0ecb0..0832ed73a 100644 --- a/state/indexer/mocks/block_indexer.go +++ b/state/indexer/mocks/block_indexer.go @@ -39,11 +39,11 @@ func (_m *BlockIndexer) Has(height int64) (bool, error) { } // Index provides a mock function with given fields: _a0 -func (_m *BlockIndexer) Index(_a0 types.EventDataNewBlockHeader) error { +func (_m *BlockIndexer) Index(_a0 types.EventDataNewBlockEvents) error { ret := _m.Called(_a0) var r0 error - if rf, ok := ret.Get(0).(func(types.EventDataNewBlockHeader) error); ok { + if rf, ok := ret.Get(0).(func(types.EventDataNewBlockEvents) error); ok { r0 = rf(_a0) } else { r0 = ret.Error(0) diff --git a/state/indexer/sink/psql/backport.go b/state/indexer/sink/psql/backport.go index 354791112..68efa2aae 100644 --- a/state/indexer/sink/psql/backport.go +++ b/state/indexer/sink/psql/backport.go @@ -24,8 +24,7 @@ import ( ) const ( - eventTypeBeginBlock = "begin_block" - eventTypeEndBlock = "end_block" + eventTypeFinalizeBlock = "finaliz_block" ) // TxIndexer returns a bridge from es to the Tendermint v0.34 transaction indexer. @@ -77,7 +76,7 @@ func (BackportBlockIndexer) Has(height int64) (bool, error) { // Index indexes block begin and end events for the specified block. It is // part of the BlockIndexer interface. -func (b BackportBlockIndexer) Index(block types.EventDataNewBlockHeader) error { +func (b BackportBlockIndexer) Index(block types.EventDataNewBlockEvents) error { return b.psql.IndexBlockEvents(block) } diff --git a/state/indexer/sink/psql/psql.go b/state/indexer/sink/psql/psql.go index 29d452a7c..a2417c8ac 100644 --- a/state/indexer/sink/psql/psql.go +++ b/state/indexer/sink/psql/psql.go @@ -139,7 +139,7 @@ func makeIndexedEvent(compositeKey, value string) abci.Event { // IndexBlockEvents indexes the specified block header, part of the // indexer.EventSink interface. -func (es *EventSink) IndexBlockEvents(h types.EventDataNewBlockHeader) error { +func (es *EventSink) IndexBlockEvents(h types.EventDataNewBlockEvents) error { ts := time.Now().UTC() return runInTransaction(es.store, func(dbtx *sql.Tx) error { @@ -150,7 +150,7 @@ INSERT INTO `+tableBlocks+` (height, chain_id, created_at) VALUES ($1, $2, $3) ON CONFLICT DO NOTHING RETURNING rowid; -`, h.Header.Height, es.chainID, ts) +`, h.Height, es.chainID, ts) if err == sql.ErrNoRows { return nil // we already saw this block; quietly succeed } else if err != nil { @@ -159,16 +159,13 @@ INSERT INTO `+tableBlocks+` (height, chain_id, created_at) // Insert the special block meta-event for height. if err := insertEvents(dbtx, blockID, 0, []abci.Event{ - makeIndexedEvent(types.BlockHeightKey, fmt.Sprint(h.Header.Height)), + makeIndexedEvent(types.BlockHeightKey, fmt.Sprint(h.Height)), }); err != nil { return fmt.Errorf("block meta-events: %w", err) } // Insert all the block events. Order is important here, - if err := insertEvents(dbtx, blockID, 0, h.ResultBeginBlock.Events); err != nil { - return fmt.Errorf("begin-block events: %w", err) - } - if err := insertEvents(dbtx, blockID, 0, h.ResultEndBlock.Events); err != nil { - return fmt.Errorf("end-block events: %w", err) + if err := insertEvents(dbtx, blockID, 0, h.Events); err != nil { + return fmt.Errorf("finalizeblock events: %w", err) } return nil }) diff --git a/state/indexer/sink/psql/psql_test.go b/state/indexer/sink/psql/psql_test.go index 46531b3ec..b08c2dbf3 100644 --- a/state/indexer/sink/psql/psql_test.go +++ b/state/indexer/sink/psql/psql_test.go @@ -19,6 +19,7 @@ import ( "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" + tmlog "github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/state/txindex" "github.com/tendermint/tendermint/types" @@ -140,7 +141,7 @@ func TestMain(m *testing.M) { func TestIndexing(t *testing.T) { t.Run("IndexBlockEvents", func(t *testing.T) { indexer := &EventSink{store: testDB(), chainID: chainID} - require.NoError(t, indexer.IndexBlockEvents(newTestBlockHeader())) + require.NoError(t, indexer.IndexBlockEvents(newTestBlockEvents())) verifyBlock(t, 1) verifyBlock(t, 2) @@ -156,7 +157,7 @@ func TestIndexing(t *testing.T) { require.NoError(t, verifyTimeStamp(tableBlocks)) // Attempting to reindex the same events should gracefully succeed. - require.NoError(t, indexer.IndexBlockEvents(newTestBlockHeader())) + require.NoError(t, indexer.IndexBlockEvents(newTestBlockEvents())) }) t.Run("IndexTxEvents", func(t *testing.T) { @@ -212,6 +213,7 @@ func TestIndexing(t *testing.T) { }) service := txindex.NewIndexerService(indexer.TxIndexer(), indexer.BlockIndexer(), eventBus, true) + service.SetLogger(tmlog.TestingLogger()) err = service.Start() require.NoError(t, err) t.Cleanup(func() { @@ -221,16 +223,16 @@ func TestIndexing(t *testing.T) { }) // publish block with txs - err = eventBus.PublishEventNewBlockHeader(types.EventDataNewBlockHeader{ - Header: types.Header{Height: 1}, - NumTxs: int64(2), + err = eventBus.PublishEventNewBlockEvents(types.EventDataNewBlockEvents{ + Height: 1, + NumTxs: 2, }) require.NoError(t, err) txResult1 := &abci.TxResult{ Height: 1, Index: uint32(0), Tx: types.Tx("foo"), - Result: abci.ResponseDeliverTx{Code: 0}, + Result: abci.ExecTxResult{Code: 0}, } err = eventBus.PublishEventTx(types.EventDataTx{TxResult: *txResult1}) require.NoError(t, err) @@ -238,7 +240,7 @@ func TestIndexing(t *testing.T) { Height: 1, Index: uint32(1), Tx: types.Tx("bar"), - Result: abci.ResponseDeliverTx{Code: 1}, + Result: abci.ExecTxResult{Code: 1}, } err = eventBus.PublishEventTx(types.EventDataTx{TxResult: *txResult2}) require.NoError(t, err) @@ -253,22 +255,16 @@ func TestStop(t *testing.T) { require.NoError(t, indexer.Stop()) } -// newTestBlockHeader constructs a fresh copy of a block header containing +// newTestBlock constructs a fresh copy of a new block event containing // known test values to exercise the indexer. -func newTestBlockHeader() types.EventDataNewBlockHeader { - return types.EventDataNewBlockHeader{ - Header: types.Header{Height: 1}, - ResultBeginBlock: abci.ResponseBeginBlock{ - Events: []abci.Event{ - makeIndexedEvent("begin_event.proposer", "FCAA001"), - makeIndexedEvent("thingy.whatzit", "O.O"), - }, - }, - ResultEndBlock: abci.ResponseEndBlock{ - Events: []abci.Event{ - makeIndexedEvent("end_event.foo", "100"), - makeIndexedEvent("thingy.whatzit", "-.O"), - }, +func newTestBlockEvents() types.EventDataNewBlockEvents { + return types.EventDataNewBlockEvents{ + Height: 1, + Events: []abci.Event{ + makeIndexedEvent("begin_event.proposer", "FCAA001"), + makeIndexedEvent("thingy.whatzit", "O.O"), + makeIndexedEvent("end_event.foo", "100"), + makeIndexedEvent("thingy.whatzit", "-.O"), }, } } @@ -307,7 +303,7 @@ func txResultWithEvents(events []abci.Event) *abci.TxResult { Height: 1, Index: 0, Tx: types.Tx("HELLO WORLD"), - Result: abci.ResponseDeliverTx{ + Result: abci.ExecTxResult{ Data: []byte{0}, Code: abci.CodeTypeOK, Log: "", @@ -355,17 +351,8 @@ SELECT height FROM `+tableBlocks+` WHERE height = $1; if err := testDB().QueryRow(` SELECT type, height, chain_id FROM `+viewBlockEvents+` WHERE height = $1 AND type = $2 AND chain_id = $3; -`, height, eventTypeBeginBlock, chainID).Err(); err == sql.ErrNoRows { - t.Errorf("No %q event found for height=%d", eventTypeBeginBlock, height) - } else if err != nil { - t.Fatalf("Database query failed: %v", err) - } - - if err := testDB().QueryRow(` -SELECT type, height, chain_id FROM `+viewBlockEvents+` - WHERE height = $1 AND type = $2 AND chain_id = $3; -`, height, eventTypeEndBlock, chainID).Err(); err == sql.ErrNoRows { - t.Errorf("No %q event found for height=%d", eventTypeEndBlock, height) +`, height, eventTypeFinalizeBlock, chainID).Err(); err == sql.ErrNoRows { + t.Errorf("No %q event found for height=%d", eventTypeFinalizeBlock, height) } else if err != nil { t.Fatalf("Database query failed: %v", err) } diff --git a/state/metrics.gen.go b/state/metrics.gen.go index 1ce2c4de1..512bb7a37 100644 --- a/state/metrics.gen.go +++ b/state/metrics.gen.go @@ -18,7 +18,7 @@ func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics { Namespace: namespace, Subsystem: MetricsSubsystem, Name: "block_processing_time", - Help: "Time between BeginBlock and EndBlock in ms.", + Help: "Time spent processig finalize block.", Buckets: stdprometheus.LinearBuckets(1, 10, 10), }, labels).With(labelsAndValues...), diff --git a/state/metrics.go b/state/metrics.go index 6c238df76..a37515668 100644 --- a/state/metrics.go +++ b/state/metrics.go @@ -14,7 +14,7 @@ const ( // Metrics contains metrics exposed by this package. type Metrics struct { - // Time between BeginBlock and EndBlock in ms. + // Time spent processing FinalizeBlock BlockProcessingTime metrics.Histogram `metrics_buckettype:"lin" metrics_bucketsizes:"1, 10, 10"` // ConsensusParamUpdates is the total number of times the application has diff --git a/state/mocks/store.go b/state/mocks/store.go index a89cf6f04..bf533c3d0 100644 --- a/state/mocks/store.go +++ b/state/mocks/store.go @@ -4,9 +4,9 @@ package mocks import ( mock "github.com/stretchr/testify/mock" - state "github.com/tendermint/tendermint/state" + abcitypes "github.com/tendermint/tendermint/abci/types" - tendermintstate "github.com/tendermint/tendermint/proto/tendermint/state" + state "github.com/tendermint/tendermint/state" types "github.com/tendermint/tendermint/types" ) @@ -65,17 +65,15 @@ func (_m *Store) Load() (state.State, error) { return r0, r1 } -// LoadABCIResponses provides a mock function with given fields: _a0 -func (_m *Store) LoadABCIResponses(_a0 int64) (*tendermintstate.ABCIResponses, error) { +// LoadConsensusParams provides a mock function with given fields: _a0 +func (_m *Store) LoadConsensusParams(_a0 int64) (types.ConsensusParams, error) { ret := _m.Called(_a0) - var r0 *tendermintstate.ABCIResponses - if rf, ok := ret.Get(0).(func(int64) *tendermintstate.ABCIResponses); ok { + var r0 types.ConsensusParams + if rf, ok := ret.Get(0).(func(int64) types.ConsensusParams); ok { r0 = rf(_a0) } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*tendermintstate.ABCIResponses) - } + r0 = ret.Get(0).(types.ConsensusParams) } var r1 error @@ -88,15 +86,17 @@ func (_m *Store) LoadABCIResponses(_a0 int64) (*tendermintstate.ABCIResponses, e return r0, r1 } -// LoadConsensusParams provides a mock function with given fields: _a0 -func (_m *Store) LoadConsensusParams(_a0 int64) (types.ConsensusParams, error) { +// LoadFinalizeBlockResponse provides a mock function with given fields: _a0 +func (_m *Store) LoadFinalizeBlockResponse(_a0 int64) (*abcitypes.ResponseFinalizeBlock, error) { ret := _m.Called(_a0) - var r0 types.ConsensusParams - if rf, ok := ret.Get(0).(func(int64) types.ConsensusParams); ok { + var r0 *abcitypes.ResponseFinalizeBlock + if rf, ok := ret.Get(0).(func(int64) *abcitypes.ResponseFinalizeBlock); ok { r0 = rf(_a0) } else { - r0 = ret.Get(0).(types.ConsensusParams) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*abcitypes.ResponseFinalizeBlock) + } } var r1 error @@ -151,16 +151,16 @@ func (_m *Store) LoadFromDBOrGenesisFile(_a0 string) (state.State, error) { return r0, r1 } -// LoadLastABCIResponse provides a mock function with given fields: _a0 -func (_m *Store) LoadLastABCIResponse(_a0 int64) (*tendermintstate.ABCIResponses, error) { +// LoadLastFinalizeBlockResponse provides a mock function with given fields: _a0 +func (_m *Store) LoadLastFinalizeBlockResponse(_a0 int64) (*abcitypes.ResponseFinalizeBlock, error) { ret := _m.Called(_a0) - var r0 *tendermintstate.ABCIResponses - if rf, ok := ret.Get(0).(func(int64) *tendermintstate.ABCIResponses); ok { + var r0 *abcitypes.ResponseFinalizeBlock + if rf, ok := ret.Get(0).(func(int64) *abcitypes.ResponseFinalizeBlock); ok { r0 = rf(_a0) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*tendermintstate.ABCIResponses) + r0 = ret.Get(0).(*abcitypes.ResponseFinalizeBlock) } } @@ -225,12 +225,12 @@ func (_m *Store) Save(_a0 state.State) error { return r0 } -// SaveABCIResponses provides a mock function with given fields: _a0, _a1 -func (_m *Store) SaveABCIResponses(_a0 int64, _a1 *tendermintstate.ABCIResponses) error { +// SaveFinalizeBlockResponse provides a mock function with given fields: _a0, _a1 +func (_m *Store) SaveFinalizeBlockResponse(_a0 int64, _a1 *abcitypes.ResponseFinalizeBlock) error { ret := _m.Called(_a0, _a1) var r0 error - if rf, ok := ret.Get(0).(func(int64, *tendermintstate.ABCIResponses) error); ok { + if rf, ok := ret.Get(0).(func(int64, *abcitypes.ResponseFinalizeBlock) error); ok { r0 = rf(_a0, _a1) } else { r0 = ret.Error(0) diff --git a/state/state.go b/state/state.go index 51ce5a3f8..171a4e713 100644 --- a/state/state.go +++ b/state/state.go @@ -68,7 +68,7 @@ type State struct { LastHeightValidatorsChanged int64 // Consensus parameters used for validating blocks. - // Changes returned by EndBlock and updated after Commit. + // Changes returned by FinalizeBlock and updated after Commit. ConsensusParams types.ConsensusParams LastHeightConsensusParamsChanged int64 diff --git a/state/state_test.go b/state/state_test.go index f88affa56..d8ddf26d1 100644 --- a/state/state_test.go +++ b/state/state_test.go @@ -18,7 +18,6 @@ import ( cryptoenc "github.com/tendermint/tendermint/crypto/encoding" "github.com/tendermint/tendermint/internal/test" tmrand "github.com/tendermint/tendermint/libs/rand" - tmstate "github.com/tendermint/tendermint/proto/tendermint/state" sm "github.com/tendermint/tendermint/state" "github.com/tendermint/tendermint/types" ) @@ -94,8 +93,8 @@ func TestStateSaveLoad(t *testing.T) { loadedState, state)) } -// TestABCIResponsesSaveLoad tests saving and loading ABCIResponses. -func TestABCIResponsesSaveLoad1(t *testing.T) { +// TestFinalizeBlockResponsesSaveLoad1 tests saving and loading ABCIResponses. +func TestFinalizeBlockResponsesSaveLoad1(t *testing.T) { tearDown, stateDB, state := setupTestCase(t) defer tearDown(t) stateStore := sm.NewStore(stateDB, sm.StoreOptions{ @@ -108,27 +107,25 @@ func TestABCIResponsesSaveLoad1(t *testing.T) { // Build mock responses. block := makeBlock(state, 2, new(types.Commit)) - abciResponses := new(tmstate.ABCIResponses) - dtxs := make([]*abci.ResponseDeliverTx, 2) - abciResponses.DeliverTxs = dtxs + abciResponses := new(abci.ResponseFinalizeBlock) + dtxs := make([]*abci.ExecTxResult, 2) + abciResponses.TxResults = dtxs - abciResponses.DeliverTxs[0] = &abci.ResponseDeliverTx{Data: []byte("foo"), Events: nil} - abciResponses.DeliverTxs[1] = &abci.ResponseDeliverTx{Data: []byte("bar"), Log: "ok", Events: nil} - abciResponses.EndBlock = &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{ + abciResponses.TxResults[0] = &abci.ExecTxResult{Data: []byte("foo"), Events: nil} + abciResponses.TxResults[1] = &abci.ExecTxResult{Data: []byte("bar"), Log: "ok", Events: nil} + abciResponses.ValidatorUpdates = []abci.ValidatorUpdate{ types.TM2PB.NewValidatorUpdate(ed25519.GenPrivKey().PubKey(), 10), - }} + } - err := stateStore.SaveABCIResponses(block.Height, abciResponses) + err := stateStore.SaveFinalizeBlockResponse(block.Height, abciResponses) require.NoError(t, err) - loadedABCIResponses, err := stateStore.LoadABCIResponses(block.Height) - assert.Nil(err) - assert.Equal(abciResponses, loadedABCIResponses, - fmt.Sprintf("ABCIResponses don't match:\ngot: %v\nexpected: %v\n", - loadedABCIResponses, abciResponses)) + loadedABCIResponses, err := stateStore.LoadFinalizeBlockResponse(block.Height) + assert.NoError(err) + assert.Equal(abciResponses, loadedABCIResponses) } -// TestResultsSaveLoad tests saving and loading ABCI results. -func TestABCIResponsesSaveLoad2(t *testing.T) { +// TestResultsSaveLoad tests saving and loading FinalizeBlock results. +func TestFinalizeBlockResponsesSaveLoad2(t *testing.T) { tearDown, stateDB, _ := setupTestCase(t) defer tearDown(t) assert := assert.New(t) @@ -140,22 +137,22 @@ func TestABCIResponsesSaveLoad2(t *testing.T) { cases := [...]struct { // Height is implied to equal index+2, // as block 1 is created from genesis. - added []*abci.ResponseDeliverTx - expected []*abci.ResponseDeliverTx + added []*abci.ExecTxResult + expected []*abci.ExecTxResult }{ 0: { nil, nil, }, 1: { - []*abci.ResponseDeliverTx{ + []*abci.ExecTxResult{ {Code: 32, Data: []byte("Hello"), Log: "Huh?"}, }, - []*abci.ResponseDeliverTx{ + []*abci.ExecTxResult{ {Code: 32, Data: []byte("Hello")}, }}, 2: { - []*abci.ResponseDeliverTx{ + []*abci.ExecTxResult{ {Code: 383}, { Data: []byte("Gotcha!"), @@ -165,7 +162,7 @@ func TestABCIResponsesSaveLoad2(t *testing.T) { }, }, }, - []*abci.ResponseDeliverTx{ + []*abci.ExecTxResult{ {Code: 383, Data: nil}, {Code: 0, Data: []byte("Gotcha!"), Events: []abci.Event{ {Type: "type1", Attributes: []abci.EventAttribute{{Key: "a", Value: "1"}}}, @@ -177,7 +174,7 @@ func TestABCIResponsesSaveLoad2(t *testing.T) { nil, }, 4: { - []*abci.ResponseDeliverTx{nil}, + []*abci.ExecTxResult{nil}, nil, }, } @@ -185,34 +182,32 @@ func TestABCIResponsesSaveLoad2(t *testing.T) { // Query all before, this should return error. for i := range cases { h := int64(i + 1) - res, err := stateStore.LoadABCIResponses(h) + res, err := stateStore.LoadFinalizeBlockResponse(h) assert.Error(err, "%d: %#v", i, res) } // Add all cases. for i, tc := range cases { h := int64(i + 1) // last block height, one below what we save - responses := &tmstate.ABCIResponses{ - BeginBlock: &abci.ResponseBeginBlock{}, - DeliverTxs: tc.added, - EndBlock: &abci.ResponseEndBlock{}, + responses := &abci.ResponseFinalizeBlock{ + TxResults: tc.added, + AgreedAppData: []byte(fmt.Sprintf("%d", h)), } - err := stateStore.SaveABCIResponses(h, responses) + err := stateStore.SaveFinalizeBlockResponse(h, responses) require.NoError(t, err) } // Query all before, should return expected value. for i, tc := range cases { h := int64(i + 1) - res, err := stateStore.LoadABCIResponses(h) + res, err := stateStore.LoadFinalizeBlockResponse(h) if assert.NoError(err, "%d", i) { t.Log(res) - responses := &tmstate.ABCIResponses{ - BeginBlock: &abci.ResponseBeginBlock{}, - DeliverTxs: tc.expected, - EndBlock: &abci.ResponseEndBlock{}, + responses := &abci.ResponseFinalizeBlock{ + TxResults: tc.expected, + AgreedAppData: []byte(fmt.Sprintf("%d", h)), } - assert.Equal(sm.ABCIResponsesResultsHash(responses), sm.ABCIResponsesResultsHash(res), "%d", i) + assert.Equal(sm.TxResultsHash(responses.TxResults), sm.TxResultsHash(res.TxResults), "%d", i) } } } @@ -281,7 +276,7 @@ func TestOneValidatorChangesSaveLoad(t *testing.T) { power++ } header, blockID, responses := makeHeaderPartsResponsesValPowerChange(t, state, power) - validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.EndBlock.ValidatorUpdates) + validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.ValidatorUpdates) require.NoError(t, err) state, err = sm.UpdateState(state, blockID, &header, responses, validatorUpdates) require.NoError(t, err) @@ -458,11 +453,8 @@ func TestProposerPriorityDoesNotGetResetToZero(t *testing.T) { bps, err := block.MakePartSet(testPartSize) require.NoError(t, err) blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()} - abciResponses := &tmstate.ABCIResponses{ - BeginBlock: &abci.ResponseBeginBlock{}, - EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil}, - } - validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) + abciResponses := &abci.ResponseFinalizeBlock{} + validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.ValidatorUpdates) require.NoError(t, err) updatedState, err := sm.UpdateState(state, blockID, &block.Header, abciResponses, validatorUpdates) assert.NoError(t, err) @@ -575,11 +567,8 @@ func TestProposerPriorityProposerAlternates(t *testing.T) { require.NoError(t, err) blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()} // no updates: - abciResponses := &tmstate.ABCIResponses{ - BeginBlock: &abci.ResponseBeginBlock{}, - EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil}, - } - validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) + abciResponses := &abci.ResponseFinalizeBlock{} + validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.ValidatorUpdates) require.NoError(t, err) updatedState, err := sm.UpdateState(state, blockID, &block.Header, abciResponses, validatorUpdates) @@ -639,7 +628,7 @@ func TestProposerPriorityProposerAlternates(t *testing.T) { updatedVal2, ) - validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) + validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.ValidatorUpdates) require.NoError(t, err) updatedState3, err := sm.UpdateState(updatedState2, blockID, &block.Header, abciResponses, validatorUpdates) @@ -678,11 +667,8 @@ func TestProposerPriorityProposerAlternates(t *testing.T) { // no changes in voting power and both validators have same voting power // -> proposers should alternate: oldState := updatedState3 - abciResponses = &tmstate.ABCIResponses{ - BeginBlock: &abci.ResponseBeginBlock{}, - EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil}, - } - validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) + abciResponses = &abci.ResponseFinalizeBlock{} + validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.ValidatorUpdates) require.NoError(t, err) oldState, err = sm.UpdateState(oldState, blockID, &block.Header, abciResponses, validatorUpdates) @@ -694,11 +680,8 @@ func TestProposerPriorityProposerAlternates(t *testing.T) { for i := 0; i < 1000; i++ { // no validator updates: - abciResponses := &tmstate.ABCIResponses{ - BeginBlock: &abci.ResponseBeginBlock{}, - EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil}, - } - validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) + abciResponses := &abci.ResponseFinalizeBlock{} + validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.ValidatorUpdates) require.NoError(t, err) updatedState, err := sm.UpdateState(oldState, blockID, &block.Header, abciResponses, validatorUpdates) @@ -752,11 +735,8 @@ func TestLargeGenesisValidator(t *testing.T) { oldState := state for i := 0; i < 10; i++ { // no updates: - abciResponses := &tmstate.ABCIResponses{ - BeginBlock: &abci.ResponseBeginBlock{}, - EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil}, - } - validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) + abciResponses := &abci.ResponseFinalizeBlock{} + validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.ValidatorUpdates) require.NoError(t, err) block := makeBlock(oldState, oldState.LastBlockHeight+1, new(types.Commit)) @@ -786,9 +766,8 @@ func TestLargeGenesisValidator(t *testing.T) { firstAddedVal := abci.ValidatorUpdate{PubKey: fvp, Power: firstAddedValVotingPower} validatorUpdates, err := types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{firstAddedVal}) assert.NoError(t, err) - abciResponses := &tmstate.ABCIResponses{ - BeginBlock: &abci.ResponseBeginBlock{}, - EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{firstAddedVal}}, + abciResponses := &abci.ResponseFinalizeBlock{ + ValidatorUpdates: []abci.ValidatorUpdate{firstAddedVal}, } block := makeBlock(oldState, oldState.LastBlockHeight+1, new(types.Commit)) @@ -802,11 +781,8 @@ func TestLargeGenesisValidator(t *testing.T) { lastState := updatedState for i := 0; i < 200; i++ { // no updates: - abciResponses := &tmstate.ABCIResponses{ - BeginBlock: &abci.ResponseBeginBlock{}, - EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil}, - } - validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) + abciResponses := &abci.ResponseFinalizeBlock{} + validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.ValidatorUpdates) require.NoError(t, err) block := makeBlock(lastState, lastState.LastBlockHeight+1, new(types.Commit)) @@ -842,9 +818,8 @@ func TestLargeGenesisValidator(t *testing.T) { validatorUpdates, err := types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{addedVal}) assert.NoError(t, err) - abciResponses := &tmstate.ABCIResponses{ - BeginBlock: &abci.ResponseBeginBlock{}, - EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{addedVal}}, + abciResponses := &abci.ResponseFinalizeBlock{ + ValidatorUpdates: []abci.ValidatorUpdate{addedVal}, } block := makeBlock(oldState, oldState.LastBlockHeight+1, new(types.Commit)) bps, err := block.MakePartSet(testPartSize) @@ -860,9 +835,8 @@ func TestLargeGenesisValidator(t *testing.T) { gp, err := cryptoenc.PubKeyToProto(genesisPubKey) require.NoError(t, err) removeGenesisVal := abci.ValidatorUpdate{PubKey: gp, Power: 0} - abciResponses = &tmstate.ABCIResponses{ - BeginBlock: &abci.ResponseBeginBlock{}, - EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{removeGenesisVal}}, + abciResponses = &abci.ResponseFinalizeBlock{ + ValidatorUpdates: []abci.ValidatorUpdate{removeGenesisVal}, } block = makeBlock(oldState, oldState.LastBlockHeight+1, new(types.Commit)) @@ -872,7 +846,7 @@ func TestLargeGenesisValidator(t *testing.T) { require.NoError(t, err) blockID = types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()} - validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) + validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.ValidatorUpdates) require.NoError(t, err) updatedState, err = sm.UpdateState(state, blockID, &block.Header, abciResponses, validatorUpdates) require.NoError(t, err) @@ -885,11 +859,8 @@ func TestLargeGenesisValidator(t *testing.T) { count := 0 isProposerUnchanged := true for isProposerUnchanged { - abciResponses := &tmstate.ABCIResponses{ - BeginBlock: &abci.ResponseBeginBlock{}, - EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil}, - } - validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) + abciResponses := &abci.ResponseFinalizeBlock{} + validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.ValidatorUpdates) require.NoError(t, err) block = makeBlock(curState, curState.LastBlockHeight+1, new(types.Commit)) @@ -913,11 +884,8 @@ func TestLargeGenesisValidator(t *testing.T) { proposers := make([]*types.Validator, numVals) for i := 0; i < 100; i++ { // no updates: - abciResponses := &tmstate.ABCIResponses{ - BeginBlock: &abci.ResponseBeginBlock{}, - EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil}, - } - validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) + abciResponses := &abci.ResponseFinalizeBlock{} + validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.ValidatorUpdates) require.NoError(t, err) block := makeBlock(updatedState, updatedState.LastBlockHeight+1, new(types.Commit)) @@ -988,7 +956,7 @@ func TestManyValidatorChangesSaveLoad(t *testing.T) { // Save state etc. var validatorUpdates []*types.Validator - validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.EndBlock.ValidatorUpdates) + validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.ValidatorUpdates) require.NoError(t, err) state, err = sm.UpdateState(state, blockID, &header, responses, validatorUpdates) require.Nil(t, err) @@ -1068,7 +1036,7 @@ func TestConsensusParamsChangesSaveLoad(t *testing.T) { cp = params[changeIndex] } header, blockID, responses := makeHeaderPartsResponsesParams(t, state, cp.ToProto()) - validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.EndBlock.ValidatorUpdates) + validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.ValidatorUpdates) require.NoError(t, err) state, err = sm.UpdateState(state, blockID, &header, responses, validatorUpdates) diff --git a/state/store.go b/state/store.go index 8503ce687..b6096adf8 100644 --- a/state/store.go +++ b/state/store.go @@ -58,17 +58,17 @@ type Store interface { Load() (State, error) // LoadValidators loads the validator set at a given height LoadValidators(int64) (*types.ValidatorSet, error) - // LoadABCIResponses loads the abciResponse for a given height - LoadABCIResponses(int64) (*tmstate.ABCIResponses, error) + // LoadFinalizeBlockResponse loads the abciResponse for a given height + LoadFinalizeBlockResponse(int64) (*abci.ResponseFinalizeBlock, error) // LoadLastABCIResponse loads the last abciResponse for a given height - LoadLastABCIResponse(int64) (*tmstate.ABCIResponses, error) + LoadLastFinalizeBlockResponse(int64) (*abci.ResponseFinalizeBlock, error) // LoadConsensusParams loads the consensus params for a given height LoadConsensusParams(int64) (types.ConsensusParams, error) // Save overwrites the previous state with the updated one Save(State) error - // SaveABCIResponses saves ABCIResponses for a given height - SaveABCIResponses(int64, *tmstate.ABCIResponses) error - // Bootstrap is used for bootstrapping state when not starting from a initial height + // SaveFinalizeBlockResponse saves ABCIResponses for a given height + SaveFinalizeBlockResponse(int64, *abci.ResponseFinalizeBlock) error + // Bootstrap is used for bootstrapping state when not starting from a initial height. Bootstrap(State) error // PruneStates takes the height from which to start pruning and which height stop at PruneStates(int64, int64, int64) error @@ -85,7 +85,7 @@ type dbStore struct { type StoreOptions struct { // DiscardABCIResponses determines whether or not the store - // retains all ABCIResponses. If DiscardABCiResponses is enabled, + // retains all ABCIResponses. If DiscardABCIResponses is enabled, // the store will maintain only the response object from the latest // height. DiscardABCIResponses bool @@ -367,20 +367,20 @@ func (store dbStore) PruneStates(from int64, to int64, evidenceThresholdHeight i //------------------------------------------------------------------------ -// ABCIResponsesResultsHash returns the root hash of a Merkle tree of -// ResponseDeliverTx responses (see ABCIResults.Hash) +// TxResultsHash returns the root hash of a Merkle tree of +// ExecTxResulst responses (see ABCIResults.Hash) // // See merkle.SimpleHashFromByteSlices -func ABCIResponsesResultsHash(ar *tmstate.ABCIResponses) []byte { - return types.NewResults(ar.DeliverTxs).Hash() +func TxResultsHash(txResults []*abci.ExecTxResult) []byte { + return types.NewResults(txResults).Hash() } -// LoadABCIResponses loads the ABCIResponses for the given height from the -// database. If the node has DiscardABCIResponses set to true, ErrABCIResponsesNotPersisted +// LoadFinalizeBlockResponse loads the DiscardABCIResponses for the given height from the +// database. If the node has D set to true, ErrABCIResponsesNotPersisted // is persisted. If not found, ErrNoABCIResponsesForHeight is returned. -func (store dbStore) LoadABCIResponses(height int64) (*tmstate.ABCIResponses, error) { +func (store dbStore) LoadFinalizeBlockResponse(height int64) (*abci.ResponseFinalizeBlock, error) { if store.DiscardABCIResponses { - return nil, ErrABCIResponsesNotPersisted + return nil, ErrFinalizeBlockResponsesNotPersisted } buf, err := store.db.Get(calcABCIResponsesKey(height)) @@ -388,29 +388,39 @@ func (store dbStore) LoadABCIResponses(height int64) (*tmstate.ABCIResponses, er return nil, err } if len(buf) == 0 { - return nil, ErrNoABCIResponsesForHeight{height} } - abciResponses := new(tmstate.ABCIResponses) - err = abciResponses.Unmarshal(buf) + resp := new(abci.ResponseFinalizeBlock) + err = resp.Unmarshal(buf) if err != nil { - // DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED - tmos.Exit(fmt.Sprintf(`LoadABCIResponses: Data has been corrupted or its spec has - changed: %v\n`, err)) + // The data might be of the legacy ABCI response type, so + // we try to unmarshal that + legacyResp := new(tmstate.LegacyABCIResponses) + rerr := legacyResp.Unmarshal(buf) + if rerr != nil { + // DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED + tmos.Exit(fmt.Sprintf(`LoadFinalizeBlockResponse: Data has been corrupted or its spec has + changed: %v\n`, err)) + } + // The state store contains the old format. Migrate to + // the new ResponseFinalizeBlock format. Note that the + // new struct expects the AgreedAppData which we don't have. + return responseFinalizeBlockFromLegacy(legacyResp), nil } + // TODO: ensure that buf is completely read. - return abciResponses, nil + return resp, nil } -// LoadLastABCIResponses loads the ABCIResponses from the most recent height. +// LoadLastFinalizeBlockResponses loads the FinalizeBlockResponses from the most recent height. // The height parameter is used to ensure that the response corresponds to the latest height. // If not, an error is returned. // // This method is used for recovering in the case that we called the Commit ABCI // method on the application but crashed before persisting the results. -func (store dbStore) LoadLastABCIResponse(height int64) (*tmstate.ABCIResponses, error) { +func (store dbStore) LoadLastFinalizeBlockResponse(height int64) (*abci.ResponseFinalizeBlock, error) { bz, err := store.db.Get(lastABCIResponseKey) if err != nil { return nil, err @@ -420,41 +430,52 @@ func (store dbStore) LoadLastABCIResponse(height int64) (*tmstate.ABCIResponses, return nil, errors.New("no last ABCI response has been persisted") } - abciResponse := new(tmstate.ABCIResponsesInfo) - err = abciResponse.Unmarshal(bz) + info := new(tmstate.ABCIResponsesInfo) + err = info.Unmarshal(bz) if err != nil { - tmos.Exit(fmt.Sprintf(`LoadLastABCIResponses: Data has been corrupted or its spec has + tmos.Exit(fmt.Sprintf(`LoadLastFinalizeBlockResponse: Data has been corrupted or its spec has changed: %v\n`, err)) } // Here we validate the result by comparing its height to the expected height. - if height != abciResponse.GetHeight() { - return nil, errors.New("expected height %d but last stored abci responses was at height %d") + if height != info.GetHeight() { + return nil, fmt.Errorf("expected height %d but last stored abci responses was at height %d", height, info.GetHeight()) } - return abciResponse.AbciResponses, nil + // It is possible if this is called directly after an upgrade that + // ResponseFinalizeBlock is nil. In which case we use the legacy + // ABCI responses + if info.ResponseFinalizeBlock == nil { + // sanity check + if info.LegacyAbciResponses == nil { + panic("state store contains last abci response but it is empty") + } + return responseFinalizeBlockFromLegacy(info.LegacyAbciResponses), nil + } + + return info.ResponseFinalizeBlock, nil } -// SaveABCIResponses persists the ABCIResponses to the database. +// SaveFinalizeBlockResponse persists the ResponseFinalizeBlock to the database. // This is useful in case we crash after app.Commit and before s.Save(). // Responses are indexed by height so they can also be loaded later to produce // Merkle proofs. // // CONTRACT: height must be monotonically increasing every time this is called. -func (store dbStore) SaveABCIResponses(height int64, abciResponses *tmstate.ABCIResponses) error { - var dtxs []*abci.ResponseDeliverTx +func (store dbStore) SaveFinalizeBlockResponse(height int64, resp *abci.ResponseFinalizeBlock) error { + var dtxs []*abci.ExecTxResult // strip nil values, - for _, tx := range abciResponses.DeliverTxs { + for _, tx := range resp.TxResults { if tx != nil { dtxs = append(dtxs, tx) } } - abciResponses.DeliverTxs = dtxs + resp.TxResults = dtxs // If the flag is false then we save the ABCIResponse. This can be used for the /BlockResults // query or to reindex an event using the command line. if !store.DiscardABCIResponses { - bz, err := abciResponses.Marshal() + bz, err := resp.Marshal() if err != nil { return err } @@ -466,8 +487,8 @@ func (store dbStore) SaveABCIResponses(height int64, abciResponses *tmstate.ABCI // We always save the last ABCI response for crash recovery. // This overwrites the previous saved ABCI Response. response := &tmstate.ABCIResponsesInfo{ - AbciResponses: abciResponses, - Height: height, + ResponseFinalizeBlock: resp, + Height: height, } bz, err := response.Marshal() if err != nil { @@ -671,3 +692,16 @@ func min(a int64, b int64) int64 { } return b } + +// responseFinalizeBlockFromLegacy is a convenience function that takes the old abci responses and morphs +// it to the finalize block response. Note that the agreed app data is missing +func responseFinalizeBlockFromLegacy(legacyResp *tmstate.LegacyABCIResponses) *abci.ResponseFinalizeBlock { + return &abci.ResponseFinalizeBlock{ + TxResults: legacyResp.DeliverTxs, + ValidatorUpdates: legacyResp.EndBlock.ValidatorUpdates, + ConsensusParamUpdates: legacyResp.EndBlock.ConsensusParamUpdates, + Events: append(legacyResp.BeginBlock.Events, legacyResp.EndBlock.Events...), + // NOTE: AgreedAppData is missing in the response but will + // be caught and filled in consensus/replay.go + } +} diff --git a/state/store_test.go b/state/store_test.go index 4d467c559..773ec4346 100644 --- a/state/store_test.go +++ b/state/store_test.go @@ -154,8 +154,8 @@ func TestPruneStates(t *testing.T) { err := stateStore.Save(state) require.NoError(t, err) - err = stateStore.SaveABCIResponses(h, &tmstate.ABCIResponses{ - DeliverTxs: []*abci.ResponseDeliverTx{ + err = stateStore.SaveFinalizeBlockResponse(h, &abci.ResponseFinalizeBlock{ + TxResults: []*abci.ExecTxResult{ {Data: []byte{1}}, {Data: []byte{2}}, {Data: []byte{3}}, @@ -195,7 +195,7 @@ func TestPruneStates(t *testing.T) { require.Empty(t, params) } - abci, err := stateStore.LoadABCIResponses(h) + abci, err := stateStore.LoadFinalizeBlockResponse(h) if expectABCI[h] { require.NoError(t, err, "abci height %v", h) require.NotNil(t, abci) @@ -208,22 +208,18 @@ func TestPruneStates(t *testing.T) { } } -func TestABCIResponsesResultsHash(t *testing.T) { - responses := &tmstate.ABCIResponses{ - BeginBlock: &abci.ResponseBeginBlock{}, - DeliverTxs: []*abci.ResponseDeliverTx{ - {Code: 32, Data: []byte("Hello"), Log: "Huh?"}, - }, - EndBlock: &abci.ResponseEndBlock{}, +func TestTxResultsHash(t *testing.T) { + txResults := []*abci.ExecTxResult{ + {Code: 32, Data: []byte("Hello"), Log: "Huh?"}, } - root := sm.ABCIResponsesResultsHash(responses) + root := sm.TxResultsHash(txResults) - // root should be Merkle tree root of DeliverTxs responses - results := types.NewResults(responses.DeliverTxs) + // root should be Merkle tree root of ExecTxResult responses + results := types.NewResults(txResults) assert.Equal(t, root, results.Hash()) - // test we can prove first DeliverTx + // test we can prove first ExecTxResult proof := results.ProveResult(0) bz, err := results[0].Marshal() require.NoError(t, err) @@ -238,41 +234,39 @@ func sliceToMap(s []int64) map[int64]bool { return m } -func TestLastABCIResponses(t *testing.T) { +func TestLastFinalizeBlockResponses(t *testing.T) { // create an empty state store. t.Run("Not persisting responses", func(t *testing.T) { stateDB := dbm.NewMemDB() stateStore := sm.NewStore(stateDB, sm.StoreOptions{ DiscardABCIResponses: false, }) - responses, err := stateStore.LoadABCIResponses(1) + responses, err := stateStore.LoadFinalizeBlockResponse(1) require.Error(t, err) require.Nil(t, responses) // stub the abciresponses. - response1 := &tmstate.ABCIResponses{ - BeginBlock: &abci.ResponseBeginBlock{}, - DeliverTxs: []*abci.ResponseDeliverTx{ + response1 := &abci.ResponseFinalizeBlock{ + TxResults: []*abci.ExecTxResult{ {Code: 32, Data: []byte("Hello"), Log: "Huh?"}, }, - EndBlock: &abci.ResponseEndBlock{}, } // create new db and state store and set discard abciresponses to false. stateDB = dbm.NewMemDB() stateStore = sm.NewStore(stateDB, sm.StoreOptions{DiscardABCIResponses: false}) height := int64(10) // save the last abci response. - err = stateStore.SaveABCIResponses(height, response1) + err = stateStore.SaveFinalizeBlockResponse(height, response1) require.NoError(t, err) - // search for the last abciresponse and check if it has saved. - lastResponse, err := stateStore.LoadLastABCIResponse(height) + // search for the last finalize block response and check if it has saved. + lastResponse, err := stateStore.LoadLastFinalizeBlockResponse(height) require.NoError(t, err) // check to see if the saved response height is the same as the loaded height. assert.Equal(t, lastResponse, response1) // use an incorret height to make sure the state store errors. - _, err = stateStore.LoadLastABCIResponse(height + 1) + _, err = stateStore.LoadLastFinalizeBlockResponse(height + 1) assert.Error(t, err) // check if the abci response didnt save in the abciresponses. - responses, err = stateStore.LoadABCIResponses(height) + responses, err = stateStore.LoadFinalizeBlockResponse(height) require.NoError(t, err, responses) require.Equal(t, response1, responses) }) @@ -281,28 +275,71 @@ func TestLastABCIResponses(t *testing.T) { stateDB := dbm.NewMemDB() height := int64(10) // stub the second abciresponse. - response2 := &tmstate.ABCIResponses{ - BeginBlock: &abci.ResponseBeginBlock{}, - DeliverTxs: []*abci.ResponseDeliverTx{ + response2 := &abci.ResponseFinalizeBlock{ + TxResults: []*abci.ExecTxResult{ {Code: 44, Data: []byte("Hello again"), Log: "????"}, }, - EndBlock: &abci.ResponseEndBlock{}, } // create a new statestore with the responses on. stateStore := sm.NewStore(stateDB, sm.StoreOptions{ DiscardABCIResponses: true, }) // save an additional response. - err := stateStore.SaveABCIResponses(height+1, response2) + err := stateStore.SaveFinalizeBlockResponse(height+1, response2) require.NoError(t, err) // check to see if the response saved by calling the last response. - lastResponse2, err := stateStore.LoadLastABCIResponse(height + 1) + lastResponse2, err := stateStore.LoadLastFinalizeBlockResponse(height + 1) require.NoError(t, err) // check to see if the saved response height is the same as the loaded height. assert.Equal(t, response2, lastResponse2) // should error as we are no longer saving the response. - _, err = stateStore.LoadABCIResponses(height + 1) - assert.Equal(t, sm.ErrABCIResponsesNotPersisted, err) + _, err = stateStore.LoadFinalizeBlockResponse(height + 1) + assert.Equal(t, sm.ErrFinalizeBlockResponsesNotPersisted, err) }) } + +func TestFinalizeBlockRecoveryUsingLegacyABCIResponses(t *testing.T) { + var ( + height int64 = 10 + lastABCIResponseKey = []byte("lastABCIResponseKey") + memDB = dbm.NewMemDB() + cp = types.DefaultConsensusParams().ToProto() + legacyResp = tmstate.ABCIResponsesInfo{ + LegacyAbciResponses: &tmstate.LegacyABCIResponses{ + BeginBlock: &tmstate.ResponseBeginBlock{ + Events: []abci.Event{{ + Type: "begin_block", + Attributes: []abci.EventAttribute{{ + Key: "key", + Value: "value", + }}, + }}, + }, + DeliverTxs: []*abci.ExecTxResult{{ + Events: []abci.Event{{ + Type: "tx", + Attributes: []abci.EventAttribute{{ + Key: "key", + Value: "value", + }}, + }}, + }}, + EndBlock: &tmstate.ResponseEndBlock{ + ConsensusParamUpdates: &cp, + }, + }, + Height: height, + } + ) + bz, err := legacyResp.Marshal() + require.NoError(t, err) + // should keep this in parity with state/store.go + require.NoError(t, memDB.Set(lastABCIResponseKey, bz)) + stateStore := sm.NewStore(memDB, sm.StoreOptions{DiscardABCIResponses: false}) + resp, err := stateStore.LoadLastFinalizeBlockResponse(height) + require.NoError(t, err) + require.Equal(t, resp.ConsensusParamUpdates, &cp) + require.Equal(t, resp.Events, legacyResp.LegacyAbciResponses.BeginBlock.Events) + require.Equal(t, resp.TxResults[0], legacyResp.LegacyAbciResponses.DeliverTxs[0]) +} diff --git a/state/txindex/indexer_service.go b/state/txindex/indexer_service.go index 0e8fbb9c9..119d2df1d 100644 --- a/state/txindex/indexer_service.go +++ b/state/txindex/indexer_service.go @@ -44,10 +44,10 @@ func (is *IndexerService) OnStart() error { // Use SubscribeUnbuffered here to ensure both subscriptions does not get // canceled due to not pulling messages fast enough. Cause this might // sometimes happen when there are no other subscribers. - blockHeadersSub, err := is.eventBus.SubscribeUnbuffered( + blockSub, err := is.eventBus.SubscribeUnbuffered( context.Background(), subscriber, - types.EventQueryNewBlockHeader) + types.EventQueryNewBlockEvents) if err != nil { return err } @@ -59,12 +59,14 @@ func (is *IndexerService) OnStart() error { go func() { for { - msg := <-blockHeadersSub.Out() - eventDataHeader := msg.Data().(types.EventDataNewBlockHeader) - height := eventDataHeader.Header.Height - batch := NewBatch(eventDataHeader.NumTxs) + msg := <-blockSub.Out() + eventNewBlockEvents := msg.Data().(types.EventDataNewBlockEvents) + height := eventNewBlockEvents.Height + numTxs := eventNewBlockEvents.NumTxs - for i := int64(0); i < eventDataHeader.NumTxs; i++ { + batch := NewBatch(numTxs) + + for i := int64(0); i < numTxs; i++ { msg2 := <-txsSub.Out() txResult := msg2.Data().(types.EventDataTx).TxResult @@ -85,7 +87,7 @@ func (is *IndexerService) OnStart() error { } } - if err := is.blockIdxr.Index(eventDataHeader); err != nil { + if err := is.blockIdxr.Index(eventNewBlockEvents); err != nil { is.Logger.Error("failed to index block", "height", height, "err", err) if is.terminateOnError { if err := is.Stop(); err != nil { @@ -106,7 +108,7 @@ func (is *IndexerService) OnStart() error { return } } else { - is.Logger.Debug("indexed transactions", "height", height, "num_txs", eventDataHeader.NumTxs) + is.Logger.Debug("indexed block txs", "height", height, "num_txs", numTxs) } } }() diff --git a/state/txindex/indexer_service_test.go b/state/txindex/indexer_service_test.go index 8c7dca2ac..5df9bb322 100644 --- a/state/txindex/indexer_service_test.go +++ b/state/txindex/indexer_service_test.go @@ -42,9 +42,21 @@ func TestIndexerServiceIndexesBlocks(t *testing.T) { } }) - // publish block with txs - err = eventBus.PublishEventNewBlockHeader(types.EventDataNewBlockHeader{ - Header: types.Header{Height: 1}, + // publish block with events + err = eventBus.PublishEventNewBlockEvents(types.EventDataNewBlockEvents{ + Height: 1, + Events: []abci.Event{ + { + Type: "begin_event", + Attributes: []abci.EventAttribute{ + { + Key: "proposer", + Value: "FCAA001", + Index: true, + }, + }, + }, + }, NumTxs: int64(2), }) require.NoError(t, err) @@ -52,7 +64,7 @@ func TestIndexerServiceIndexesBlocks(t *testing.T) { Height: 1, Index: uint32(0), Tx: types.Tx("foo"), - Result: abci.ResponseDeliverTx{Code: 0}, + Result: abci.ExecTxResult{Code: 0}, } err = eventBus.PublishEventTx(types.EventDataTx{TxResult: *txResult1}) require.NoError(t, err) @@ -60,7 +72,7 @@ func TestIndexerServiceIndexesBlocks(t *testing.T) { Height: 1, Index: uint32(1), Tx: types.Tx("bar"), - Result: abci.ResponseDeliverTx{Code: 0}, + Result: abci.ExecTxResult{Code: 0}, } err = eventBus.PublishEventTx(types.EventDataTx{TxResult: *txResult2}) require.NoError(t, err) diff --git a/state/txindex/kv/kv_bench_test.go b/state/txindex/kv/kv_bench_test.go index 97cbaf1f1..00cfde227 100644 --- a/state/txindex/kv/kv_bench_test.go +++ b/state/txindex/kv/kv_bench_test.go @@ -47,7 +47,7 @@ func BenchmarkTxSearch(b *testing.B) { Height: int64(i), Index: 0, Tx: types.Tx(string(txBz)), - Result: abci.ResponseDeliverTx{ + Result: abci.ExecTxResult{ Data: []byte{0}, Code: abci.CodeTypeOK, Log: "", diff --git a/state/txindex/kv/kv_test.go b/state/txindex/kv/kv_test.go index b5f2d65cd..ee22f7011 100644 --- a/state/txindex/kv/kv_test.go +++ b/state/txindex/kv/kv_test.go @@ -27,7 +27,7 @@ func TestTxIndex(t *testing.T) { Height: 1, Index: 0, Tx: tx, - Result: abci.ResponseDeliverTx{ + Result: abci.ExecTxResult{ Data: []byte{0}, Code: abci.CodeTypeOK, Log: "", Events: nil, }, @@ -50,7 +50,7 @@ func TestTxIndex(t *testing.T) { Height: 1, Index: 0, Tx: tx2, - Result: abci.ResponseDeliverTx{ + Result: abci.ExecTxResult{ Data: []byte{0}, Code: abci.CodeTypeOK, Log: "", Events: nil, }, @@ -273,7 +273,7 @@ func TestTxIndexDuplicatePreviouslySuccessful(t *testing.T) { Height: 1, Index: 0, Tx: mockTx, - Result: abci.ResponseDeliverTx{ + Result: abci.ExecTxResult{ Code: abci.CodeTypeOK, }, }, @@ -281,7 +281,7 @@ func TestTxIndexDuplicatePreviouslySuccessful(t *testing.T) { Height: 2, Index: 0, Tx: mockTx, - Result: abci.ResponseDeliverTx{ + Result: abci.ExecTxResult{ Code: abci.CodeTypeOK + 1, }, }, @@ -293,7 +293,7 @@ func TestTxIndexDuplicatePreviouslySuccessful(t *testing.T) { Height: 1, Index: 0, Tx: mockTx, - Result: abci.ResponseDeliverTx{ + Result: abci.ExecTxResult{ Code: abci.CodeTypeOK + 1, }, }, @@ -301,7 +301,7 @@ func TestTxIndexDuplicatePreviouslySuccessful(t *testing.T) { Height: 2, Index: 0, Tx: mockTx, - Result: abci.ResponseDeliverTx{ + Result: abci.ExecTxResult{ Code: abci.CodeTypeOK + 1, }, }, @@ -313,7 +313,7 @@ func TestTxIndexDuplicatePreviouslySuccessful(t *testing.T) { Height: 1, Index: 0, Tx: mockTx, - Result: abci.ResponseDeliverTx{ + Result: abci.ExecTxResult{ Code: abci.CodeTypeOK, }, }, @@ -321,7 +321,7 @@ func TestTxIndexDuplicatePreviouslySuccessful(t *testing.T) { Height: 2, Index: 0, Tx: mockTx, - Result: abci.ResponseDeliverTx{ + Result: abci.ExecTxResult{ Code: abci.CodeTypeOK, }, }, @@ -415,7 +415,7 @@ func txResultWithEvents(events []abci.Event) *abci.TxResult { Height: 1, Index: 0, Tx: tx, - Result: abci.ResponseDeliverTx{ + Result: abci.ExecTxResult{ Data: []byte{0}, Code: abci.CodeTypeOK, Log: "", @@ -441,7 +441,7 @@ func benchmarkTxIndex(txsCount int64, b *testing.B) { Height: 1, Index: txIndex, Tx: tx, - Result: abci.ResponseDeliverTx{ + Result: abci.ExecTxResult{ Data: []byte{0}, Code: abci.CodeTypeOK, Log: "", diff --git a/statesync/reactor.go b/statesync/reactor.go index d650a6a55..c898a3ee9 100644 --- a/statesync/reactor.go +++ b/statesync/reactor.go @@ -1,6 +1,7 @@ package statesync import ( + "context" "errors" "sort" "time" @@ -172,7 +173,7 @@ func (r *Reactor) Receive(e p2p.Envelope) { case *ssproto.ChunkRequest: r.Logger.Debug("Received chunk request", "height", msg.Height, "format", msg.Format, "chunk", msg.Index, "peer", e.Src.ID()) - resp, err := r.conn.LoadSnapshotChunkSync(abci.RequestLoadSnapshotChunk{ + resp, err := r.conn.LoadSnapshotChunk(context.TODO(), &abci.RequestLoadSnapshotChunk{ Height: msg.Height, Format: msg.Format, Chunk: msg.Index, @@ -228,7 +229,7 @@ func (r *Reactor) Receive(e p2p.Envelope) { // recentSnapshots fetches the n most recent snapshots from the app func (r *Reactor) recentSnapshots(n uint32) ([]*snapshot, error) { - resp, err := r.conn.ListSnapshotsSync(abci.RequestListSnapshots{}) + resp, err := r.conn.ListSnapshots(context.TODO(), &abci.RequestListSnapshots{}) if err != nil { return nil, err } diff --git a/statesync/reactor_test.go b/statesync/reactor_test.go index eed3b2361..3a08af771 100644 --- a/statesync/reactor_test.go +++ b/statesync/reactor_test.go @@ -43,7 +43,7 @@ func TestReactor_Receive_ChunkRequest(t *testing.T) { t.Run(name, func(t *testing.T) { // Mock ABCI connection to return local snapshots conn := &proxymocks.AppConnSnapshot{} - conn.On("LoadSnapshotChunkSync", abci.RequestLoadSnapshotChunk{ + conn.On("LoadSnapshotChunk", mock.Anything, &abci.RequestLoadSnapshotChunk{ Height: tc.request.Height, Format: tc.request.Format, Chunk: tc.request.Index, @@ -135,7 +135,7 @@ func TestReactor_Receive_SnapshotsRequest(t *testing.T) { t.Run(name, func(t *testing.T) { // Mock ABCI connection to return local snapshots conn := &proxymocks.AppConnSnapshot{} - conn.On("ListSnapshotsSync", abci.RequestListSnapshots{}).Return(&abci.ResponseListSnapshots{ + conn.On("ListSnapshots", mock.Anything, &abci.RequestListSnapshots{}).Return(&abci.ResponseListSnapshots{ Snapshots: tc.snapshots, }, nil) diff --git a/statesync/syncer.go b/statesync/syncer.go index 6be091886..51ad0dd0a 100644 --- a/statesync/syncer.go +++ b/statesync/syncer.go @@ -322,7 +322,7 @@ func (s *syncer) Sync(snapshot *snapshot, chunks *chunkQueue) (sm.State, *types. func (s *syncer) offerSnapshot(snapshot *snapshot) error { s.logger.Info("Offering snapshot to ABCI app", "height", snapshot.Height, "format", snapshot.Format, "hash", log.NewLazySprintf("%X", snapshot.Hash)) - resp, err := s.conn.OfferSnapshotSync(abci.RequestOfferSnapshot{ + resp, err := s.conn.OfferSnapshot(context.TODO(), &abci.RequestOfferSnapshot{ Snapshot: &abci.Snapshot{ Height: snapshot.Height, Format: snapshot.Format, @@ -364,7 +364,7 @@ func (s *syncer) applyChunks(chunks *chunkQueue) error { return fmt.Errorf("failed to fetch chunk: %w", err) } - resp, err := s.conn.ApplySnapshotChunkSync(abci.RequestApplySnapshotChunk{ + resp, err := s.conn.ApplySnapshotChunk(context.TODO(), &abci.RequestApplySnapshotChunk{ Index: chunk.Index, Chunk: chunk.Chunk, Sender: string(chunk.Sender), @@ -483,7 +483,7 @@ func (s *syncer) requestChunk(snapshot *snapshot, chunk uint32) { // verifyApp verifies the sync, checking the app hash, last block height and app version func (s *syncer) verifyApp(snapshot *snapshot, appVersion uint64) error { - resp, err := s.connQuery.InfoSync(proxy.RequestInfo) + resp, err := s.connQuery.Info(context.TODO(), proxy.RequestInfo) if err != nil { return fmt.Errorf("failed to query ABCI app for appHash: %w", err) } diff --git a/statesync/syncer_test.go b/statesync/syncer_test.go index 100349eb3..aa07f15f6 100644 --- a/statesync/syncer_test.go +++ b/statesync/syncer_test.go @@ -138,7 +138,7 @@ func TestSyncer_SyncAny(t *testing.T) { // We start a sync, with peers sending back chunks when requested. We first reject the snapshot // with height 2 format 2, and accept the snapshot at height 1. - connSnapshot.On("OfferSnapshotSync", abci.RequestOfferSnapshot{ + connSnapshot.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{ Snapshot: &abci.Snapshot{ Height: 2, Format: 2, @@ -147,7 +147,7 @@ func TestSyncer_SyncAny(t *testing.T) { }, AppHash: []byte("app_hash_2"), }).Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT_FORMAT}, nil) - connSnapshot.On("OfferSnapshotSync", abci.RequestOfferSnapshot{ + connSnapshot.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{ Snapshot: &abci.Snapshot{ Height: s.Height, Format: s.Format, @@ -188,7 +188,7 @@ func TestSyncer_SyncAny(t *testing.T) { // The first time we're applying chunk 2 we tell it to retry the snapshot and discard chunk 1, // which should cause it to keep the existing chunk 0 and 2, and restart restoration from // beginning. We also wait for a little while, to exercise the retry logic in fetchChunks(). - connSnapshot.On("ApplySnapshotChunkSync", abci.RequestApplySnapshotChunk{ + connSnapshot.On("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{ @@ -196,16 +196,16 @@ func TestSyncer_SyncAny(t *testing.T) { RefetchChunks: []uint32{1}, }, nil) - connSnapshot.On("ApplySnapshotChunkSync", 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", 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", 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", proxy.RequestInfo).Return(&abci.ResponseInfo{ + connQuery.On("Info", mock.Anything, proxy.RequestInfo).Return(&abci.ResponseInfo{ AppVersion: testAppVersion, LastBlockHeight: 1, LastBlockAppHash: []byte("app_hash"), @@ -243,7 +243,7 @@ func TestSyncer_SyncAny_abort(t *testing.T) { s := &snapshot{Height: 1, Format: 1, Chunks: 3, Hash: []byte{1, 2, 3}} _, err := syncer.AddSnapshot(simplePeer("id"), s) require.NoError(t, err) - connSnapshot.On("OfferSnapshotSync", abci.RequestOfferSnapshot{ + connSnapshot.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{ Snapshot: toABCI(s), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ABORT}, nil) @@ -266,15 +266,15 @@ func TestSyncer_SyncAny_reject(t *testing.T) { _, err = syncer.AddSnapshot(simplePeer("id"), s11) require.NoError(t, err) - connSnapshot.On("OfferSnapshotSync", abci.RequestOfferSnapshot{ + connSnapshot.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{ Snapshot: toABCI(s22), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT}, nil) - connSnapshot.On("OfferSnapshotSync", abci.RequestOfferSnapshot{ + connSnapshot.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{ Snapshot: toABCI(s12), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT}, nil) - connSnapshot.On("OfferSnapshotSync", abci.RequestOfferSnapshot{ + connSnapshot.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{ Snapshot: toABCI(s11), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT}, nil) @@ -297,11 +297,11 @@ func TestSyncer_SyncAny_reject_format(t *testing.T) { _, err = syncer.AddSnapshot(simplePeer("id"), s11) require.NoError(t, err) - connSnapshot.On("OfferSnapshotSync", abci.RequestOfferSnapshot{ + connSnapshot.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{ Snapshot: toABCI(s22), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT_FORMAT}, nil) - connSnapshot.On("OfferSnapshotSync", abci.RequestOfferSnapshot{ + connSnapshot.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{ Snapshot: toABCI(s11), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ABORT}, nil) @@ -335,11 +335,11 @@ func TestSyncer_SyncAny_reject_sender(t *testing.T) { _, err = syncer.AddSnapshot(peerC, sbc) require.NoError(t, err) - connSnapshot.On("OfferSnapshotSync", abci.RequestOfferSnapshot{ + connSnapshot.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{ Snapshot: toABCI(sbc), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT_SENDER}, nil) - connSnapshot.On("OfferSnapshotSync", abci.RequestOfferSnapshot{ + connSnapshot.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{ Snapshot: toABCI(sa), AppHash: []byte("app_hash"), }).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT}, nil) @@ -355,7 +355,7 @@ func TestSyncer_SyncAny_abciError(t *testing.T) { s := &snapshot{Height: 1, Format: 1, Chunks: 3, Hash: []byte{1, 2, 3}} _, err := syncer.AddSnapshot(simplePeer("id"), s) require.NoError(t, err) - connSnapshot.On("OfferSnapshotSync", abci.RequestOfferSnapshot{ + connSnapshot.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{ Snapshot: toABCI(s), AppHash: []byte("app_hash"), }).Once().Return(nil, errBoom) @@ -387,7 +387,7 @@ func TestSyncer_offerSnapshot(t *testing.T) { t.Run(name, func(t *testing.T) { syncer, connSnapshot := setupOfferSyncer(t) s := &snapshot{Height: 1, Format: 1, Chunks: 3, Hash: []byte{1, 2, 3}, trustedAppHash: []byte("app_hash")} - connSnapshot.On("OfferSnapshotSync", abci.RequestOfferSnapshot{ + connSnapshot.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{ Snapshot: toABCI(s), AppHash: []byte("app_hash"), }).Return(&abci.ResponseOfferSnapshot{Result: tc.result}, tc.err) @@ -440,11 +440,11 @@ func TestSyncer_applyChunks_Results(t *testing.T) { _, err = chunks.Add(&chunk{Height: 1, Format: 1, Index: 0, Chunk: body}) require.NoError(t, err) - connSnapshot.On("ApplySnapshotChunkSync", abci.RequestApplySnapshotChunk{ + connSnapshot.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{ Index: 0, Chunk: body, }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: tc.result}, tc.err) if tc.result == abci.ResponseApplySnapshotChunk_RETRY { - connSnapshot.On("ApplySnapshotChunkSync", abci.RequestApplySnapshotChunk{ + connSnapshot.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{ Index: 0, Chunk: body, }).Once().Return(&abci.ResponseApplySnapshotChunk{ Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) @@ -500,13 +500,13 @@ func TestSyncer_applyChunks_RefetchChunks(t *testing.T) { require.NoError(t, err) // The first two chunks are accepted, before the last one asks for 1 to be refetched - connSnapshot.On("ApplySnapshotChunkSync", abci.RequestApplySnapshotChunk{ + connSnapshot.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{ Index: 0, Chunk: []byte{0}, }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) - connSnapshot.On("ApplySnapshotChunkSync", abci.RequestApplySnapshotChunk{ + connSnapshot.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{ Index: 1, Chunk: []byte{1}, }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) - connSnapshot.On("ApplySnapshotChunkSync", abci.RequestApplySnapshotChunk{ + connSnapshot.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{ Index: 2, Chunk: []byte{2}, }).Once().Return(&abci.ResponseApplySnapshotChunk{ Result: tc.result, @@ -586,13 +586,13 @@ func TestSyncer_applyChunks_RejectSenders(t *testing.T) { require.NoError(t, err) // The first two chunks are accepted, before the last one asks for b sender to be rejected - connSnapshot.On("ApplySnapshotChunkSync", abci.RequestApplySnapshotChunk{ + connSnapshot.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{ Index: 0, Chunk: []byte{0}, Sender: "a", }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) - connSnapshot.On("ApplySnapshotChunkSync", abci.RequestApplySnapshotChunk{ + connSnapshot.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{ Index: 1, Chunk: []byte{1}, Sender: "b", }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) - connSnapshot.On("ApplySnapshotChunkSync", abci.RequestApplySnapshotChunk{ + connSnapshot.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{ Index: 2, Chunk: []byte{2}, Sender: "c", }).Once().Return(&abci.ResponseApplySnapshotChunk{ Result: tc.result, @@ -601,7 +601,7 @@ func TestSyncer_applyChunks_RejectSenders(t *testing.T) { // On retry, the last chunk will be tried again, so we just accept it then. if tc.result == abci.ResponseApplySnapshotChunk_RETRY { - connSnapshot.On("ApplySnapshotChunkSync", abci.RequestApplySnapshotChunk{ + connSnapshot.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{ Index: 2, Chunk: []byte{2}, Sender: "c", }).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil) } @@ -674,7 +674,7 @@ func TestSyncer_verifyApp(t *testing.T) { cfg := config.DefaultStateSyncConfig() syncer := newSyncer(*cfg, log.NewNopLogger(), connSnapshot, connQuery, stateProvider, "") - connQuery.On("InfoSync", proxy.RequestInfo).Return(tc.response, tc.err) + connQuery.On("Info", mock.Anything, proxy.RequestInfo).Return(tc.response, tc.err) err := syncer.verifyApp(s, appVersion) unwrapped := errors.Unwrap(err) if unwrapped != nil { diff --git a/test/e2e/app/app.go b/test/e2e/app/app.go index c145e03d1..a2f393977 100644 --- a/test/e2e/app/app.go +++ b/test/e2e/app/app.go @@ -2,6 +2,7 @@ package app import ( "bytes" + "context" "encoding/base64" "errors" "fmt" @@ -10,7 +11,7 @@ import ( "strconv" "time" - "github.com/tendermint/tendermint/abci/example/code" + "github.com/tendermint/tendermint/abci/example/kvstore" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/version" @@ -76,7 +77,8 @@ type Config struct { PrepareProposalDelay time.Duration `toml:"prepare_proposal_delay"` ProcessProposalDelay time.Duration `toml:"process_proposal_delay"` CheckTxDelay time.Duration `toml:"check_tx_delay"` - // TODO: add vote extension and finalize block delays once completed (@cmwaters) + FinalizeBlockDelay time.Duration `toml:"finalize_block_delay"` + // TODO: add vote extension delays once completed (@cmwaters) } func DefaultConfig(dir string) *Config { @@ -106,17 +108,17 @@ func NewApplication(cfg *Config) (abci.Application, error) { } // Info implements ABCI. -func (app *Application) Info(req abci.RequestInfo) abci.ResponseInfo { - return abci.ResponseInfo{ +func (app *Application) Info(_ context.Context, req *abci.RequestInfo) (*abci.ResponseInfo, error) { + return &abci.ResponseInfo{ Version: version.ABCIVersion, AppVersion: appVersion, LastBlockHeight: int64(app.state.Height), LastBlockAppHash: app.state.Hash, - } + }, nil } // Info implements ABCI. -func (app *Application) InitChain(req abci.RequestInitChain) abci.ResponseInitChain { +func (app *Application) InitChain(_ context.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) { var err error app.state.initialHeight = uint64(req.InitialHeight) if len(req.AppStateBytes) > 0 { @@ -125,51 +127,59 @@ func (app *Application) InitChain(req abci.RequestInitChain) abci.ResponseInitCh panic(err) } } - resp := abci.ResponseInitChain{ + resp := &abci.ResponseInitChain{ AppHash: app.state.Hash, } if resp.Validators, err = app.validatorUpdates(0); err != nil { panic(err) } - return resp + return resp, nil } // CheckTx implements ABCI. -func (app *Application) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx { +func (app *Application) CheckTx(_ context.Context, req *abci.RequestCheckTx) (*abci.ResponseCheckTx, error) { _, _, err := parseTx(req.Tx) if err != nil { - return abci.ResponseCheckTx{ - Code: code.CodeTypeEncodingError, + return &abci.ResponseCheckTx{ + Code: kvstore.CodeTypeEncodingError, Log: err.Error(), - } + }, nil } if app.cfg.CheckTxDelay != 0 { time.Sleep(app.cfg.CheckTxDelay) } - return abci.ResponseCheckTx{Code: code.CodeTypeOK, GasWanted: 1} + return &abci.ResponseCheckTx{Code: kvstore.CodeTypeOK, GasWanted: 1}, nil } -// DeliverTx implements ABCI. -func (app *Application) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx { - key, value, err := parseTx(req.Tx) - if err != nil { - panic(err) // shouldn't happen since we verified it in CheckTx +// FinalizeBlock implements ABCI. +func (app *Application) FinalizeBlock(_ context.Context, req *abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { + var txs = make([]*abci.ExecTxResult, len(req.Txs)) + + for i, tx := range req.Txs { + key, value, err := parseTx(tx) + if err != nil { + panic(err) // shouldn't happen since we verified it in CheckTx + } + app.state.Set(key, value) + + txs[i] = &abci.ExecTxResult{Code: kvstore.CodeTypeOK} } - app.state.Set(key, value) - return abci.ResponseDeliverTx{Code: code.CodeTypeOK} -} -// EndBlock implements ABCI. -func (app *Application) EndBlock(req abci.RequestEndBlock) abci.ResponseEndBlock { valUpdates, err := app.validatorUpdates(uint64(req.Height)) if err != nil { panic(err) } - return abci.ResponseEndBlock{ + if app.cfg.FinalizeBlockDelay != 0 { + time.Sleep(app.cfg.FinalizeBlockDelay) + } + + return &abci.ResponseFinalizeBlock{ + TxResults: txs, ValidatorUpdates: valUpdates, + AgreedAppData: app.state.Finalize(), Events: []abci.Event{ { Type: "val_updates", @@ -185,12 +195,12 @@ func (app *Application) EndBlock(req abci.RequestEndBlock) abci.ResponseEndBlock }, }, }, - } + }, nil } // Commit implements ABCI. -func (app *Application) Commit() abci.ResponseCommit { - height, hash, err := app.state.Commit() +func (app *Application) Commit(_ context.Context, _ *abci.RequestCommit) (*abci.ResponseCommit, error) { + height, err := app.state.Commit() if err != nil { panic(err) } @@ -199,57 +209,60 @@ func (app *Application) Commit() abci.ResponseCommit { if err != nil { panic(err) } - app.logger.Info("Created state sync snapshot", "height", snapshot.Height) + app.logger.Info("created state sync snapshot", "height", snapshot.Height) + err = app.snapshots.Prune(maxSnapshotCount) + if err != nil { + app.logger.Error("failed to prune snapshots", "err", err) + } } retainHeight := int64(0) if app.cfg.RetainBlocks > 0 { retainHeight = int64(height - app.cfg.RetainBlocks + 1) } - return abci.ResponseCommit{ - Data: hash, + return &abci.ResponseCommit{ RetainHeight: retainHeight, - } + }, nil } // Query implements ABCI. -func (app *Application) Query(req abci.RequestQuery) abci.ResponseQuery { - return abci.ResponseQuery{ +func (app *Application) Query(_ context.Context, req *abci.RequestQuery) (*abci.ResponseQuery, error) { + return &abci.ResponseQuery{ Height: int64(app.state.Height), Key: req.Data, Value: []byte(app.state.Get(string(req.Data))), - } + }, nil } // ListSnapshots implements ABCI. -func (app *Application) ListSnapshots(req abci.RequestListSnapshots) abci.ResponseListSnapshots { +func (app *Application) ListSnapshots(_ context.Context, req *abci.RequestListSnapshots) (*abci.ResponseListSnapshots, error) { snapshots, err := app.snapshots.List() if err != nil { panic(err) } - return abci.ResponseListSnapshots{Snapshots: snapshots} + return &abci.ResponseListSnapshots{Snapshots: snapshots}, nil } // LoadSnapshotChunk implements ABCI. -func (app *Application) LoadSnapshotChunk(req abci.RequestLoadSnapshotChunk) abci.ResponseLoadSnapshotChunk { +func (app *Application) LoadSnapshotChunk(_ context.Context, req *abci.RequestLoadSnapshotChunk) (*abci.ResponseLoadSnapshotChunk, error) { chunk, err := app.snapshots.LoadChunk(req.Height, req.Format, req.Chunk) if err != nil { panic(err) } - return abci.ResponseLoadSnapshotChunk{Chunk: chunk} + return &abci.ResponseLoadSnapshotChunk{Chunk: chunk}, nil } // OfferSnapshot implements ABCI. -func (app *Application) OfferSnapshot(req abci.RequestOfferSnapshot) abci.ResponseOfferSnapshot { +func (app *Application) OfferSnapshot(_ context.Context, req *abci.RequestOfferSnapshot) (*abci.ResponseOfferSnapshot, error) { if app.restoreSnapshot != nil { panic("A snapshot is already being restored") } app.restoreSnapshot = req.Snapshot app.restoreChunks = [][]byte{} - return abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ACCEPT} + return &abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ACCEPT}, nil } // ApplySnapshotChunk implements ABCI. -func (app *Application) ApplySnapshotChunk(req abci.RequestApplySnapshotChunk) abci.ResponseApplySnapshotChunk { +func (app *Application) ApplySnapshotChunk(_ context.Context, req *abci.RequestApplySnapshotChunk) (*abci.ResponseApplySnapshotChunk, error) { if app.restoreSnapshot == nil { panic("No restore in progress") } @@ -266,12 +279,11 @@ func (app *Application) ApplySnapshotChunk(req abci.RequestApplySnapshotChunk) a app.restoreSnapshot = nil app.restoreChunks = nil } - return abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT} + return &abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil } func (app *Application) PrepareProposal( - req abci.RequestPrepareProposal, -) abci.ResponsePrepareProposal { + _ context.Context, req *abci.RequestPrepareProposal) (*abci.ResponsePrepareProposal, error) { txs := make([][]byte, 0, len(req.Txs)) var totalBytes int64 for _, tx := range req.Txs { @@ -286,16 +298,16 @@ func (app *Application) PrepareProposal( time.Sleep(app.cfg.PrepareProposalDelay) } - return abci.ResponsePrepareProposal{Txs: txs} + return &abci.ResponsePrepareProposal{Txs: txs}, nil } // ProcessProposal implements part of the Application interface. // It accepts any proposal that does not contain a malformed transaction. -func (app *Application) ProcessProposal(req abci.RequestProcessProposal) abci.ResponseProcessProposal { +func (app *Application) ProcessProposal(_ context.Context, req *abci.RequestProcessProposal) (*abci.ResponseProcessProposal, error) { for _, tx := range req.Txs { _, _, err := parseTx(tx) if err != nil { - return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT} + return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}, nil } } @@ -303,7 +315,7 @@ func (app *Application) ProcessProposal(req abci.RequestProcessProposal) abci.Re time.Sleep(app.cfg.ProcessProposalDelay) } - return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT} + return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}, nil } func (app *Application) Rollback() error { diff --git a/test/e2e/app/snapshots.go b/test/e2e/app/snapshots.go index bd6c8686a..26438d7ce 100644 --- a/test/e2e/app/snapshots.go +++ b/test/e2e/app/snapshots.go @@ -14,6 +14,9 @@ import ( const ( snapshotChunkSize = 1e6 + + // Keep only the most recent 10 snapshots. Older snapshots are pruned + maxSnapshotCount = 10 ) // SnapshotStore stores state sync snapshots. Snapshots are stored simply as @@ -28,7 +31,7 @@ type SnapshotStore struct { // NewSnapshotStore creates a new snapshot store. func NewSnapshotStore(dir string) (*SnapshotStore, error) { store := &SnapshotStore{dir: dir} - if err := os.MkdirAll(dir, 0o755); err != nil { + if err := os.MkdirAll(dir, 0755); err != nil { return nil, err } if err := store.loadMetadata(); err != nil { @@ -88,7 +91,7 @@ func (s *SnapshotStore) Create(state *State) (abci.Snapshot, error) { snapshot := abci.Snapshot{ Height: state.Height, Format: 1, - Hash: hashItems(state.Values), + Hash: hashItems(state.Values, state.Height), Chunks: byteChunks(bz), } err = os.WriteFile(filepath.Join(s.dir, fmt.Sprintf("%v.json", state.Height)), bz, 0o644) //nolint:gosec @@ -103,6 +106,27 @@ func (s *SnapshotStore) Create(state *State) (abci.Snapshot, error) { return snapshot, nil } +// Prune removes old snapshots ensuring only the most recent n snapshots remain +func (s *SnapshotStore) Prune(n int) error { + s.Lock() + defer s.Unlock() + // snapshots are appended to the metadata struct, hence pruning removes from + // the front of the array + i := 0 + for ; i < len(s.metadata)-n; i++ { + h := s.metadata[i].Height + if err := os.Remove(filepath.Join(s.dir, fmt.Sprintf("%v.json", h))); err != nil { + return err + } + } + + // update metadata by removing the deleted snapshots + pruned := make([]abci.Snapshot, len(s.metadata[i:])) + copy(pruned, s.metadata[i:]) + s.metadata = pruned + return nil +} + // List lists available snapshots. func (s *SnapshotStore) List() ([]*abci.Snapshot, error) { s.RLock() diff --git a/test/e2e/app/state.go b/test/e2e/app/state.go index b07a6b9fc..a10a5cbf3 100644 --- a/test/e2e/app/state.go +++ b/test/e2e/app/state.go @@ -2,6 +2,7 @@ package app import ( "crypto/sha256" + "encoding/binary" "encoding/json" "errors" "fmt" @@ -39,7 +40,7 @@ func NewState(dir string, persistInterval uint64) (*State, error) { previousFile: filepath.Join(dir, prevStateFileName), persistInterval: persistInterval, } - state.Hash = hashItems(state.Values) + state.Hash = hashItems(state.Values, state.Height) err := state.load() switch { case errors.Is(err, os.ErrNotExist): @@ -115,7 +116,7 @@ func (s *State) Import(height uint64, jsonBytes []byte) error { } s.Height = height s.Values = values - s.Hash = hashItems(values) + s.Hash = hashItems(values, height) return s.save() } @@ -137,11 +138,10 @@ func (s *State) Set(key, value string) { } } -// Commit commits the current state. -func (s *State) Commit() (uint64, []byte, error) { +// Finalize is called after applying a block, updating the height and returning the new app_hash +func (s *State) Finalize() []byte { s.Lock() defer s.Unlock() - s.Hash = hashItems(s.Values) switch { case s.Height > 0: s.Height++ @@ -150,13 +150,21 @@ func (s *State) Commit() (uint64, []byte, error) { default: s.Height = 1 } + s.Hash = hashItems(s.Values, s.Height) + return s.Hash +} + +// Commit commits the current state. +func (s *State) Commit() (uint64, error) { + s.Lock() + defer s.Unlock() if s.persistInterval > 0 && s.Height%s.persistInterval == 0 { err := s.save() if err != nil { - return 0, nil, err + return 0, err } } - return s.Height, s.Hash, nil + return s.Height, nil } func (s *State) Rollback() error { @@ -172,7 +180,7 @@ func (s *State) Rollback() error { } // hashItems hashes a set of key/value items. -func hashItems(items map[string]string) []byte { +func hashItems(items map[string]string, height uint64) []byte { keys := make([]string, 0, len(items)) for key := range items { keys = append(keys, key) @@ -180,6 +188,9 @@ func hashItems(items map[string]string) []byte { sort.Strings(keys) hasher := sha256.New() + var b [8]byte + binary.BigEndian.PutUint64(b[:], height) + _, _ = hasher.Write(b[:]) for _, key := range keys { _, _ = hasher.Write([]byte(key)) _, _ = hasher.Write([]byte{0}) diff --git a/test/e2e/app/sync_app.go b/test/e2e/app/sync_app.go index 8df8da7a3..0b6d413c1 100644 --- a/test/e2e/app/sync_app.go +++ b/test/e2e/app/sync_app.go @@ -1,12 +1,13 @@ package app import ( + "context" "sync" abci "github.com/tendermint/tendermint/abci/types" ) -// SyncApplication wraps an Application, managing its own synchronization. This +// SyncApplication wraps the e2e Application, managing its own synchronization. This // allows it to be called from an unsynchronized local client, as it is // implemented in a thread-safe way. type SyncApplication struct { @@ -26,86 +27,74 @@ func NewSyncApplication(cfg *Config) (abci.Application, error) { }, nil } -func (app *SyncApplication) Info(req abci.RequestInfo) abci.ResponseInfo { +func (app *SyncApplication) Info(ctx context.Context, req *abci.RequestInfo) (*abci.ResponseInfo, error) { app.mtx.RLock() defer app.mtx.RUnlock() - return app.app.Info(req) + return app.app.Info(ctx, req) } -func (app *SyncApplication) InitChain(req abci.RequestInitChain) abci.ResponseInitChain { +func (app *SyncApplication) InitChain(ctx context.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) { app.mtx.Lock() defer app.mtx.Unlock() - return app.app.InitChain(req) + return app.app.InitChain(ctx, req) } -func (app *SyncApplication) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx { +func (app *SyncApplication) CheckTx(ctx context.Context, req *abci.RequestCheckTx) (*abci.ResponseCheckTx, error) { app.mtx.RLock() defer app.mtx.RUnlock() - return app.app.CheckTx(req) + return app.app.CheckTx(ctx, req) } -func (app *SyncApplication) PrepareProposal(req abci.RequestPrepareProposal) abci.ResponsePrepareProposal { +func (app *SyncApplication) PrepareProposal(ctx context.Context, req *abci.RequestPrepareProposal) (*abci.ResponsePrepareProposal, error) { // app.app.PrepareProposal does not modify state app.mtx.RLock() defer app.mtx.RUnlock() - return app.app.PrepareProposal(req) + return app.app.PrepareProposal(ctx, req) } -func (app *SyncApplication) ProcessProposal(req abci.RequestProcessProposal) abci.ResponseProcessProposal { +func (app *SyncApplication) ProcessProposal(ctx context.Context, req *abci.RequestProcessProposal) (*abci.ResponseProcessProposal, error) { // app.app.ProcessProposal does not modify state app.mtx.RLock() defer app.mtx.RUnlock() - return app.app.ProcessProposal(req) + return app.app.ProcessProposal(ctx, req) } -func (app *SyncApplication) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx { +func (app *SyncApplication) FinalizeBlock(ctx context.Context, req *abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { app.mtx.Lock() defer app.mtx.Unlock() - return app.app.DeliverTx(req) + return app.app.FinalizeBlock(ctx, req) } -func (app *SyncApplication) BeginBlock(req abci.RequestBeginBlock) abci.ResponseBeginBlock { +func (app *SyncApplication) Commit(ctx context.Context, req *abci.RequestCommit) (*abci.ResponseCommit, error) { app.mtx.Lock() defer app.mtx.Unlock() - return app.app.BeginBlock(req) + return app.app.Commit(ctx, req) } -func (app *SyncApplication) EndBlock(req abci.RequestEndBlock) abci.ResponseEndBlock { - app.mtx.Lock() - defer app.mtx.Unlock() - return app.app.EndBlock(req) -} - -func (app *SyncApplication) Commit() abci.ResponseCommit { - app.mtx.Lock() - defer app.mtx.Unlock() - return app.app.Commit() -} - -func (app *SyncApplication) Query(req abci.RequestQuery) abci.ResponseQuery { +func (app *SyncApplication) Query(ctx context.Context, req *abci.RequestQuery) (*abci.ResponseQuery, error) { app.mtx.RLock() defer app.mtx.RUnlock() - return app.app.Query(req) + return app.app.Query(ctx, req) } -func (app *SyncApplication) ApplySnapshotChunk(req abci.RequestApplySnapshotChunk) abci.ResponseApplySnapshotChunk { +func (app *SyncApplication) ApplySnapshotChunk(ctx context.Context, req *abci.RequestApplySnapshotChunk) (*abci.ResponseApplySnapshotChunk, error) { app.mtx.Lock() defer app.mtx.Unlock() - return app.app.ApplySnapshotChunk(req) + return app.app.ApplySnapshotChunk(ctx, req) } -func (app *SyncApplication) ListSnapshots(req abci.RequestListSnapshots) abci.ResponseListSnapshots { +func (app *SyncApplication) ListSnapshots(ctx context.Context, req *abci.RequestListSnapshots) (*abci.ResponseListSnapshots, error) { // Calls app.snapshots.List(), which is thread-safe. - return app.app.ListSnapshots(req) + return app.app.ListSnapshots(ctx, req) } -func (app *SyncApplication) LoadSnapshotChunk(req abci.RequestLoadSnapshotChunk) abci.ResponseLoadSnapshotChunk { +func (app *SyncApplication) LoadSnapshotChunk(ctx context.Context, req *abci.RequestLoadSnapshotChunk) (*abci.ResponseLoadSnapshotChunk, error) { // Calls app.snapshots.LoadChunk, which is thread-safe. - return app.app.LoadSnapshotChunk(req) + return app.app.LoadSnapshotChunk(ctx, req) } -func (app *SyncApplication) OfferSnapshot(req abci.RequestOfferSnapshot) abci.ResponseOfferSnapshot { +func (app *SyncApplication) OfferSnapshot(ctx context.Context, req *abci.RequestOfferSnapshot) (*abci.ResponseOfferSnapshot, error) { app.mtx.Lock() defer app.mtx.Unlock() - return app.app.OfferSnapshot(req) + return app.app.OfferSnapshot(ctx, req) } diff --git a/test/e2e/generator/generate_test.go b/test/e2e/generator/generate_test.go index 1367c0faf..2affedb11 100644 --- a/test/e2e/generator/generate_test.go +++ b/test/e2e/generator/generate_test.go @@ -15,11 +15,12 @@ import ( func TestGenerator(t *testing.T) { manifests, err := Generate(rand.New(rand.NewSource(randomSeed))) require.NoError(t, err) - require.True(t, len(manifests) >= 24, "insufficient combinations %d", len(manifests)) for idx, m := range manifests { t.Run(fmt.Sprintf("Case%04d", idx), func(t *testing.T) { - _, err := e2e.NewTestnetFromManifest(m, filepath.Join(t.TempDir(), fmt.Sprintf("Case%04d", idx))) + infra, err := e2e.NewDockerInfrastructureData(m) + require.NoError(t, err) + _, err = e2e.NewTestnetFromManifest(m, filepath.Join(t.TempDir(), fmt.Sprintf("Case%04d", idx)), infra) require.NoError(t, err) }) } diff --git a/test/e2e/runner/main.go b/test/e2e/runner/main.go index ce91dc3f2..c9854e112 100644 --- a/test/e2e/runner/main.go +++ b/test/e2e/runner/main.go @@ -79,7 +79,7 @@ func NewCLI() *CLI { return fmt.Errorf("unknown infrastructure type '%s'", inft) } - testnet, err := e2e.LoadTestnet(m, file, ifd) + testnet, err := e2e.LoadTestnet(file, ifd) if err != nil { return fmt.Errorf("loading testnet: %s", err) } diff --git a/test/e2e/tests/app_test.go b/test/e2e/tests/app_test.go index 8b8d23960..801b5a5c7 100644 --- a/test/e2e/tests/app_test.go +++ b/test/e2e/tests/app_test.go @@ -42,15 +42,22 @@ func TestApp_Hash(t *testing.T) { require.NoError(t, err) require.NotEmpty(t, info.Response.LastBlockAppHash, "expected app to return app hash") - block, err := client.Block(ctx, nil) - require.NoError(t, err) - require.EqualValues(t, info.Response.LastBlockAppHash, block.Block.AppHash, - "app hash does not match last block's app hash") + // In next-block execution, the app hash is stored in the next block + requestedHeight := info.Response.LastBlockHeight + 1 - status, err := client.Status(ctx) + require.Eventually(t, func() bool { + status, err := client.Status(ctx) + require.NoError(t, err) + require.NotZero(t, status.SyncInfo.LatestBlockHeight) + return status.SyncInfo.LatestBlockHeight >= requestedHeight + }, 5*time.Second, 500*time.Millisecond) + + block, err := client.Block(ctx, &requestedHeight) require.NoError(t, err) - require.EqualValues(t, info.Response.LastBlockAppHash, status.SyncInfo.LatestAppHash, - "app hash does not match node status") + require.Equal(t, + fmt.Sprintf("%x", info.Response.LastBlockAppHash), + fmt.Sprintf("%x", block.Block.AppHash.Bytes()), + "app hash does not match last block's app hash") }) } diff --git a/test/e2e/tests/e2e_test.go b/test/e2e/tests/e2e_test.go index 5df3309d4..15473e437 100644 --- a/test/e2e/tests/e2e_test.go +++ b/test/e2e/tests/e2e_test.go @@ -84,7 +84,7 @@ func loadTestnet(t *testing.T) e2e.Testnet { ifd, err := e2e.NewDockerInfrastructureData(m) require.NoError(t, err) - testnet, err := e2e.LoadTestnet(m, manifestFile, ifd) + testnet, err := e2e.LoadTestnet(manifestFile, ifd) require.NoError(t, err) testnetCache[manifestFile] = *testnet return *testnet diff --git a/test/fuzz/mempool/v0/checktx.go b/test/fuzz/mempool/v0/checktx.go index 1d70be9be..dd3bd9de9 100644 --- a/test/fuzz/mempool/v0/checktx.go +++ b/test/fuzz/mempool/v0/checktx.go @@ -11,7 +11,7 @@ import ( var mempool mempl.Mempool func init() { - app := kvstore.NewApplication() + app := kvstore.NewInMemoryApplication() cc := proxy.NewLocalClientCreator(app) appConnMem, _ := cc.NewABCIClient() err := appConnMem.Start() diff --git a/test/fuzz/mempool/v1/checktx.go b/test/fuzz/mempool/v1/checktx.go index 5d05ae7b3..7ee1c7bd6 100644 --- a/test/fuzz/mempool/v1/checktx.go +++ b/test/fuzz/mempool/v1/checktx.go @@ -13,7 +13,7 @@ import ( var mempool mempl.Mempool func init() { - app := kvstore.NewApplication() + app := kvstore.NewInMemoryApplication() cc := proxy.NewLocalClientCreator(app) appConnMem, _ := cc.NewABCIClient() err := appConnMem.Start() diff --git a/test/fuzz/tests/mempool_test.go b/test/fuzz/tests/mempool_test.go index 7b09e7c6a..004074393 100644 --- a/test/fuzz/tests/mempool_test.go +++ b/test/fuzz/tests/mempool_test.go @@ -15,7 +15,7 @@ import ( ) func FuzzMempool(f *testing.F) { - app := kvstore.NewApplication() + app := kvstore.NewInMemoryApplication() logger := log.NewNopLogger() mtx := new(tmsync.Mutex) conn := abciclient.NewLocalClient(mtx, app) diff --git a/types/block.go b/types/block.go index 5bf1cbfdb..3677be8af 100644 --- a/types/block.go +++ b/types/block.go @@ -342,7 +342,7 @@ type Header struct { ConsensusHash tmbytes.HexBytes `json:"consensus_hash"` // consensus params for current block AppHash tmbytes.HexBytes `json:"app_hash"` // state after txs from the previous block // root hash of all results from the txs from the previous block - // see `deterministicResponseDeliverTx` to understand which parts of a tx is hashed into here + // see `deterministicExecTxResult` to understand which parts of a tx is hashed into here LastResultsHash tmbytes.HexBytes `json:"last_results_hash"` // consensus info diff --git a/types/event_bus.go b/types/event_bus.go index d51ae8e67..239df1919 100644 --- a/types/event_bus.go +++ b/types/event_bus.go @@ -135,8 +135,7 @@ func (b *EventBus) PublishEventNewBlock(data EventDataNewBlock) error { // no explicit deadline for publishing events ctx := context.Background() - resultEvents := append(data.ResultBeginBlock.Events, data.ResultEndBlock.Events...) - events := b.validateAndStringifyEvents(resultEvents, b.Logger.With("block", data.Block.StringShort())) + events := b.validateAndStringifyEvents(data.ResultFinalizeBlock.Events, b.Logger.With("height", data.Block.Height)) // add predefined new block event events[EventTypeKey] = append(events[EventTypeKey], EventNewBlock) @@ -144,20 +143,22 @@ func (b *EventBus) PublishEventNewBlock(data EventDataNewBlock) error { return b.pubsub.PublishWithEvents(ctx, data, events) } -func (b *EventBus) PublishEventNewBlockHeader(data EventDataNewBlockHeader) error { +func (b *EventBus) PublishEventNewBlockEvents(data EventDataNewBlockEvents) error { // no explicit deadline for publishing events ctx := context.Background() - resultTags := append(data.ResultBeginBlock.Events, data.ResultEndBlock.Events...) - // TODO: Create StringShort method for Header and use it in logger. - events := b.validateAndStringifyEvents(resultTags, b.Logger.With("header", data.Header)) + events := b.validateAndStringifyEvents(data.Events, b.Logger.With("height", data.Height)) - // add predefined new block header event - events[EventTypeKey] = append(events[EventTypeKey], EventNewBlockHeader) + // add predefined new block event + events[EventTypeKey] = append(events[EventTypeKey], EventNewBlockEvents) return b.pubsub.PublishWithEvents(ctx, data, events) } +func (b *EventBus) PublishEventNewBlockHeader(data EventDataNewBlockHeader) error { + return b.Publish(EventNewBlockHeader, data) +} + func (b *EventBus) PublishEventNewEvidence(evidence EventDataNewEvidence) error { return b.Publish(EventNewEvidence, evidence) } @@ -255,6 +256,10 @@ func (NopEventBus) PublishEventNewBlockHeader(data EventDataNewBlockHeader) erro return nil } +func (NopEventBus) PublishEventNewBlockEvents(data EventDataNewBlockEvents) error { + return nil +} + func (NopEventBus) PublishEventNewEvidence(evidence EventDataNewEvidence) error { return nil } diff --git a/types/event_bus_test.go b/types/event_bus_test.go index 62f57fca6..1abe11bf0 100644 --- a/types/event_bus_test.go +++ b/types/event_bus_test.go @@ -27,7 +27,7 @@ func TestEventBusPublishEventTx(t *testing.T) { }) tx := Tx("foo") - result := abci.ResponseDeliverTx{ + result := abci.ExecTxResult{ Data: []byte("bar"), Events: []abci.Event{ {Type: "testType", Attributes: []abci.EventAttribute{{Key: "baz", Value: "1"}}}, @@ -76,19 +76,14 @@ func TestEventBusPublishEventNewBlock(t *testing.T) { }) block := MakeBlock(0, []Tx{}, nil, []Evidence{}) - resultBeginBlock := abci.ResponseBeginBlock{ + resultFinalizeBlock := abci.ResponseFinalizeBlock{ Events: []abci.Event{ {Type: "testType", Attributes: []abci.EventAttribute{{Key: "baz", Value: "1"}}}, }, } - resultEndBlock := abci.ResponseEndBlock{ - Events: []abci.Event{ - {Type: "testType", Attributes: []abci.EventAttribute{{Key: "foz", Value: "2"}}}, - }, - } // PublishEventNewBlock adds the tm.event compositeKey, so the query below should work - query := "tm.event='NewBlock' AND testType.baz=1 AND testType.foz=2" + query := "tm.event='NewBlock' AND testType.baz=1" blocksSub, err := eventBus.Subscribe(context.Background(), "test", tmquery.MustCompile(query)) require.NoError(t, err) @@ -97,15 +92,21 @@ func TestEventBusPublishEventNewBlock(t *testing.T) { msg := <-blocksSub.Out() edt := msg.Data().(EventDataNewBlock) assert.Equal(t, block, edt.Block) - assert.Equal(t, resultBeginBlock, edt.ResultBeginBlock) - assert.Equal(t, resultEndBlock, edt.ResultEndBlock) + assert.Equal(t, resultFinalizeBlock, edt.ResultFinalizeBlock) close(done) }() + var ps *PartSet + ps, err = block.MakePartSet(MaxBlockSizeBytes) + require.NoError(t, err) + err = eventBus.PublishEventNewBlock(EventDataNewBlock{ - Block: block, - ResultBeginBlock: resultBeginBlock, - ResultEndBlock: resultEndBlock, + Block: block, + BlockID: BlockID{ + Hash: block.Hash(), + PartSetHeader: ps.Header(), + }, + ResultFinalizeBlock: resultFinalizeBlock, }) assert.NoError(t, err) @@ -127,7 +128,7 @@ func TestEventBusPublishEventTxDuplicateKeys(t *testing.T) { }) tx := Tx("foo") - result := abci.ResponseDeliverTx{ + result := abci.ExecTxResult{ Data: []byte("bar"), Events: []abci.Event{ { @@ -235,19 +236,8 @@ func TestEventBusPublishEventNewBlockHeader(t *testing.T) { }) block := MakeBlock(0, []Tx{}, nil, []Evidence{}) - resultBeginBlock := abci.ResponseBeginBlock{ - Events: []abci.Event{ - {Type: "testType", Attributes: []abci.EventAttribute{{Key: "baz", Value: "1"}}}, - }, - } - resultEndBlock := abci.ResponseEndBlock{ - Events: []abci.Event{ - {Type: "testType", Attributes: []abci.EventAttribute{{Key: "foz", Value: "2"}}}, - }, - } - // PublishEventNewBlockHeader adds the tm.event compositeKey, so the query below should work - query := "tm.event='NewBlockHeader' AND testType.baz=1 AND testType.foz=2" + query := "tm.event='NewBlockHeader'" headersSub, err := eventBus.Subscribe(context.Background(), "test", tmquery.MustCompile(query)) require.NoError(t, err) @@ -256,15 +246,53 @@ func TestEventBusPublishEventNewBlockHeader(t *testing.T) { msg := <-headersSub.Out() edt := msg.Data().(EventDataNewBlockHeader) assert.Equal(t, block.Header, edt.Header) - assert.Equal(t, resultBeginBlock, edt.ResultBeginBlock) - assert.Equal(t, resultEndBlock, edt.ResultEndBlock) close(done) }() err = eventBus.PublishEventNewBlockHeader(EventDataNewBlockHeader{ - Header: block.Header, - ResultBeginBlock: resultBeginBlock, - ResultEndBlock: resultEndBlock, + Header: block.Header, + }) + assert.NoError(t, err) + + select { + case <-done: + case <-time.After(1 * time.Second): + t.Fatal("did not receive a block header after 1 sec.") + } +} + +func TestEventBusPublishEventNewBlockEvents(t *testing.T) { + eventBus := NewEventBus() + err := eventBus.Start() + require.NoError(t, err) + t.Cleanup(func() { + if err := eventBus.Stop(); err != nil { + t.Error(err) + } + }) + + // PublishEventNewBlockHeader adds the tm.event compositeKey, so the query below should work + query := "tm.event='NewBlockEvents'" + headersSub, err := eventBus.Subscribe(context.Background(), "test", tmquery.MustCompile(query)) + require.NoError(t, err) + + done := make(chan struct{}) + go func() { + msg := <-headersSub.Out() + edt := msg.Data().(EventDataNewBlockEvents) + assert.Equal(t, int64(1), edt.Height) + close(done) + }() + + err = eventBus.PublishEventNewBlockEvents(EventDataNewBlockEvents{ + Height: 1, + Events: []abci.Event{{ + Type: "transfer", + Attributes: []abci.EventAttribute{{ + Key: "currency", + Value: "ATOM", + }}, + }}, }) assert.NoError(t, err) @@ -324,7 +352,7 @@ func TestEventBusPublish(t *testing.T) { } }) - const numEventsExpected = 14 + const numEventsExpected = 15 sub, err := eventBus.Subscribe(context.Background(), "test", tmquery.All, numEventsExpected) require.NoError(t, err) @@ -343,10 +371,12 @@ func TestEventBusPublish(t *testing.T) { err = eventBus.Publish(EventNewBlockHeader, EventDataNewBlockHeader{}) require.NoError(t, err) - err = eventBus.PublishEventNewBlock(EventDataNewBlock{}) + err = eventBus.PublishEventNewBlock(EventDataNewBlock{Block: &Block{Header: Header{Height: 1}}}) require.NoError(t, err) err = eventBus.PublishEventNewBlockHeader(EventDataNewBlockHeader{}) require.NoError(t, err) + err = eventBus.PublishEventNewBlockEvents(EventDataNewBlockEvents{Height: 1}) + require.NoError(t, err) err = eventBus.PublishEventVote(EventDataVote{}) require.NoError(t, err) err = eventBus.PublishEventNewRoundStep(EventDataRoundState{}) @@ -465,6 +495,7 @@ func benchmarkEventBus(numClients int, randQueries bool, randEvents bool, b *tes var events = []string{ EventNewBlock, EventNewBlockHeader, + EventNewBlockEvents, EventNewRound, EventNewRoundStep, EventTimeoutPropose, @@ -483,6 +514,7 @@ func randEvent() string { var queries = []tmpubsub.Query{ EventQueryNewBlock, EventQueryNewBlockHeader, + EventQueryNewBlockEvents, EventQueryNewRound, EventQueryNewRoundStep, EventQueryTimeoutPropose, diff --git a/types/events.go b/types/events.go index ae6c8637b..e6f4381e0 100644 --- a/types/events.go +++ b/types/events.go @@ -18,6 +18,7 @@ const ( // All of this data can be fetched through the rpc. EventNewBlock = "NewBlock" EventNewBlockHeader = "NewBlockHeader" + EventNewBlockEvents = "NewBlockEvents" EventNewEvidence = "NewEvidence" EventTx = "Tx" EventValidatorSetUpdates = "ValidatorSetUpdates" @@ -48,6 +49,7 @@ type TMEventData interface { func init() { tmjson.RegisterType(EventDataNewBlock{}, "tendermint/event/NewBlock") tmjson.RegisterType(EventDataNewBlockHeader{}, "tendermint/event/NewBlockHeader") + tmjson.RegisterType(EventDataNewBlockEvents{}, "tendermint/event/NewBlockEvents") tmjson.RegisterType(EventDataNewEvidence{}, "tendermint/event/NewEvidence") tmjson.RegisterType(EventDataTx{}, "tendermint/event/Tx") tmjson.RegisterType(EventDataRoundState{}, "tendermint/event/RoundState") @@ -62,24 +64,24 @@ func init() { // but some (an input to a call tx or a receive) are more exotic type EventDataNewBlock struct { - Block *Block `json:"block"` - - ResultBeginBlock abci.ResponseBeginBlock `json:"result_begin_block"` - ResultEndBlock abci.ResponseEndBlock `json:"result_end_block"` + Block *Block `json:"block"` + BlockID BlockID `json:"block_id"` + ResultFinalizeBlock abci.ResponseFinalizeBlock `json:"result_finalize_block"` } type EventDataNewBlockHeader struct { Header Header `json:"header"` +} - NumTxs int64 `json:"num_txs"` // Number of txs in a block - ResultBeginBlock abci.ResponseBeginBlock `json:"result_begin_block"` - ResultEndBlock abci.ResponseEndBlock `json:"result_end_block"` +type EventDataNewBlockEvents struct { + Height int64 `json:"height"` + Events []abci.Event `json:"events"` + NumTxs int64 `json:"num_txs,string"` // Number of txs in a block } type EventDataNewEvidence struct { + Height int64 `json:"height"` Evidence Evidence `json:"evidence"` - - Height int64 `json:"height"` } // All txs fire EventDataTx @@ -130,15 +132,16 @@ type EventDataValidatorSetUpdates struct { const ( // EventTypeKey is a reserved composite key for event name. EventTypeKey = "tm.event" + // TxHashKey is a reserved key, used to specify transaction's hash. // see EventBus#PublishEventTx TxHashKey = "tx.hash" + // TxHeightKey is a reserved key, used to specify transaction block's height. // see EventBus#PublishEventTx TxHeightKey = "tx.height" - // BlockHeightKey is a reserved key used for indexing BeginBlock and Endblock - // events. + // BlockHeightKey is a reserved key used for indexing FinalizeBlock events. BlockHeightKey = "block.height" ) @@ -147,6 +150,7 @@ var ( EventQueryLock = QueryForEvent(EventLock) EventQueryNewBlock = QueryForEvent(EventNewBlock) EventQueryNewBlockHeader = QueryForEvent(EventNewBlockHeader) + EventQueryNewBlockEvents = QueryForEvent(EventNewBlockEvents) EventQueryNewEvidence = QueryForEvent(EventNewEvidence) EventQueryNewRound = QueryForEvent(EventNewRound) EventQueryNewRoundStep = QueryForEvent(EventNewRoundStep) @@ -173,6 +177,7 @@ func QueryForEvent(eventType string) tmpubsub.Query { type BlockEventPublisher interface { PublishEventNewBlock(block EventDataNewBlock) error PublishEventNewBlockHeader(header EventDataNewBlockHeader) error + PublishEventNewBlockEvents(events EventDataNewBlockEvents) error PublishEventNewEvidence(evidence EventDataNewEvidence) error PublishEventTx(EventDataTx) error PublishEventValidatorSetUpdates(EventDataValidatorSetUpdates) error diff --git a/types/results.go b/types/results.go index 9181450bc..1ba6d56ff 100644 --- a/types/results.go +++ b/types/results.go @@ -6,14 +6,14 @@ import ( ) // ABCIResults wraps the deliver tx results to return a proof. -type ABCIResults []*abci.ResponseDeliverTx +type ABCIResults []*abci.ExecTxResult -// NewResults strips non-deterministic fields from ResponseDeliverTx responses +// NewResults strips non-deterministic fields from ExecTxResult responses // and returns ABCIResults. -func NewResults(responses []*abci.ResponseDeliverTx) ABCIResults { +func NewResults(responses []*abci.ExecTxResult) ABCIResults { res := make(ABCIResults, len(responses)) for i, d := range responses { - res[i] = deterministicResponseDeliverTx(d) + res[i] = deterministicExecTxResult(d) } return res } @@ -42,10 +42,10 @@ func (a ABCIResults) toByteSlices() [][]byte { return bzs } -// deterministicResponseDeliverTx strips non-deterministic fields from -// ResponseDeliverTx and returns another ResponseDeliverTx. -func deterministicResponseDeliverTx(response *abci.ResponseDeliverTx) *abci.ResponseDeliverTx { - return &abci.ResponseDeliverTx{ +// deterministicExecTxResult strips non-deterministic fields from +// ExecTxResult and returns another ExecTxResult. +func deterministicExecTxResult(response *abci.ExecTxResult) *abci.ExecTxResult { + return &abci.ExecTxResult{ Code: response.Code, Data: response.Data, GasWanted: response.GasWanted, diff --git a/types/results_test.go b/types/results_test.go index 5b1be3466..da7eebed0 100644 --- a/types/results_test.go +++ b/types/results_test.go @@ -10,12 +10,12 @@ import ( ) func TestABCIResults(t *testing.T) { - a := &abci.ResponseDeliverTx{Code: 0, Data: nil} - b := &abci.ResponseDeliverTx{Code: 0, Data: []byte{}} - c := &abci.ResponseDeliverTx{Code: 0, Data: []byte("one")} - d := &abci.ResponseDeliverTx{Code: 14, Data: nil} - e := &abci.ResponseDeliverTx{Code: 14, Data: []byte("foo")} - f := &abci.ResponseDeliverTx{Code: 14, Data: []byte("bar")} + a := &abci.ExecTxResult{Code: 0, Data: nil} + b := &abci.ExecTxResult{Code: 0, Data: []byte{}} + c := &abci.ExecTxResult{Code: 0, Data: []byte("one")} + d := &abci.ExecTxResult{Code: 14, Data: nil} + e := &abci.ExecTxResult{Code: 14, Data: []byte("foo")} + f := &abci.ExecTxResult{Code: 14, Data: []byte("bar")} // Nil and []byte{} should produce the same bytes bzA, err := a.Marshal() diff --git a/types/validation.go b/types/validation.go index 3b33e90db..3601f0479 100644 --- a/types/validation.go +++ b/types/validation.go @@ -19,7 +19,7 @@ func shouldBatchVerify(vals *ValidatorSet, commit *Commit) bool { // // It checks all the signatures! While it's safe to exit as soon as we have // 2/3+ signatures, doing so would impact incentivization logic in the ABCI -// application that depends on the LastCommitInfo sent in BeginBlock, which +// application that depends on the LastCommitInfo sent in FinalizeBlock, which // includes which validators signed. For instance, Gaia incentivizes proposers // with a bonus for including more than +2/3 of the signatures. func VerifyCommit(chainID string, vals *ValidatorSet, blockID BlockID,