diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md index 62c3e4f3a..7f9d6f651 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.md +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -19,7 +19,7 @@ v without deliberation ## Proposal diff --git a/.github/auto-comment.yml b/.github/auto-comment.yml index 604c2f878..97b9a6adf 100644 --- a/.github/auto-comment.yml +++ b/.github/auto-comment.yml @@ -13,4 +13,4 @@ pullRequestOpened: | - [ ] Applied Appropriate Labels - Thank you for your contribution to Tendermint! :rocket: \ No newline at end of file + Thank you for your contribution to Ostracon! :rocket: \ No newline at end of file diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index cb1bea6c8..b5ef605f2 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -11,7 +11,7 @@ on: jobs: e2e-test: runs-on: ubuntu-latest - timeout-minutes: 15 + timeout-minutes: 30 steps: - uses: actions/setup-go@v2 with: diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 9eab0dc6d..b5033cbd3 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -1,5 +1,5 @@ name: Lint -# Lint runs golangci-lint over the entire Tendermint repository +# Lint runs golangci-lint over the entire Ostracon repository # This workflow is run on every pull request and push to master # The `golangci` job will pass without running if no *.{go, mod, sum} files have been modified. on: diff --git a/.github/workflows/proto-docker.yml b/.github/workflows/proto-docker.yml index 72b4e671b..8f9c4e7eb 100644 --- a/.github/workflows/proto-docker.yml +++ b/.github/workflows/proto-docker.yml @@ -1,4 +1,4 @@ -name: Build & Push TM Proto Builder +name: Build & Push OC Proto Builder on: pull_request: paths: diff --git a/DOCKER/Dockerfile b/DOCKER/Dockerfile index f2e39afbc..8e9b2065f 100644 --- a/DOCKER/Dockerfile +++ b/DOCKER/Dockerfile @@ -16,7 +16,7 @@ LABEL maintainer="hello@blockchain.line.me" # private validator file into /ostracon/config. # # The /ostracon/data dir is used by ostracon to store state. -ENV TMHOME /ostracon +ENV OCHOME /ostracon # OS environment setup # Set user right away for determinism, create directory for persistence and give our user ownership @@ -27,12 +27,12 @@ RUN apk update && \ apk upgrade && \ apk add --no-cache git make gcc libc-dev build-base curl jq bash file gmp-dev clang && \ addgroup ostracon && \ - adduser -S -G ostracon ostracon -h "$TMHOME" + adduser -S -G ostracon ostracon -h "$OCHOME" # Run the container with ostracon by default. (UID=100, GID=1000) USER ostracon -WORKDIR $TMHOME +WORKDIR $OCHOME # p2p, rpc and prometheus port EXPOSE 26656 26657 26660 @@ -52,5 +52,5 @@ ENTRYPOINT ["docker-entrypoint.sh"] CMD ["node"] # Expose the data directory as a volume since there's mutable state in there -VOLUME [ "$TMHOME" ] +VOLUME [ "$OCHOME" ] diff --git a/DOCKER/docker-entrypoint.sh b/DOCKER/docker-entrypoint.sh index 0d705475c..3b0cfa3e8 100755 --- a/DOCKER/docker-entrypoint.sh +++ b/DOCKER/docker-entrypoint.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -if [ ! -d "$TMHOME/config" ]; then +if [ ! -d "$OCHOME/config" ]; then echo "Running ostracon init to create (default) configuration for docker run." ostracon init @@ -13,11 +13,11 @@ if [ ! -d "$TMHOME/config" ]; then -e 's/^index_all_tags\s*=.*/index_all_tags = true/' \ -e 's,^laddr = "tcp://127.0.0.1:26657",laddr = "tcp://0.0.0.0:26657",' \ -e 's/^prometheus\s*=.*/prometheus = true/' \ - "$TMHOME/config/config.toml" + "$OCHOME/config/config.toml" jq ".chain_id = \"$CHAIN_ID\" | .consensus_params.block.time_iota_ms = \"500\"" \ - "$TMHOME/config/genesis.json" > "$TMHOME/config/genesis.json.new" - mv "$TMHOME/config/genesis.json.new" "$TMHOME/config/genesis.json" + "$OCHOME/config/genesis.json" > "$OCHOME/config/genesis.json.new" + mv "$OCHOME/config/genesis.json.new" "$OCHOME/config/genesis.json" fi exec ostracon "$@" diff --git a/abci/client/client.go b/abci/client/client.go index dd3b8a8b6..8ccfc5cb6 100644 --- a/abci/client/client.go +++ b/abci/client/client.go @@ -9,6 +9,7 @@ import ( tmsync "github.com/line/ostracon/libs/sync" ) +//go:generate mockery --case underscore --name Client const ( dialRetryIntervalSeconds = 3 echoRetryIntervalSeconds = 1 @@ -22,27 +23,30 @@ const ( type Client interface { service.Service - SetResponseCallback(Callback) + SetGlobalCallback(GlobalCallback) + GetGlobalCallback() GlobalCallback Error() error - FlushAsync() *ReqRes - EchoAsync(msg string) *ReqRes - InfoAsync(types.RequestInfo) *ReqRes - SetOptionAsync(types.RequestSetOption) *ReqRes - DeliverTxAsync(types.RequestDeliverTx) *ReqRes - CheckTxAsync(types.RequestCheckTx) *ReqRes - QueryAsync(types.RequestQuery) *ReqRes - CommitAsync() *ReqRes - InitChainAsync(types.RequestInitChain) *ReqRes - BeginBlockAsync(types.RequestBeginBlock) *ReqRes - EndBlockAsync(types.RequestEndBlock) *ReqRes - ListSnapshotsAsync(types.RequestListSnapshots) *ReqRes - OfferSnapshotAsync(types.RequestOfferSnapshot) *ReqRes - LoadSnapshotChunkAsync(types.RequestLoadSnapshotChunk) *ReqRes - ApplySnapshotChunkAsync(types.RequestApplySnapshotChunk) *ReqRes - - FlushSync() error - EchoSync(msg string) (*types.ResponseEcho, error) + FlushAsync(ResponseCallback) *ReqRes + EchoAsync(string, ResponseCallback) *ReqRes + InfoAsync(types.RequestInfo, ResponseCallback) *ReqRes + SetOptionAsync(types.RequestSetOption, ResponseCallback) *ReqRes + DeliverTxAsync(types.RequestDeliverTx, ResponseCallback) *ReqRes + CheckTxAsync(types.RequestCheckTx, ResponseCallback) *ReqRes + QueryAsync(types.RequestQuery, ResponseCallback) *ReqRes + CommitAsync(ResponseCallback) *ReqRes + InitChainAsync(types.RequestInitChain, ResponseCallback) *ReqRes + BeginBlockAsync(types.RequestBeginBlock, ResponseCallback) *ReqRes + EndBlockAsync(types.RequestEndBlock, ResponseCallback) *ReqRes + BeginRecheckTxAsync(types.RequestBeginRecheckTx, ResponseCallback) *ReqRes + EndRecheckTxAsync(types.RequestEndRecheckTx, ResponseCallback) *ReqRes + ListSnapshotsAsync(types.RequestListSnapshots, ResponseCallback) *ReqRes + OfferSnapshotAsync(types.RequestOfferSnapshot, ResponseCallback) *ReqRes + LoadSnapshotChunkAsync(types.RequestLoadSnapshotChunk, ResponseCallback) *ReqRes + ApplySnapshotChunkAsync(types.RequestApplySnapshotChunk, ResponseCallback) *ReqRes + + FlushSync() (*types.ResponseFlush, error) + EchoSync(string) (*types.ResponseEcho, error) InfoSync(types.RequestInfo) (*types.ResponseInfo, error) SetOptionSync(types.RequestSetOption) (*types.ResponseSetOption, error) DeliverTxSync(types.RequestDeliverTx) (*types.ResponseDeliverTx, error) @@ -52,6 +56,8 @@ type Client interface { InitChainSync(types.RequestInitChain) (*types.ResponseInitChain, error) BeginBlockSync(types.RequestBeginBlock) (*types.ResponseBeginBlock, error) EndBlockSync(types.RequestEndBlock) (*types.ResponseEndBlock, error) + BeginRecheckTxSync(types.RequestBeginRecheckTx) (*types.ResponseBeginRecheckTx, error) + EndRecheckTxSync(types.RequestEndRecheckTx) (*types.ResponseEndRecheckTx, error) ListSnapshotsSync(types.RequestListSnapshots) (*types.ResponseListSnapshots, error) OfferSnapshotSync(types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) LoadSnapshotChunkSync(types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) @@ -74,73 +80,62 @@ func NewClient(addr, transport string, mustConnect bool) (client Client, err err return } -type Callback func(*types.Request, *types.Response) +type GlobalCallback func(*types.Request, *types.Response) +type ResponseCallback func(*types.Response) type ReqRes struct { *types.Request - *sync.WaitGroup *types.Response // Not set atomically, so be sure to use WaitGroup. mtx tmsync.Mutex - done bool // Gets set to true once *after* WaitGroup.Done(). - cb func(*types.Response) // A single callback that may be set. + wg *sync.WaitGroup + done bool // Gets set to true once *after* WaitGroup.Done(). + cb ResponseCallback // A single callback that may be set. } -func NewReqRes(req *types.Request) *ReqRes { +func NewReqRes(req *types.Request, cb ResponseCallback) *ReqRes { return &ReqRes{ - Request: req, - WaitGroup: waitGroup1(), - Response: nil, + Request: req, + Response: nil, + wg: waitGroup1(), done: false, - cb: nil, + cb: cb, } } -// Sets sets the callback. If reqRes is already done, it will call the cb -// immediately. Note, reqRes.cb should not change if reqRes.done and only one -// callback is supported. -func (r *ReqRes) SetCallback(cb func(res *types.Response)) { - r.mtx.Lock() +// InvokeCallback invokes a thread-safe execution of the configured callback +// if non-nil. +func (reqRes *ReqRes) InvokeCallback() { + reqRes.mtx.Lock() + defer reqRes.mtx.Unlock() - if r.done { - r.mtx.Unlock() - cb(r.Response) - return + if reqRes.cb != nil { + reqRes.cb(reqRes.Response) } - - r.cb = cb - r.mtx.Unlock() } -// InvokeCallback invokes a thread-safe execution of the configured callback -// if non-nil. -func (r *ReqRes) InvokeCallback() { - r.mtx.Lock() - defer r.mtx.Unlock() +func (reqRes *ReqRes) SetDone(res *types.Response) (set bool) { + reqRes.mtx.Lock() + // TODO should we panic if it's already done? + set = !reqRes.done + if set { + reqRes.Response = res + reqRes.done = true + reqRes.wg.Done() + } + reqRes.mtx.Unlock() - if r.cb != nil { - r.cb(r.Response) + // NOTE `reqRes.cb` is immutable so we're safe to access it at here without `mtx` + if set && reqRes.cb != nil { + reqRes.cb(res) } -} -// GetCallback returns the configured callback of the ReqRes object which may be -// nil. Note, it is not safe to concurrently call this in cases where it is -// marked done and SetCallback is called before calling GetCallback as that -// will invoke the callback twice and create a potential race condition. -// -// ref: https://github.com/tendermint/tendermint/issues/5439 -func (r *ReqRes) GetCallback() func(*types.Response) { - r.mtx.Lock() - defer r.mtx.Unlock() - return r.cb + return set } -// SetDone marks the ReqRes object as done. -func (r *ReqRes) SetDone() { - r.mtx.Lock() - r.done = true - r.mtx.Unlock() +func (reqRes *ReqRes) Wait() { + reqRes.wg.Wait() } func waitGroup1() (wg *sync.WaitGroup) { diff --git a/abci/client/grpc_client.go b/abci/client/grpc_client.go index a041c6523..e8be0f5ec 100644 --- a/abci/client/grpc_client.go +++ b/abci/client/grpc_client.go @@ -23,27 +23,21 @@ type grpcClient struct { service.BaseService mustConnect bool - client types.ABCIApplicationClient - conn *grpc.ClientConn - chReqRes chan *ReqRes // dispatches "async" responses to callbacks *in order*, needed by mempool + client types.ABCIApplicationClient + conn *grpc.ClientConn - mtx tmsync.Mutex - addr string - err error - resCb func(*types.Request, *types.Response) // listens to all callbacks + mtx tmsync.Mutex + addr string + err error + + globalCbMtx sync.Mutex + globalCb func(*types.Request, *types.Response) // listens to all callbacks } func NewGRPCClient(addr string, mustConnect bool) Client { cli := &grpcClient{ addr: addr, mustConnect: mustConnect, - // Buffering the channel is needed to make calls appear asynchronous, - // which is required when the caller makes multiple async calls before - // processing callbacks (e.g. due to holding locks). 64 means that a - // caller can make up to 64 async calls before a callback must be - // processed (otherwise it deadlocks). It also means that we can make 64 - // gRPC calls while processing a slow callback at the channel head. - chReqRes: make(chan *ReqRes, 64), } cli.BaseService = *service.NewBaseService(nil, "grpcClient", cli) return cli @@ -58,36 +52,6 @@ func (cli *grpcClient) OnStart() error { return err } - // This processes asynchronous request/response messages and dispatches - // them to callbacks. - go func() { - // Use a separate function to use defer for mutex unlocks (this handles panics) - callCb := func(reqres *ReqRes) { - cli.mtx.Lock() - defer cli.mtx.Unlock() - - reqres.SetDone() - reqres.Done() - - // Notify client listener if set - if cli.resCb != nil { - cli.resCb(reqres.Request, reqres.Response) - } - - // Notify reqRes listener if set - if cb := reqres.GetCallback(); cb != nil { - cb(reqres.Response) - } - } - for reqres := range cli.chReqRes { - if reqres != nil { - callCb(reqres) - } else { - cli.Logger.Error("Received nil reqres") - } - } - }() - RETRY_LOOP: for { conn, err := grpc.Dial(cli.addr, grpc.WithInsecure(), grpc.WithContextDialer(dialerFunc)) @@ -125,7 +89,6 @@ func (cli *grpcClient) OnStop() { if cli.conn != nil { cli.conn.Close() } - close(cli.chReqRes) } func (cli *grpcClient) StopForError(err error) { @@ -151,12 +114,17 @@ func (cli *grpcClient) Error() error { return cli.err } -// Set listener for all responses -// NOTE: callback may get internally generated flush responses. -func (cli *grpcClient) SetResponseCallback(resCb Callback) { - cli.mtx.Lock() - cli.resCb = resCb - cli.mtx.Unlock() +func (cli *grpcClient) SetGlobalCallback(globalCb GlobalCallback) { + cli.globalCbMtx.Lock() + cli.globalCb = globalCb + cli.globalCbMtx.Unlock() +} + +func (cli *grpcClient) GetGlobalCallback() (cb GlobalCallback) { + cli.globalCbMtx.Lock() + cb = cli.globalCb + cli.globalCbMtx.Unlock() + return cb } //---------------------------------------- @@ -167,253 +135,279 @@ func (cli *grpcClient) SetResponseCallback(resCb Callback) { // maybe one day, if people really want it, we use grpc streams, // but hopefully not :D -func (cli *grpcClient) EchoAsync(msg string) *ReqRes { +func (cli *grpcClient) EchoAsync(msg string, cb ResponseCallback) *ReqRes { req := types.ToRequestEcho(msg) res, err := cli.client.Echo(context.Background(), req.GetEcho(), grpc.WaitForReady(true)) if err != nil { cli.StopForError(err) } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_Echo{Echo: res}}) + return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_Echo{Echo: res}}, cb) } -func (cli *grpcClient) FlushAsync() *ReqRes { +func (cli *grpcClient) FlushAsync(cb ResponseCallback) *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}}) + return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_Flush{Flush: res}}, cb) } -func (cli *grpcClient) InfoAsync(params types.RequestInfo) *ReqRes { +func (cli *grpcClient) InfoAsync(params types.RequestInfo, cb ResponseCallback) *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}}) + return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_Info{Info: res}}, cb) } -func (cli *grpcClient) SetOptionAsync(params types.RequestSetOption) *ReqRes { +func (cli *grpcClient) SetOptionAsync(params types.RequestSetOption, cb ResponseCallback) *ReqRes { req := types.ToRequestSetOption(params) res, err := cli.client.SetOption(context.Background(), req.GetSetOption(), grpc.WaitForReady(true)) if err != nil { cli.StopForError(err) } - return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_SetOption{SetOption: res}}) + return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_SetOption{SetOption: res}}, cb) } -func (cli *grpcClient) DeliverTxAsync(params types.RequestDeliverTx) *ReqRes { +func (cli *grpcClient) DeliverTxAsync(params types.RequestDeliverTx, cb ResponseCallback) *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}}) + return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_DeliverTx{DeliverTx: res}}, cb) } -func (cli *grpcClient) CheckTxAsync(params types.RequestCheckTx) *ReqRes { +func (cli *grpcClient) CheckTxAsync(params types.RequestCheckTx, cb ResponseCallback) *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}}) + return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_CheckTx{CheckTx: res}}, cb) } -func (cli *grpcClient) QueryAsync(params types.RequestQuery) *ReqRes { +func (cli *grpcClient) QueryAsync(params types.RequestQuery, cb ResponseCallback) *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}}) + return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_Query{Query: res}}, cb) } -func (cli *grpcClient) CommitAsync() *ReqRes { +func (cli *grpcClient) CommitAsync(cb ResponseCallback) *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}}) + return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_Commit{Commit: res}}, cb) } -func (cli *grpcClient) InitChainAsync(params types.RequestInitChain) *ReqRes { +func (cli *grpcClient) InitChainAsync(params types.RequestInitChain, cb ResponseCallback) *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}}) + return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_InitChain{InitChain: res}}, cb) } -func (cli *grpcClient) BeginBlockAsync(params types.RequestBeginBlock) *ReqRes { +func (cli *grpcClient) BeginBlockAsync(params types.RequestBeginBlock, cb ResponseCallback) *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}}) + return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_BeginBlock{BeginBlock: res}}, cb) } -func (cli *grpcClient) EndBlockAsync(params types.RequestEndBlock) *ReqRes { +func (cli *grpcClient) EndBlockAsync(params types.RequestEndBlock, cb ResponseCallback) *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}}) + return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_EndBlock{EndBlock: res}}, cb) } -func (cli *grpcClient) ListSnapshotsAsync(params types.RequestListSnapshots) *ReqRes { +func (cli *grpcClient) BeginRecheckTxAsync(params types.RequestBeginRecheckTx, cb ResponseCallback) *ReqRes { + req := types.ToRequestBeginRecheckTx(params) + res, err := cli.client.BeginRecheckTx(context.Background(), req.GetBeginRecheckTx(), grpc.WaitForReady(true)) + if err != nil { + cli.StopForError(err) + } + return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_BeginRecheckTx{BeginRecheckTx: res}}, cb) +} + +func (cli *grpcClient) EndRecheckTxAsync(params types.RequestEndRecheckTx, cb ResponseCallback) *ReqRes { + req := types.ToRequestEndRecheckTx(params) + res, err := cli.client.EndRecheckTx(context.Background(), req.GetEndRecheckTx(), grpc.WaitForReady(true)) + if err != nil { + cli.StopForError(err) + } + return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_EndRecheckTx{EndRecheckTx: res}}, cb) +} + +func (cli *grpcClient) ListSnapshotsAsync(params types.RequestListSnapshots, cb ResponseCallback) *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}}) + return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_ListSnapshots{ListSnapshots: res}}, cb) } -func (cli *grpcClient) OfferSnapshotAsync(params types.RequestOfferSnapshot) *ReqRes { +func (cli *grpcClient) OfferSnapshotAsync(params types.RequestOfferSnapshot, cb ResponseCallback) *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}}) + return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_OfferSnapshot{OfferSnapshot: res}}, cb) } -func (cli *grpcClient) LoadSnapshotChunkAsync(params types.RequestLoadSnapshotChunk) *ReqRes { +func (cli *grpcClient) LoadSnapshotChunkAsync(params types.RequestLoadSnapshotChunk, cb ResponseCallback) *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}}) + return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_LoadSnapshotChunk{LoadSnapshotChunk: res}}, cb) } -func (cli *grpcClient) ApplySnapshotChunkAsync(params types.RequestApplySnapshotChunk) *ReqRes { +func (cli *grpcClient) ApplySnapshotChunkAsync(params types.RequestApplySnapshotChunk, cb ResponseCallback) *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}}) -} - -// finishAsyncCall creates a ReqRes for an async call, and immediately populates it -// with the response. We don't complete it until it's been ordered via the channel. -func (cli *grpcClient) finishAsyncCall(req *types.Request, res *types.Response) *ReqRes { - reqres := NewReqRes(req) - reqres.Response = res - cli.chReqRes <- reqres // use channel for async responses, since they must be ordered - 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 + return cli.finishAsyncCall(req, + &types.Response{Value: &types.Response_ApplySnapshotChunk{ApplySnapshotChunk: res}}, cb) } -//---------------------------------------- +func (cli *grpcClient) finishAsyncCall(req *types.Request, res *types.Response, cb ResponseCallback) *ReqRes { + reqRes := NewReqRes(req, cb) + + // goroutine for callbacks + go func() { + set := reqRes.SetDone(res) + if set { + // Notify client listener if set + if globalCb := cli.GetGlobalCallback(); globalCb != nil { + globalCb(req, res) + } + } + }() + + return reqRes +} -func (cli *grpcClient) FlushSync() error { - return nil +//---------------------------------------- +func (cli *grpcClient) FlushSync() (*types.ResponseFlush, error) { + reqres := cli.FlushAsync(nil) + reqres.Wait() + return reqres.Response.GetFlush(), cli.Error() } func (cli *grpcClient) EchoSync(msg string) (*types.ResponseEcho, error) { - reqres := cli.EchoAsync(msg) + reqres := cli.EchoAsync(msg, nil) + reqres.Wait() // StopForError should already have been called if error is set - return cli.finishSyncCall(reqres).GetEcho(), cli.Error() + return reqres.Response.GetEcho(), cli.Error() } func (cli *grpcClient) InfoSync(req types.RequestInfo) (*types.ResponseInfo, error) { - reqres := cli.InfoAsync(req) - return cli.finishSyncCall(reqres).GetInfo(), cli.Error() + reqres := cli.InfoAsync(req, nil) + reqres.Wait() + return reqres.Response.GetInfo(), cli.Error() } func (cli *grpcClient) SetOptionSync(req types.RequestSetOption) (*types.ResponseSetOption, error) { - reqres := cli.SetOptionAsync(req) + reqres := cli.SetOptionAsync(req, nil) + reqres.Wait() return reqres.Response.GetSetOption(), cli.Error() } func (cli *grpcClient) DeliverTxSync(params types.RequestDeliverTx) (*types.ResponseDeliverTx, error) { - reqres := cli.DeliverTxAsync(params) - return cli.finishSyncCall(reqres).GetDeliverTx(), cli.Error() + reqres := cli.DeliverTxAsync(params, nil) + reqres.Wait() + return reqres.Response.GetDeliverTx(), cli.Error() } func (cli *grpcClient) CheckTxSync(params types.RequestCheckTx) (*types.ResponseCheckTx, error) { - reqres := cli.CheckTxAsync(params) - return cli.finishSyncCall(reqres).GetCheckTx(), cli.Error() + reqres := cli.CheckTxAsync(params, nil) + reqres.Wait() + return reqres.Response.GetCheckTx(), cli.Error() } func (cli *grpcClient) QuerySync(req types.RequestQuery) (*types.ResponseQuery, error) { - reqres := cli.QueryAsync(req) - return cli.finishSyncCall(reqres).GetQuery(), cli.Error() + reqres := cli.QueryAsync(req, nil) + reqres.Wait() + return reqres.Response.GetQuery(), cli.Error() } func (cli *grpcClient) CommitSync() (*types.ResponseCommit, error) { - reqres := cli.CommitAsync() - return cli.finishSyncCall(reqres).GetCommit(), cli.Error() + reqres := cli.CommitAsync(nil) + reqres.Wait() + return reqres.Response.GetCommit(), cli.Error() } func (cli *grpcClient) InitChainSync(params types.RequestInitChain) (*types.ResponseInitChain, error) { - reqres := cli.InitChainAsync(params) - return cli.finishSyncCall(reqres).GetInitChain(), cli.Error() + reqres := cli.InitChainAsync(params, nil) + reqres.Wait() + return reqres.Response.GetInitChain(), cli.Error() } func (cli *grpcClient) BeginBlockSync(params types.RequestBeginBlock) (*types.ResponseBeginBlock, error) { - reqres := cli.BeginBlockAsync(params) - return cli.finishSyncCall(reqres).GetBeginBlock(), cli.Error() + reqres := cli.BeginBlockAsync(params, nil) + reqres.Wait() + return reqres.Response.GetBeginBlock(), cli.Error() } func (cli *grpcClient) EndBlockSync(params types.RequestEndBlock) (*types.ResponseEndBlock, error) { - reqres := cli.EndBlockAsync(params) - return cli.finishSyncCall(reqres).GetEndBlock(), cli.Error() + reqres := cli.EndBlockAsync(params, nil) + reqres.Wait() + return reqres.Response.GetEndBlock(), cli.Error() +} + +func (cli *grpcClient) BeginRecheckTxSync(params types.RequestBeginRecheckTx) (*types.ResponseBeginRecheckTx, error) { + reqres := cli.BeginRecheckTxAsync(params, nil) + reqres.Wait() + return reqres.Response.GetBeginRecheckTx(), cli.Error() +} + +func (cli *grpcClient) EndRecheckTxSync(params types.RequestEndRecheckTx) (*types.ResponseEndRecheckTx, error) { + reqres := cli.EndRecheckTxAsync(params, nil) + reqres.Wait() + return reqres.Response.GetEndRecheckTx(), cli.Error() } func (cli *grpcClient) ListSnapshotsSync(params types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { - reqres := cli.ListSnapshotsAsync(params) - return cli.finishSyncCall(reqres).GetListSnapshots(), cli.Error() + reqres := cli.ListSnapshotsAsync(params, nil) + reqres.Wait() + return reqres.Response.GetListSnapshots(), cli.Error() } func (cli *grpcClient) OfferSnapshotSync(params types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { - reqres := cli.OfferSnapshotAsync(params) - return cli.finishSyncCall(reqres).GetOfferSnapshot(), cli.Error() + reqres := cli.OfferSnapshotAsync(params, nil) + reqres.Wait() + return reqres.Response.GetOfferSnapshot(), cli.Error() } func (cli *grpcClient) LoadSnapshotChunkSync( params types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { - reqres := cli.LoadSnapshotChunkAsync(params) - return cli.finishSyncCall(reqres).GetLoadSnapshotChunk(), cli.Error() + reqres := cli.LoadSnapshotChunkAsync(params, nil) + reqres.Wait() + return reqres.Response.GetLoadSnapshotChunk(), cli.Error() } func (cli *grpcClient) ApplySnapshotChunkSync( params types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { - reqres := cli.ApplySnapshotChunkAsync(params) - return cli.finishSyncCall(reqres).GetApplySnapshotChunk(), cli.Error() + reqres := cli.ApplySnapshotChunkAsync(params, nil) + reqres.Wait() + return reqres.Response.GetApplySnapshotChunk(), cli.Error() } diff --git a/abci/client/grpc_client_test.go b/abci/client/grpc_client_test.go new file mode 100644 index 000000000..4e04b502d --- /dev/null +++ b/abci/client/grpc_client_test.go @@ -0,0 +1,98 @@ +package abcicli + +import ( + "fmt" + "testing" + + "github.com/line/ostracon/abci/server" + "github.com/line/ostracon/abci/types" + "github.com/line/ostracon/libs/rand" + "github.com/stretchr/testify/require" +) + +func TestGrpcClientCalls(t *testing.T) { + app := sampleApp{} + + port := 20000 + rand.Int32()%10000 + addr := fmt.Sprintf("localhost:%d", port) + + s, err0 := server.NewServer(addr, "grpc", app) + require.NoError(t, err0) + err0 = s.Start() + require.NoError(t, err0) + + c := NewGRPCClient(addr, true) + c.SetGlobalCallback(func(*types.Request, *types.Response) { + }) + err0 = c.Start() + require.NoError(t, err0) + + c.EchoAsync("msg", getResponseCallback(t)) + c.FlushAsync(getResponseCallback(t)) + c.InfoAsync(types.RequestInfo{}, getResponseCallback(t)) + c.SetOptionAsync(types.RequestSetOption{}, getResponseCallback(t)) + c.DeliverTxAsync(types.RequestDeliverTx{}, getResponseCallback(t)) + c.CheckTxAsync(types.RequestCheckTx{}, getResponseCallback(t)) + c.QueryAsync(types.RequestQuery{}, getResponseCallback(t)) + c.CommitAsync(getResponseCallback(t)) + c.InitChainAsync(types.RequestInitChain{}, getResponseCallback(t)) + c.BeginBlockAsync(types.RequestBeginBlock{}, getResponseCallback(t)) + c.EndBlockAsync(types.RequestEndBlock{}, getResponseCallback(t)) + c.BeginRecheckTxAsync(types.RequestBeginRecheckTx{}, getResponseCallback(t)) + c.EndRecheckTxAsync(types.RequestEndRecheckTx{}, getResponseCallback(t)) + c.ListSnapshotsAsync(types.RequestListSnapshots{}, getResponseCallback(t)) + c.OfferSnapshotAsync(types.RequestOfferSnapshot{}, getResponseCallback(t)) + c.LoadSnapshotChunkAsync(types.RequestLoadSnapshotChunk{}, getResponseCallback(t)) + c.ApplySnapshotChunkAsync(types.RequestApplySnapshotChunk{}, getResponseCallback(t)) + + _, err := c.EchoSync("msg") + require.NoError(t, err) + + _, err = c.FlushSync() + require.NoError(t, err) + + _, err = c.InfoSync(types.RequestInfo{}) + require.NoError(t, err) + + _, err = c.SetOptionSync(types.RequestSetOption{}) + require.NoError(t, err) + + _, err = c.DeliverTxSync(types.RequestDeliverTx{}) + require.NoError(t, err) + + _, err = c.CheckTxSync(types.RequestCheckTx{}) + require.NoError(t, err) + + _, err = c.QuerySync(types.RequestQuery{}) + require.NoError(t, err) + + _, err = c.CommitSync() + require.NoError(t, err) + + _, err = c.InitChainSync(types.RequestInitChain{}) + require.NoError(t, err) + + _, err = c.BeginBlockSync(types.RequestBeginBlock{}) + require.NoError(t, err) + + _, err = c.EndBlockSync(types.RequestEndBlock{}) + require.NoError(t, err) + + _, err = c.BeginRecheckTxSync(types.RequestBeginRecheckTx{}) + require.NoError(t, err) + + _, err = c.EndRecheckTxSync(types.RequestEndRecheckTx{}) + require.NoError(t, err) + + _, err = c.ListSnapshotsSync(types.RequestListSnapshots{}) + require.NoError(t, err) + + _, err = c.OfferSnapshotSync(types.RequestOfferSnapshot{}) + require.NoError(t, err) + + _, err = c.LoadSnapshotChunkSync(types.RequestLoadSnapshotChunk{}) + require.NoError(t, err) + + _, err = c.ApplySnapshotChunkSync(types.RequestApplySnapshotChunk{}) + require.NoError(t, err) +} diff --git a/abci/client/local_client.go b/abci/client/local_client.go index 5bc0ec0fb..0186384a6 100644 --- a/abci/client/local_client.go +++ b/abci/client/local_client.go @@ -15,9 +15,13 @@ var _ Client = (*localClient)(nil) type localClient struct { service.BaseService + // TODO: remove `mtx` to increase concurrency. We could remove it because the app should protect itself. mtx *tmsync.Mutex + // CONTRACT: The application should protect itself from concurrency as an abci server. types.Application - Callback + + globalCbMtx tmsync.Mutex + globalCb GlobalCallback } func NewLocalClient(mtx *tmsync.Mutex, app types.Application) Client { @@ -32,10 +36,17 @@ func NewLocalClient(mtx *tmsync.Mutex, app types.Application) Client { return cli } -func (app *localClient) SetResponseCallback(cb Callback) { - app.mtx.Lock() - app.Callback = cb - app.mtx.Unlock() +func (app *localClient) SetGlobalCallback(globalCb GlobalCallback) { + app.globalCbMtx.Lock() + app.globalCb = globalCb + app.globalCbMtx.Unlock() +} + +func (app *localClient) GetGlobalCallback() (cb GlobalCallback) { + app.globalCbMtx.Lock() + cb = app.globalCb + app.globalCbMtx.Unlock() + return cb } // TODO: change types.Application to include Error()? @@ -43,171 +54,174 @@ func (app *localClient) Error() error { return nil } -func (app *localClient) FlushAsync() *ReqRes { +func (app *localClient) FlushAsync(cb ResponseCallback) *ReqRes { // Do nothing - return newLocalReqRes(types.ToRequestFlush(), nil) + reqRes := NewReqRes(types.ToRequestFlush(), cb) + return app.done(reqRes, types.ToResponseFlush()) } -func (app *localClient) EchoAsync(msg string) *ReqRes { - app.mtx.Lock() - defer app.mtx.Unlock() +func (app *localClient) EchoAsync(msg string, cb ResponseCallback) *ReqRes { + // NOTE: commented out for performance. delete all after commenting out all `app.mtx` + // app.mtx.Lock() + // defer app.mtx.Unlock() - return app.callback( - types.ToRequestEcho(msg), - types.ToResponseEcho(msg), - ) + reqRes := NewReqRes(types.ToRequestEcho(msg), cb) + return app.done(reqRes, types.ToResponseEcho(msg)) } -func (app *localClient) InfoAsync(req types.RequestInfo) *ReqRes { +func (app *localClient) InfoAsync(req types.RequestInfo, cb ResponseCallback) *ReqRes { app.mtx.Lock() defer app.mtx.Unlock() + reqRes := NewReqRes(types.ToRequestInfo(req), cb) res := app.Application.Info(req) - return app.callback( - types.ToRequestInfo(req), - types.ToResponseInfo(res), - ) + return app.done(reqRes, types.ToResponseInfo(res)) } -func (app *localClient) SetOptionAsync(req types.RequestSetOption) *ReqRes { +func (app *localClient) SetOptionAsync(req types.RequestSetOption, cb ResponseCallback) *ReqRes { app.mtx.Lock() defer app.mtx.Unlock() + reqRes := NewReqRes(types.ToRequestSetOption(req), cb) res := app.Application.SetOption(req) - return app.callback( - types.ToRequestSetOption(req), - types.ToResponseSetOption(res), - ) + return app.done(reqRes, types.ToResponseSetOption(res)) } -func (app *localClient) DeliverTxAsync(params types.RequestDeliverTx) *ReqRes { +func (app *localClient) DeliverTxAsync(req types.RequestDeliverTx, cb ResponseCallback) *ReqRes { app.mtx.Lock() defer app.mtx.Unlock() - res := app.Application.DeliverTx(params) - return app.callback( - types.ToRequestDeliverTx(params), - types.ToResponseDeliverTx(res), - ) + reqRes := NewReqRes(types.ToRequestDeliverTx(req), cb) + res := app.Application.DeliverTx(req) + return app.done(reqRes, types.ToResponseDeliverTx(res)) } -func (app *localClient) CheckTxAsync(req types.RequestCheckTx) *ReqRes { - app.mtx.Lock() - defer app.mtx.Unlock() +func (app *localClient) CheckTxAsync(req types.RequestCheckTx, cb ResponseCallback) *ReqRes { + // NOTE: commented out for performance. delete all after commenting out all `app.mtx` + // app.mtx.Lock() + // defer app.mtx.Unlock() - res := app.Application.CheckTx(req) - return app.callback( - types.ToRequestCheckTx(req), - types.ToResponseCheckTx(res), - ) + reqRes := NewReqRes(types.ToRequestCheckTx(req), cb) + + app.Application.CheckTxAsync(req, func(r types.ResponseCheckTx) { + res := types.ToResponseCheckTx(r) + app.done(reqRes, res) + }) + + return reqRes } -func (app *localClient) QueryAsync(req types.RequestQuery) *ReqRes { +func (app *localClient) QueryAsync(req types.RequestQuery, cb ResponseCallback) *ReqRes { app.mtx.Lock() defer app.mtx.Unlock() + reqRes := NewReqRes(types.ToRequestQuery(req), cb) res := app.Application.Query(req) - return app.callback( - types.ToRequestQuery(req), - types.ToResponseQuery(res), - ) + return app.done(reqRes, types.ToResponseQuery(res)) } -func (app *localClient) CommitAsync() *ReqRes { +func (app *localClient) CommitAsync(cb ResponseCallback) *ReqRes { app.mtx.Lock() defer app.mtx.Unlock() + reqRes := NewReqRes(types.ToRequestCommit(), cb) res := app.Application.Commit() - return app.callback( - types.ToRequestCommit(), - types.ToResponseCommit(res), - ) + return app.done(reqRes, types.ToResponseCommit(res)) } -func (app *localClient) InitChainAsync(req types.RequestInitChain) *ReqRes { +func (app *localClient) InitChainAsync(req types.RequestInitChain, cb ResponseCallback) *ReqRes { app.mtx.Lock() defer app.mtx.Unlock() + reqRes := NewReqRes(types.ToRequestInitChain(req), cb) res := app.Application.InitChain(req) - return app.callback( - types.ToRequestInitChain(req), - types.ToResponseInitChain(res), - ) + return app.done(reqRes, types.ToResponseInitChain(res)) } -func (app *localClient) BeginBlockAsync(req types.RequestBeginBlock) *ReqRes { +func (app *localClient) BeginBlockAsync(req types.RequestBeginBlock, cb ResponseCallback) *ReqRes { app.mtx.Lock() defer app.mtx.Unlock() + reqRes := NewReqRes(types.ToRequestBeginBlock(req), cb) res := app.Application.BeginBlock(req) - return app.callback( - types.ToRequestBeginBlock(req), - types.ToResponseBeginBlock(res), - ) + return app.done(reqRes, types.ToResponseBeginBlock(res)) } -func (app *localClient) EndBlockAsync(req types.RequestEndBlock) *ReqRes { +func (app *localClient) EndBlockAsync(req types.RequestEndBlock, cb ResponseCallback) *ReqRes { app.mtx.Lock() defer app.mtx.Unlock() + reqRes := NewReqRes(types.ToRequestEndBlock(req), cb) res := app.Application.EndBlock(req) - return app.callback( - types.ToRequestEndBlock(req), - types.ToResponseEndBlock(res), - ) + return app.done(reqRes, types.ToResponseEndBlock(res)) +} + +func (app *localClient) BeginRecheckTxAsync(req types.RequestBeginRecheckTx, cb ResponseCallback) *ReqRes { + // NOTE: commented out for performance. delete all after commenting out all `app.mtx` + // app.mtx.Lock() + // defer app.mtx.Unlock() + + reqRes := NewReqRes(types.ToRequestBeginRecheckTx(req), cb) + res := app.Application.BeginRecheckTx(req) + return app.done(reqRes, types.ToResponseBeginRecheckTx(res)) +} + +func (app *localClient) EndRecheckTxAsync(req types.RequestEndRecheckTx, cb ResponseCallback) *ReqRes { + // NOTE: commented out for performance. delete all after commenting out all `app.mtx` + // app.mtx.Lock() + // defer app.mtx.Unlock() + + reqRes := NewReqRes(types.ToRequestEndRecheckTx(req), cb) + res := app.Application.EndRecheckTx(req) + return app.done(reqRes, types.ToResponseEndRecheckTx(res)) } -func (app *localClient) ListSnapshotsAsync(req types.RequestListSnapshots) *ReqRes { +func (app *localClient) ListSnapshotsAsync(req types.RequestListSnapshots, cb ResponseCallback) *ReqRes { app.mtx.Lock() defer app.mtx.Unlock() + reqRes := NewReqRes(types.ToRequestListSnapshots(req), cb) res := app.Application.ListSnapshots(req) - return app.callback( - types.ToRequestListSnapshots(req), - types.ToResponseListSnapshots(res), - ) + return app.done(reqRes, types.ToResponseListSnapshots(res)) } -func (app *localClient) OfferSnapshotAsync(req types.RequestOfferSnapshot) *ReqRes { +func (app *localClient) OfferSnapshotAsync(req types.RequestOfferSnapshot, cb ResponseCallback) *ReqRes { app.mtx.Lock() defer app.mtx.Unlock() + reqRes := NewReqRes(types.ToRequestOfferSnapshot(req), cb) res := app.Application.OfferSnapshot(req) - return app.callback( - types.ToRequestOfferSnapshot(req), - types.ToResponseOfferSnapshot(res), - ) + return app.done(reqRes, types.ToResponseOfferSnapshot(res)) } -func (app *localClient) LoadSnapshotChunkAsync(req types.RequestLoadSnapshotChunk) *ReqRes { +func (app *localClient) LoadSnapshotChunkAsync(req types.RequestLoadSnapshotChunk, cb ResponseCallback) *ReqRes { app.mtx.Lock() defer app.mtx.Unlock() + reqRes := NewReqRes(types.ToRequestLoadSnapshotChunk(req), cb) res := app.Application.LoadSnapshotChunk(req) - return app.callback( - types.ToRequestLoadSnapshotChunk(req), - types.ToResponseLoadSnapshotChunk(res), - ) + return app.done(reqRes, types.ToResponseLoadSnapshotChunk(res)) } -func (app *localClient) ApplySnapshotChunkAsync(req types.RequestApplySnapshotChunk) *ReqRes { +func (app *localClient) ApplySnapshotChunkAsync(req types.RequestApplySnapshotChunk, cb ResponseCallback) *ReqRes { app.mtx.Lock() defer app.mtx.Unlock() + reqRes := NewReqRes(types.ToRequestApplySnapshotChunk(req), cb) res := app.Application.ApplySnapshotChunk(req) - return app.callback( - types.ToRequestApplySnapshotChunk(req), - types.ToResponseApplySnapshotChunk(res), - ) + return app.done(reqRes, types.ToResponseApplySnapshotChunk(res)) } //------------------------------------------------------- - -func (app *localClient) FlushSync() error { - return nil +func (app *localClient) FlushSync() (*types.ResponseFlush, error) { + return &types.ResponseFlush{}, nil } func (app *localClient) EchoSync(msg string) (*types.ResponseEcho, error) { + // NOTE: commented out for performance. delete all after commenting out all `app.mtx` + // app.mtx.Lock() + // defer app.mtx.Unlock() + return &types.ResponseEcho{Message: msg}, nil } @@ -236,10 +250,11 @@ func (app *localClient) DeliverTxSync(req types.RequestDeliverTx) (*types.Respon } func (app *localClient) CheckTxSync(req types.RequestCheckTx) (*types.ResponseCheckTx, error) { - app.mtx.Lock() - defer app.mtx.Unlock() + // NOTE: commented out for performance. delete all after commenting out all `app.mtx` + // app.mtx.Lock() + // defer app.mtx.Unlock() - res := app.Application.CheckTx(req) + res := app.Application.CheckTxSync(req) return &res, nil } @@ -283,6 +298,24 @@ func (app *localClient) EndBlockSync(req types.RequestEndBlock) (*types.Response return &res, nil } +func (app *localClient) BeginRecheckTxSync(req types.RequestBeginRecheckTx) (*types.ResponseBeginRecheckTx, error) { + // NOTE: commented out for performance. delete all after commenting out all `app.mtx` + // app.mtx.Lock() + // defer app.mtx.Unlock() + + res := app.Application.BeginRecheckTx(req) + return &res, nil +} + +func (app *localClient) EndRecheckTxSync(req types.RequestEndRecheckTx) (*types.ResponseEndRecheckTx, error) { + // NOTE: commented out for performance. delete all after commenting out all `app.mtx` + // app.mtx.Lock() + // defer app.mtx.Unlock() + + res := app.Application.EndRecheckTx(req) + return &res, nil +} + func (app *localClient) ListSnapshotsSync(req types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { app.mtx.Lock() defer app.mtx.Unlock() @@ -319,14 +352,12 @@ func (app *localClient) ApplySnapshotChunkSync( //------------------------------------------------------- -func (app *localClient) callback(req *types.Request, res *types.Response) *ReqRes { - app.Callback(req, res) - return newLocalReqRes(req, res) -} - -func newLocalReqRes(req *types.Request, res *types.Response) *ReqRes { - reqRes := NewReqRes(req) - reqRes.Response = res - reqRes.SetDone() +func (app *localClient) done(reqRes *ReqRes, res *types.Response) *ReqRes { + set := reqRes.SetDone(res) + if set { + if globalCb := app.GetGlobalCallback(); globalCb != nil { + globalCb(reqRes.Request, res) + } + } return reqRes } diff --git a/abci/client/local_client_test.go b/abci/client/local_client_test.go new file mode 100644 index 000000000..4ad2e6a24 --- /dev/null +++ b/abci/client/local_client_test.go @@ -0,0 +1,111 @@ +package abcicli + +import ( + "testing" + "time" + + "github.com/line/ostracon/abci/types" + "github.com/stretchr/testify/require" +) + +type sampleApp struct { + types.BaseApplication +} + +func newDoneChan(t *testing.T) chan struct{} { + result := make(chan struct{}) + go func(){ + select { + case <-time.After(time.Second): + require.Fail(t, "callback is not called for a second") + case <-result: + return + } + }() + return result +} + +func getResponseCallback(t *testing.T) ResponseCallback { + doneChan := newDoneChan(t) + return func (res *types.Response) { + require.NotNil(t, res) + doneChan<- struct{}{} + } +} + +func TestLocalClientCalls(t *testing.T) { + app := sampleApp{} + c := NewLocalClient(nil, app) + + c.SetGlobalCallback(func(*types.Request, *types.Response) { + }) + + c.EchoAsync("msg", getResponseCallback(t)) + c.FlushAsync(getResponseCallback(t)) + c.InfoAsync(types.RequestInfo{}, getResponseCallback(t)) + c.SetOptionAsync(types.RequestSetOption{}, getResponseCallback(t)) + c.DeliverTxAsync(types.RequestDeliverTx{}, getResponseCallback(t)) + c.CheckTxAsync(types.RequestCheckTx{}, getResponseCallback(t)) + c.QueryAsync(types.RequestQuery{}, getResponseCallback(t)) + c.CommitAsync(getResponseCallback(t)) + c.InitChainAsync(types.RequestInitChain{}, getResponseCallback(t)) + c.BeginBlockAsync(types.RequestBeginBlock{}, getResponseCallback(t)) + c.EndBlockAsync(types.RequestEndBlock{}, getResponseCallback(t)) + c.BeginRecheckTxAsync(types.RequestBeginRecheckTx{}, getResponseCallback(t)) + c.EndRecheckTxAsync(types.RequestEndRecheckTx{}, getResponseCallback(t)) + c.ListSnapshotsAsync(types.RequestListSnapshots{}, getResponseCallback(t)) + c.OfferSnapshotAsync(types.RequestOfferSnapshot{}, getResponseCallback(t)) + c.LoadSnapshotChunkAsync(types.RequestLoadSnapshotChunk{}, getResponseCallback(t)) + c.ApplySnapshotChunkAsync(types.RequestApplySnapshotChunk{}, getResponseCallback(t)) + + _, err := c.EchoSync("msg") + require.NoError(t, err) + + _, err = c.FlushSync() + require.NoError(t, err) + + _, err = c.InfoSync(types.RequestInfo{}) + require.NoError(t, err) + + _, err = c.SetOptionSync(types.RequestSetOption{}) + require.NoError(t, err) + + _, err = c.DeliverTxSync(types.RequestDeliverTx{}) + require.NoError(t, err) + + _, err = c.CheckTxSync(types.RequestCheckTx{}) + require.NoError(t, err) + + _, err = c.QuerySync(types.RequestQuery{}) + require.NoError(t, err) + + _, err = c.CommitSync() + require.NoError(t, err) + + _, err = c.InitChainSync(types.RequestInitChain{}) + require.NoError(t, err) + + _, err = c.BeginBlockSync(types.RequestBeginBlock{}) + require.NoError(t, err) + + _, err = c.EndBlockSync(types.RequestEndBlock{}) + require.NoError(t, err) + + _, err = c.BeginRecheckTxSync(types.RequestBeginRecheckTx{}) + require.NoError(t, err) + + _, err = c.EndRecheckTxSync(types.RequestEndRecheckTx{}) + require.NoError(t, err) + + _, err = c.ListSnapshotsSync(types.RequestListSnapshots{}) + require.NoError(t, err) + + _, err = c.OfferSnapshotSync(types.RequestOfferSnapshot{}) + require.NoError(t, err) + + _, err = c.LoadSnapshotChunkSync(types.RequestLoadSnapshotChunk{}) + require.NoError(t, err) + + _, err = c.ApplySnapshotChunkSync(types.RequestApplySnapshotChunk{}) + require.NoError(t, err) +} diff --git a/abci/client/mocks/client.go b/abci/client/mocks/client.go index 9b4a046b0..219c9bf73 100644 --- a/abci/client/mocks/client.go +++ b/abci/client/mocks/client.go @@ -1,4 +1,4 @@ -// Code generated by mockery v1.1.1. DO NOT EDIT. +// Code generated by mockery 2.7.4. DO NOT EDIT. package mocks @@ -16,13 +16,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) +// ApplySnapshotChunkAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) ApplySnapshotChunkAsync(_a0 types.RequestApplySnapshotChunk, _a1 abcicli.ResponseCallback) *abcicli.ReqRes { + ret := _m.Called(_a0, _a1) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestApplySnapshotChunk) *abcicli.ReqRes); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(types.RequestApplySnapshotChunk, abcicli.ResponseCallback) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) @@ -55,13 +55,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) +// BeginBlockAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) BeginBlockAsync(_a0 types.RequestBeginBlock, _a1 abcicli.ResponseCallback) *abcicli.ReqRes { + ret := _m.Called(_a0, _a1) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestBeginBlock) *abcicli.ReqRes); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(types.RequestBeginBlock, abcicli.ResponseCallback) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) @@ -94,13 +94,52 @@ func (_m *Client) BeginBlockSync(_a0 types.RequestBeginBlock) (*types.ResponseBe return r0, r1 } -// CheckTxAsync provides a mock function with given fields: _a0 -func (_m *Client) CheckTxAsync(_a0 types.RequestCheckTx) *abcicli.ReqRes { - ret := _m.Called(_a0) +// BeginRecheckTxAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) BeginRecheckTxAsync(_a0 types.RequestBeginRecheckTx, _a1 abcicli.ResponseCallback) *abcicli.ReqRes { + ret := _m.Called(_a0, _a1) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestCheckTx) *abcicli.ReqRes); ok { + if rf, ok := ret.Get(0).(func(types.RequestBeginRecheckTx, abcicli.ResponseCallback) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*abcicli.ReqRes) + } + } + + return r0 +} + +// BeginRecheckTxSync provides a mock function with given fields: _a0 +func (_m *Client) BeginRecheckTxSync(_a0 types.RequestBeginRecheckTx) (*types.ResponseBeginRecheckTx, error) { + ret := _m.Called(_a0) + + var r0 *types.ResponseBeginRecheckTx + if rf, ok := ret.Get(0).(func(types.RequestBeginRecheckTx) *types.ResponseBeginRecheckTx); ok { r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseBeginRecheckTx) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(types.RequestBeginRecheckTx) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CheckTxAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) CheckTxAsync(_a0 types.RequestCheckTx, _a1 abcicli.ResponseCallback) *abcicli.ReqRes { + ret := _m.Called(_a0, _a1) + + var r0 *abcicli.ReqRes + if rf, ok := ret.Get(0).(func(types.RequestCheckTx, abcicli.ResponseCallback) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) @@ -133,13 +172,13 @@ func (_m *Client) CheckTxSync(_a0 types.RequestCheckTx) (*types.ResponseCheckTx, return r0, r1 } -// CommitAsync provides a mock function with given fields: -func (_m *Client) CommitAsync() *abcicli.ReqRes { - ret := _m.Called() +// CommitAsync provides a mock function with given fields: _a0 +func (_m *Client) CommitAsync(_a0 abcicli.ResponseCallback) *abcicli.ReqRes { + ret := _m.Called(_a0) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func() *abcicli.ReqRes); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(abcicli.ResponseCallback) *abcicli.ReqRes); ok { + r0 = rf(_a0) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) @@ -172,13 +211,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) +// DeliverTxAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) DeliverTxAsync(_a0 types.RequestDeliverTx, _a1 abcicli.ResponseCallback) *abcicli.ReqRes { + ret := _m.Called(_a0, _a1) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestDeliverTx) *abcicli.ReqRes); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(types.RequestDeliverTx, abcicli.ResponseCallback) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) @@ -211,13 +250,13 @@ func (_m *Client) DeliverTxSync(_a0 types.RequestDeliverTx) (*types.ResponseDeli return r0, r1 } -// EchoAsync provides a mock function with given fields: msg -func (_m *Client) EchoAsync(msg string) *abcicli.ReqRes { - ret := _m.Called(msg) +// EchoAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) EchoAsync(_a0 string, _a1 abcicli.ResponseCallback) *abcicli.ReqRes { + ret := _m.Called(_a0, _a1) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(string) *abcicli.ReqRes); ok { - r0 = rf(msg) + if rf, ok := ret.Get(0).(func(string, abcicli.ResponseCallback) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) @@ -227,13 +266,13 @@ func (_m *Client) EchoAsync(msg string) *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) +// EchoSync provides a mock function with given fields: _a0 +func (_m *Client) EchoSync(_a0 string) (*types.ResponseEcho, error) { + ret := _m.Called(_a0) var r0 *types.ResponseEcho if rf, ok := ret.Get(0).(func(string) *types.ResponseEcho); ok { - r0 = rf(msg) + r0 = rf(_a0) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*types.ResponseEcho) @@ -242,7 +281,7 @@ 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) + r1 = rf(_a0) } else { r1 = ret.Error(1) } @@ -250,13 +289,13 @@ func (_m *Client) EchoSync(msg string) (*types.ResponseEcho, error) { return r0, r1 } -// EndBlockAsync provides a mock function with given fields: _a0 -func (_m *Client) EndBlockAsync(_a0 types.RequestEndBlock) *abcicli.ReqRes { - ret := _m.Called(_a0) +// EndBlockAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) EndBlockAsync(_a0 types.RequestEndBlock, _a1 abcicli.ResponseCallback) *abcicli.ReqRes { + ret := _m.Called(_a0, _a1) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestEndBlock) *abcicli.ReqRes); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(types.RequestEndBlock, abcicli.ResponseCallback) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) @@ -289,6 +328,45 @@ func (_m *Client) EndBlockSync(_a0 types.RequestEndBlock) (*types.ResponseEndBlo return r0, r1 } +// EndRecheckTxAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) EndRecheckTxAsync(_a0 types.RequestEndRecheckTx, _a1 abcicli.ResponseCallback) *abcicli.ReqRes { + ret := _m.Called(_a0, _a1) + + var r0 *abcicli.ReqRes + if rf, ok := ret.Get(0).(func(types.RequestEndRecheckTx, abcicli.ResponseCallback) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*abcicli.ReqRes) + } + } + + return r0 +} + +// EndRecheckTxSync provides a mock function with given fields: _a0 +func (_m *Client) EndRecheckTxSync(_a0 types.RequestEndRecheckTx) (*types.ResponseEndRecheckTx, error) { + ret := _m.Called(_a0) + + var r0 *types.ResponseEndRecheckTx + if rf, ok := ret.Get(0).(func(types.RequestEndRecheckTx) *types.ResponseEndRecheckTx); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseEndRecheckTx) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(types.RequestEndRecheckTx) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // Error provides a mock function with given fields: func (_m *Client) Error() error { ret := _m.Called() @@ -303,13 +381,13 @@ func (_m *Client) Error() error { return r0 } -// FlushAsync provides a mock function with given fields: -func (_m *Client) FlushAsync() *abcicli.ReqRes { - ret := _m.Called() +// FlushAsync provides a mock function with given fields: _a0 +func (_m *Client) FlushAsync(_a0 abcicli.ResponseCallback) *abcicli.ReqRes { + ret := _m.Called(_a0) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func() *abcicli.ReqRes); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(abcicli.ResponseCallback) *abcicli.ReqRes); ok { + r0 = rf(_a0) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) @@ -320,26 +398,51 @@ func (_m *Client) FlushAsync() *abcicli.ReqRes { } // FlushSync provides a mock function with given fields: -func (_m *Client) FlushSync() error { +func (_m *Client) FlushSync() (*types.ResponseFlush, error) { ret := _m.Called() - var r0 error - if rf, ok := ret.Get(0).(func() error); ok { + var r0 *types.ResponseFlush + if rf, ok := ret.Get(0).(func() *types.ResponseFlush); ok { r0 = rf() } else { - r0 = ret.Error(0) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseFlush) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetGlobalCallback provides a mock function with given fields: +func (_m *Client) GetGlobalCallback() abcicli.GlobalCallback { + ret := _m.Called() + + var r0 abcicli.GlobalCallback + if rf, ok := ret.Get(0).(func() abcicli.GlobalCallback); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(abcicli.GlobalCallback) + } } return r0 } -// InfoAsync provides a mock function with given fields: _a0 -func (_m *Client) InfoAsync(_a0 types.RequestInfo) *abcicli.ReqRes { - ret := _m.Called(_a0) +// InfoAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) InfoAsync(_a0 types.RequestInfo, _a1 abcicli.ResponseCallback) *abcicli.ReqRes { + ret := _m.Called(_a0, _a1) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestInfo) *abcicli.ReqRes); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(types.RequestInfo, abcicli.ResponseCallback) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) @@ -372,13 +475,13 @@ 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 { - ret := _m.Called(_a0) +// InitChainAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) InitChainAsync(_a0 types.RequestInitChain, _a1 abcicli.ResponseCallback) *abcicli.ReqRes { + ret := _m.Called(_a0, _a1) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestInitChain) *abcicli.ReqRes); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(types.RequestInitChain, abcicli.ResponseCallback) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) @@ -425,13 +528,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) +// ListSnapshotsAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) ListSnapshotsAsync(_a0 types.RequestListSnapshots, _a1 abcicli.ResponseCallback) *abcicli.ReqRes { + ret := _m.Called(_a0, _a1) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestListSnapshots) *abcicli.ReqRes); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(types.RequestListSnapshots, abcicli.ResponseCallback) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) @@ -464,13 +567,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) +// LoadSnapshotChunkAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) LoadSnapshotChunkAsync(_a0 types.RequestLoadSnapshotChunk, _a1 abcicli.ResponseCallback) *abcicli.ReqRes { + ret := _m.Called(_a0, _a1) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestLoadSnapshotChunk) *abcicli.ReqRes); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(types.RequestLoadSnapshotChunk, abcicli.ResponseCallback) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) @@ -503,13 +606,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) +// OfferSnapshotAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) OfferSnapshotAsync(_a0 types.RequestOfferSnapshot, _a1 abcicli.ResponseCallback) *abcicli.ReqRes { + ret := _m.Called(_a0, _a1) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestOfferSnapshot) *abcicli.ReqRes); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(types.RequestOfferSnapshot, abcicli.ResponseCallback) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) @@ -575,13 +678,13 @@ func (_m *Client) OnStop() { _m.Called() } -// QueryAsync provides a mock function with given fields: _a0 -func (_m *Client) QueryAsync(_a0 types.RequestQuery) *abcicli.ReqRes { - ret := _m.Called(_a0) +// QueryAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) QueryAsync(_a0 types.RequestQuery, _a1 abcicli.ResponseCallback) *abcicli.ReqRes { + ret := _m.Called(_a0, _a1) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestQuery) *abcicli.ReqRes); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(types.RequestQuery, abcicli.ResponseCallback) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) @@ -644,18 +747,23 @@ func (_m *Client) Reset() error { return r0 } +// SetGlobalCallback provides a mock function with given fields: _a0 +func (_m *Client) SetGlobalCallback(_a0 abcicli.GlobalCallback) { + _m.Called(_a0) +} + // SetLogger provides a mock function with given fields: _a0 func (_m *Client) SetLogger(_a0 log.Logger) { _m.Called(_a0) } -// SetOptionAsync provides a mock function with given fields: _a0 -func (_m *Client) SetOptionAsync(_a0 types.RequestSetOption) *abcicli.ReqRes { - ret := _m.Called(_a0) +// SetOptionAsync provides a mock function with given fields: _a0, _a1 +func (_m *Client) SetOptionAsync(_a0 types.RequestSetOption, _a1 abcicli.ResponseCallback) *abcicli.ReqRes { + ret := _m.Called(_a0, _a1) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestSetOption) *abcicli.ReqRes); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(types.RequestSetOption, abcicli.ResponseCallback) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) @@ -688,11 +796,6 @@ func (_m *Client) SetOptionSync(_a0 types.RequestSetOption) (*types.ResponseSetO return r0, r1 } -// SetResponseCallback provides a mock function with given fields: _a0 -func (_m *Client) SetResponseCallback(_a0 abcicli.Callback) { - _m.Called(_a0) -} - // Start provides a mock function with given fields: func (_m *Client) Start() error { ret := _m.Called() diff --git a/abci/client/socket_client.go b/abci/client/socket_client.go index 736a9a1d6..147e2a641 100644 --- a/abci/client/socket_client.go +++ b/abci/client/socket_client.go @@ -36,8 +36,10 @@ type socketClient struct { mtx tmsync.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. + reqSent *list.List // list of requests sent, waiting for response + + globalCbMtx tmsync.Mutex + globalCb GlobalCallback } var _ Client = (*socketClient)(nil) @@ -51,9 +53,9 @@ func NewSocketClient(addr string, mustConnect bool) Client { flushTimer: timer.NewThrottleTimer("socketClient", flushThrottleMS), mustConnect: mustConnect, - addr: addr, - reqSent: list.New(), - resCb: nil, + addr: addr, + reqSent: list.New(), + globalCb: nil, } cli.BaseService = *service.NewBaseService(nil, "socketClient", cli) return cli @@ -104,14 +106,17 @@ 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. -// -// NOTE: callback may get internally generated flush responses. -func (cli *socketClient) SetResponseCallback(resCb Callback) { - cli.mtx.Lock() - cli.resCb = resCb - cli.mtx.Unlock() +func (cli *socketClient) SetGlobalCallback(globalCb GlobalCallback) { + cli.globalCbMtx.Lock() + cli.globalCb = globalCb + cli.globalCbMtx.Unlock() +} + +func (cli *socketClient) GetGlobalCallback() (cb GlobalCallback) { + cli.globalCbMtx.Lock() + cb = cli.globalCb + cli.globalCbMtx.Unlock() + return cb } //---------------------------------------- @@ -140,7 +145,7 @@ func (cli *socketClient) sendRequestsRoutine(conn io.Writer) { } case <-cli.flushTimer.Ch: // flush queue select { - case cli.reqQueue <- NewReqRes(types.ToRequestFlush()): + case cli.reqQueue <- NewReqRes(types.ToRequestFlush(), nil): default: // Probably will fill the buffer, or retry later. } @@ -200,12 +205,12 @@ func (cli *socketClient) didRecvResponse(res *types.Response) error { } reqres.Response = res - reqres.Done() // release waiters + reqres.wg.Done() // release waiters cli.reqSent.Remove(next) // pop first item from linked list // Notify client listener if set (global callback). - if cli.resCb != nil { - cli.resCb(reqres.Request, res) + if cli.globalCb != nil { + cli.globalCb(reqres.Request, res) } // Notify reqRes listener if set (request specific callback). @@ -219,80 +224,88 @@ func (cli *socketClient) didRecvResponse(res *types.Response) error { //---------------------------------------- -func (cli *socketClient) EchoAsync(msg string) *ReqRes { - return cli.queueRequest(types.ToRequestEcho(msg)) +func (cli *socketClient) EchoAsync(msg string, cb ResponseCallback) *ReqRes { + return cli.queueRequest(types.ToRequestEcho(msg), cb) } -func (cli *socketClient) FlushAsync() *ReqRes { - return cli.queueRequest(types.ToRequestFlush()) +func (cli *socketClient) FlushAsync(cb ResponseCallback) *ReqRes { + return cli.queueRequest(types.ToRequestFlush(), cb) } -func (cli *socketClient) InfoAsync(req types.RequestInfo) *ReqRes { - return cli.queueRequest(types.ToRequestInfo(req)) +func (cli *socketClient) InfoAsync(req types.RequestInfo, cb ResponseCallback) *ReqRes { + return cli.queueRequest(types.ToRequestInfo(req), cb) } -func (cli *socketClient) SetOptionAsync(req types.RequestSetOption) *ReqRes { - return cli.queueRequest(types.ToRequestSetOption(req)) +func (cli *socketClient) SetOptionAsync(req types.RequestSetOption, cb ResponseCallback) *ReqRes { + return cli.queueRequest(types.ToRequestSetOption(req), cb) } -func (cli *socketClient) DeliverTxAsync(req types.RequestDeliverTx) *ReqRes { - return cli.queueRequest(types.ToRequestDeliverTx(req)) +func (cli *socketClient) DeliverTxAsync(req types.RequestDeliverTx, cb ResponseCallback) *ReqRes { + return cli.queueRequest(types.ToRequestDeliverTx(req), cb) } -func (cli *socketClient) CheckTxAsync(req types.RequestCheckTx) *ReqRes { - return cli.queueRequest(types.ToRequestCheckTx(req)) +func (cli *socketClient) CheckTxAsync(req types.RequestCheckTx, cb ResponseCallback) *ReqRes { + return cli.queueRequest(types.ToRequestCheckTx(req), cb) } -func (cli *socketClient) QueryAsync(req types.RequestQuery) *ReqRes { - return cli.queueRequest(types.ToRequestQuery(req)) +func (cli *socketClient) QueryAsync(req types.RequestQuery, cb ResponseCallback) *ReqRes { + return cli.queueRequest(types.ToRequestQuery(req), cb) } -func (cli *socketClient) CommitAsync() *ReqRes { - return cli.queueRequest(types.ToRequestCommit()) +func (cli *socketClient) CommitAsync(cb ResponseCallback) *ReqRes { + return cli.queueRequest(types.ToRequestCommit(), cb) } -func (cli *socketClient) InitChainAsync(req types.RequestInitChain) *ReqRes { - return cli.queueRequest(types.ToRequestInitChain(req)) +func (cli *socketClient) InitChainAsync(req types.RequestInitChain, cb ResponseCallback) *ReqRes { + return cli.queueRequest(types.ToRequestInitChain(req), cb) } -func (cli *socketClient) BeginBlockAsync(req types.RequestBeginBlock) *ReqRes { - return cli.queueRequest(types.ToRequestBeginBlock(req)) +func (cli *socketClient) BeginBlockAsync(req types.RequestBeginBlock, cb ResponseCallback) *ReqRes { + return cli.queueRequest(types.ToRequestBeginBlock(req), cb) } -func (cli *socketClient) EndBlockAsync(req types.RequestEndBlock) *ReqRes { - return cli.queueRequest(types.ToRequestEndBlock(req)) +func (cli *socketClient) EndBlockAsync(req types.RequestEndBlock, cb ResponseCallback) *ReqRes { + return cli.queueRequest(types.ToRequestEndBlock(req), cb) } -func (cli *socketClient) ListSnapshotsAsync(req types.RequestListSnapshots) *ReqRes { - return cli.queueRequest(types.ToRequestListSnapshots(req)) +func (cli *socketClient) BeginRecheckTxAsync(req types.RequestBeginRecheckTx, cb ResponseCallback) *ReqRes { + return cli.queueRequest(types.ToRequestBeginRecheckTx(req), cb) } -func (cli *socketClient) OfferSnapshotAsync(req types.RequestOfferSnapshot) *ReqRes { - return cli.queueRequest(types.ToRequestOfferSnapshot(req)) +func (cli *socketClient) EndRecheckTxAsync(req types.RequestEndRecheckTx, cb ResponseCallback) *ReqRes { + return cli.queueRequest(types.ToRequestEndRecheckTx(req), cb) } -func (cli *socketClient) LoadSnapshotChunkAsync(req types.RequestLoadSnapshotChunk) *ReqRes { - return cli.queueRequest(types.ToRequestLoadSnapshotChunk(req)) +func (cli *socketClient) ListSnapshotsAsync(req types.RequestListSnapshots, cb ResponseCallback) *ReqRes { + return cli.queueRequest(types.ToRequestListSnapshots(req), cb) } -func (cli *socketClient) ApplySnapshotChunkAsync(req types.RequestApplySnapshotChunk) *ReqRes { - return cli.queueRequest(types.ToRequestApplySnapshotChunk(req)) +func (cli *socketClient) OfferSnapshotAsync(req types.RequestOfferSnapshot, cb ResponseCallback) *ReqRes { + return cli.queueRequest(types.ToRequestOfferSnapshot(req), cb) +} + +func (cli *socketClient) LoadSnapshotChunkAsync(req types.RequestLoadSnapshotChunk, cb ResponseCallback) *ReqRes { + return cli.queueRequest(types.ToRequestLoadSnapshotChunk(req), cb) +} + +func (cli *socketClient) ApplySnapshotChunkAsync(req types.RequestApplySnapshotChunk, cb ResponseCallback) *ReqRes { + return cli.queueRequest(types.ToRequestApplySnapshotChunk(req), cb) } //---------------------------------------- -func (cli *socketClient) FlushSync() error { - reqRes := cli.queueRequest(types.ToRequestFlush()) +func (cli *socketClient) FlushSync() (*types.ResponseFlush, error) { + reqRes := cli.queueRequest(types.ToRequestFlush(), nil) if err := cli.Error(); err != nil { - return err + return nil, err } reqRes.Wait() // NOTE: if we don't flush the queue, its possible to get stuck here - return cli.Error() + return reqRes.Response.GetFlush(), cli.Error() } func (cli *socketClient) EchoSync(msg string) (*types.ResponseEcho, error) { - reqres := cli.queueRequest(types.ToRequestEcho(msg)) - if err := cli.FlushSync(); err != nil { + reqres := cli.queueRequest(types.ToRequestEcho(msg), nil) + if _, err := cli.FlushSync(); err != nil { return nil, err } @@ -300,8 +313,8 @@ func (cli *socketClient) EchoSync(msg string) (*types.ResponseEcho, error) { } func (cli *socketClient) InfoSync(req types.RequestInfo) (*types.ResponseInfo, error) { - reqres := cli.queueRequest(types.ToRequestInfo(req)) - if err := cli.FlushSync(); err != nil { + reqres := cli.queueRequest(types.ToRequestInfo(req), nil) + if _, err := cli.FlushSync(); err != nil { return nil, err } @@ -309,8 +322,8 @@ func (cli *socketClient) InfoSync(req types.RequestInfo) (*types.ResponseInfo, e } func (cli *socketClient) SetOptionSync(req types.RequestSetOption) (*types.ResponseSetOption, error) { - reqres := cli.queueRequest(types.ToRequestSetOption(req)) - if err := cli.FlushSync(); err != nil { + reqres := cli.queueRequest(types.ToRequestSetOption(req), nil) + if _, err := cli.FlushSync(); err != nil { return nil, err } @@ -318,8 +331,8 @@ func (cli *socketClient) SetOptionSync(req types.RequestSetOption) (*types.Respo } func (cli *socketClient) DeliverTxSync(req types.RequestDeliverTx) (*types.ResponseDeliverTx, error) { - reqres := cli.queueRequest(types.ToRequestDeliverTx(req)) - if err := cli.FlushSync(); err != nil { + reqres := cli.queueRequest(types.ToRequestDeliverTx(req), nil) + if _, err := cli.FlushSync(); err != nil { return nil, err } @@ -327,8 +340,8 @@ func (cli *socketClient) DeliverTxSync(req types.RequestDeliverTx) (*types.Respo } func (cli *socketClient) CheckTxSync(req types.RequestCheckTx) (*types.ResponseCheckTx, error) { - reqres := cli.queueRequest(types.ToRequestCheckTx(req)) - if err := cli.FlushSync(); err != nil { + reqres := cli.queueRequest(types.ToRequestCheckTx(req), nil) + if _, err := cli.FlushSync(); err != nil { return nil, err } @@ -336,8 +349,8 @@ func (cli *socketClient) CheckTxSync(req types.RequestCheckTx) (*types.ResponseC } func (cli *socketClient) QuerySync(req types.RequestQuery) (*types.ResponseQuery, error) { - reqres := cli.queueRequest(types.ToRequestQuery(req)) - if err := cli.FlushSync(); err != nil { + reqres := cli.queueRequest(types.ToRequestQuery(req), nil) + if _, err := cli.FlushSync(); err != nil { return nil, err } @@ -345,8 +358,8 @@ func (cli *socketClient) QuerySync(req types.RequestQuery) (*types.ResponseQuery } func (cli *socketClient) CommitSync() (*types.ResponseCommit, error) { - reqres := cli.queueRequest(types.ToRequestCommit()) - if err := cli.FlushSync(); err != nil { + reqres := cli.queueRequest(types.ToRequestCommit(), nil) + if _, err := cli.FlushSync(); err != nil { return nil, err } @@ -354,8 +367,8 @@ func (cli *socketClient) CommitSync() (*types.ResponseCommit, error) { } func (cli *socketClient) InitChainSync(req types.RequestInitChain) (*types.ResponseInitChain, error) { - reqres := cli.queueRequest(types.ToRequestInitChain(req)) - if err := cli.FlushSync(); err != nil { + reqres := cli.queueRequest(types.ToRequestInitChain(req), nil) + if _, err := cli.FlushSync(); err != nil { return nil, err } @@ -363,8 +376,8 @@ func (cli *socketClient) InitChainSync(req types.RequestInitChain) (*types.Respo } func (cli *socketClient) BeginBlockSync(req types.RequestBeginBlock) (*types.ResponseBeginBlock, error) { - reqres := cli.queueRequest(types.ToRequestBeginBlock(req)) - if err := cli.FlushSync(); err != nil { + reqres := cli.queueRequest(types.ToRequestBeginBlock(req), nil) + if _, err := cli.FlushSync(); err != nil { return nil, err } @@ -372,17 +385,35 @@ func (cli *socketClient) BeginBlockSync(req types.RequestBeginBlock) (*types.Res } func (cli *socketClient) EndBlockSync(req types.RequestEndBlock) (*types.ResponseEndBlock, error) { - reqres := cli.queueRequest(types.ToRequestEndBlock(req)) - if err := cli.FlushSync(); err != nil { + reqres := cli.queueRequest(types.ToRequestEndBlock(req), nil) + if _, err := cli.FlushSync(); err != nil { return nil, err } return reqres.Response.GetEndBlock(), cli.Error() } +func (cli *socketClient) BeginRecheckTxSync(req types.RequestBeginRecheckTx) (*types.ResponseBeginRecheckTx, error) { + reqres := cli.queueRequest(types.ToRequestBeginRecheckTx(req), nil) + if _, err := cli.FlushSync(); err != nil { + return nil, err + } + + return reqres.Response.GetBeginRecheckTx(), cli.Error() +} + +func (cli *socketClient) EndRecheckTxSync(req types.RequestEndRecheckTx) (*types.ResponseEndRecheckTx, error) { + reqres := cli.queueRequest(types.ToRequestEndRecheckTx(req), nil) + if _, err := cli.FlushSync(); err != nil { + return nil, err + } + + return reqres.Response.GetEndRecheckTx(), cli.Error() +} + func (cli *socketClient) ListSnapshotsSync(req types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { - reqres := cli.queueRequest(types.ToRequestListSnapshots(req)) - if err := cli.FlushSync(); err != nil { + reqres := cli.queueRequest(types.ToRequestListSnapshots(req), nil) + if _, err := cli.FlushSync(); err != nil { return nil, err } @@ -390,8 +421,8 @@ func (cli *socketClient) ListSnapshotsSync(req types.RequestListSnapshots) (*typ } func (cli *socketClient) OfferSnapshotSync(req types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { - reqres := cli.queueRequest(types.ToRequestOfferSnapshot(req)) - if err := cli.FlushSync(); err != nil { + reqres := cli.queueRequest(types.ToRequestOfferSnapshot(req), nil) + if _, err := cli.FlushSync(); err != nil { return nil, err } @@ -400,8 +431,8 @@ func (cli *socketClient) OfferSnapshotSync(req types.RequestOfferSnapshot) (*typ func (cli *socketClient) LoadSnapshotChunkSync( req types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { - reqres := cli.queueRequest(types.ToRequestLoadSnapshotChunk(req)) - if err := cli.FlushSync(); err != nil { + reqres := cli.queueRequest(types.ToRequestLoadSnapshotChunk(req), nil) + if _, err := cli.FlushSync(); err != nil { return nil, err } @@ -410,8 +441,8 @@ func (cli *socketClient) LoadSnapshotChunkSync( func (cli *socketClient) ApplySnapshotChunkSync( req types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { - reqres := cli.queueRequest(types.ToRequestApplySnapshotChunk(req)) - if err := cli.FlushSync(); err != nil { + reqres := cli.queueRequest(types.ToRequestApplySnapshotChunk(req), nil) + if _, err := cli.FlushSync(); err != nil { return nil, err } return reqres.Response.GetApplySnapshotChunk(), cli.Error() @@ -419,8 +450,8 @@ func (cli *socketClient) ApplySnapshotChunkSync( //---------------------------------------- -func (cli *socketClient) queueRequest(req *types.Request) *ReqRes { - reqres := NewReqRes(req) +func (cli *socketClient) queueRequest(req *types.Request, cb ResponseCallback) *ReqRes { + reqres := NewReqRes(req, cb) // TODO: set cli.err if reqQueue times out cli.reqQueue <- reqres @@ -443,7 +474,7 @@ func (cli *socketClient) flushQueue() { // mark all in-flight messages as resolved (they will get cli.Error()) for req := cli.reqSent.Front(); req != nil; req = req.Next() { reqres := req.Value.(*ReqRes) - reqres.Done() + reqres.wg.Done() } // mark all queued messages as resolved @@ -451,7 +482,7 @@ LOOP: for { select { case reqres := <-cli.reqQueue: - reqres.Done() + reqres.wg.Done() default: break LOOP } @@ -484,6 +515,10 @@ func resMatchesReq(req *types.Request, res *types.Response) (ok bool) { _, ok = res.Value.(*types.Response_BeginBlock) case *types.Request_EndBlock: _, ok = res.Value.(*types.Response_EndBlock) + case *types.Request_BeginRecheckTx: + _, ok = res.Value.(*types.Response_BeginRecheckTx) + case *types.Request_EndRecheckTx: + _, ok = res.Value.(*types.Response_EndRecheckTx) case *types.Request_ApplySnapshotChunk: _, ok = res.Value.(*types.Response_ApplySnapshotChunk) case *types.Request_LoadSnapshotChunk: diff --git a/abci/client/socket_client_test.go b/abci/client/socket_client_test.go index 478bbb4ae..b18c08225 100644 --- a/abci/client/socket_client_test.go +++ b/abci/client/socket_client_test.go @@ -33,8 +33,8 @@ func TestProperSyncCalls(t *testing.T) { resp := make(chan error, 1) go func() { // This is BeginBlockSync unrolled.... - reqres := c.BeginBlockAsync(types.RequestBeginBlock{}) - err := c.FlushSync() + reqres := c.BeginBlockAsync(types.RequestBeginBlock{}, nil) + _, err := c.FlushSync() require.NoError(t, err) res := reqres.Response.GetBeginBlock() require.NotNil(t, res) @@ -68,8 +68,8 @@ func TestHangingSyncCalls(t *testing.T) { resp := make(chan error, 1) go func() { // Start BeginBlock and flush it - reqres := c.BeginBlockAsync(types.RequestBeginBlock{}) - flush := c.FlushAsync() + reqres := c.BeginBlockAsync(types.RequestBeginBlock{}, nil) + flush := c.FlushAsync(nil) // wait 20 ms for all events to travel socket, but // no response yet from server time.Sleep(20 * time.Millisecond) @@ -118,3 +118,116 @@ func (slowApp) BeginBlock(req types.RequestBeginBlock) types.ResponseBeginBlock time.Sleep(200 * time.Millisecond) return types.ResponseBeginBlock{} } + +func TestSockerClientCalls(t *testing.T) { + app := sampleApp{} + + 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.SetGlobalCallback(func(*types.Request, *types.Response) { + }) + + c.EchoAsync("msg", getResponseCallback(t)) + c.FlushAsync(getResponseCallback(t)) + c.InfoAsync(types.RequestInfo{}, getResponseCallback(t)) + c.SetOptionAsync(types.RequestSetOption{}, getResponseCallback(t)) + c.DeliverTxAsync(types.RequestDeliverTx{}, getResponseCallback(t)) + c.CheckTxAsync(types.RequestCheckTx{}, getResponseCallback(t)) + c.QueryAsync(types.RequestQuery{}, getResponseCallback(t)) + c.CommitAsync(getResponseCallback(t)) + c.InitChainAsync(types.RequestInitChain{}, getResponseCallback(t)) + c.BeginBlockAsync(types.RequestBeginBlock{}, getResponseCallback(t)) + c.EndBlockAsync(types.RequestEndBlock{}, getResponseCallback(t)) + c.BeginRecheckTxAsync(types.RequestBeginRecheckTx{}, getResponseCallback(t)) + c.EndRecheckTxAsync(types.RequestEndRecheckTx{}, getResponseCallback(t)) + c.ListSnapshotsAsync(types.RequestListSnapshots{}, getResponseCallback(t)) + c.OfferSnapshotAsync(types.RequestOfferSnapshot{}, getResponseCallback(t)) + c.LoadSnapshotChunkAsync(types.RequestLoadSnapshotChunk{}, getResponseCallback(t)) + c.ApplySnapshotChunkAsync(types.RequestApplySnapshotChunk{}, getResponseCallback(t)) + + _, err := c.EchoSync("msg") + require.NoError(t, err) + + _, err = c.FlushSync() + require.NoError(t, err) + + _, err = c.InfoSync(types.RequestInfo{}) + require.NoError(t, err) + + _, err = c.SetOptionSync(types.RequestSetOption{}) + require.NoError(t, err) + + _, err = c.DeliverTxSync(types.RequestDeliverTx{}) + require.NoError(t, err) + + _, err = c.CheckTxSync(types.RequestCheckTx{}) + require.NoError(t, err) + + _, err = c.QuerySync(types.RequestQuery{}) + require.NoError(t, err) + + _, err = c.CommitSync() + require.NoError(t, err) + + _, err = c.InitChainSync(types.RequestInitChain{}) + require.NoError(t, err) + + _, err = c.BeginBlockSync(types.RequestBeginBlock{}) + require.NoError(t, err) + + _, err = c.EndBlockSync(types.RequestEndBlock{}) + require.NoError(t, err) + + _, err = c.BeginRecheckTxSync(types.RequestBeginRecheckTx{}) + require.NoError(t, err) + + _, err = c.EndRecheckTxSync(types.RequestEndRecheckTx{}) + require.NoError(t, err) + + _, err = c.ListSnapshotsSync(types.RequestListSnapshots{}) + require.NoError(t, err) + + _, err = c.OfferSnapshotSync(types.RequestOfferSnapshot{}) + require.NoError(t, err) + + _, err = c.LoadSnapshotChunkSync(types.RequestLoadSnapshotChunk{}) + require.NoError(t, err) + + _, err = c.ApplySnapshotChunkSync(types.RequestApplySnapshotChunk{}) + require.NoError(t, err) +} + +type sampleApp struct { + types.BaseApplication +} + +func newDoneChan(t *testing.T) chan struct{} { + result := make(chan struct{}) + go func(){ + select { + case <-time.After(time.Second): + require.Fail(t, "callback is not called for a second") + case <-result: + return + } + }() + return result +} + +func getResponseCallback(t *testing.T) abcicli.ResponseCallback { + doneChan := newDoneChan(t) + return func (res *types.Response) { + require.NotNil(t, res) + doneChan<- struct{}{} + } +} diff --git a/abci/cmd/abci-cli/abci-cli.go b/abci/cmd/abci-cli/abci-cli.go index fbad683e7..d00b82995 100644 --- a/abci/cmd/abci-cli/abci-cli.go +++ b/abci/cmd/abci-cli/abci-cli.go @@ -69,7 +69,7 @@ var RootCmd = &cobra.Command{ if err != nil { return err } - logger = log.NewFilter(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), allowLevel) + logger = log.NewFilter(log.NewOCLogger(log.NewSyncWriter(os.Stdout)), allowLevel) } if client == nil { var err error @@ -627,7 +627,7 @@ func cmdQuery(cmd *cobra.Command, args []string) error { func cmdCounter(cmd *cobra.Command, args []string) error { app := counter.NewApplication(flagSerial) - logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) + logger := log.NewOCLogger(log.NewSyncWriter(os.Stdout)) // Start the listener srv, err := server.NewServer(flagAddress, flagAbci, app) @@ -652,7 +652,7 @@ func cmdCounter(cmd *cobra.Command, args []string) error { } func cmdKVStore(cmd *cobra.Command, args []string) error { - logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) + logger := log.NewOCLogger(log.NewSyncWriter(os.Stdout)) // Create the application - in memory or persisted to disk var app types.Application diff --git a/abci/example/counter/counter.go b/abci/example/counter/counter.go index d5dae6d5a..3c9225e0e 100644 --- a/abci/example/counter/counter.go +++ b/abci/example/counter/counter.go @@ -62,7 +62,15 @@ func (app *Application) DeliverTx(req types.RequestDeliverTx) types.ResponseDeli return types.ResponseDeliverTx{Code: code.CodeTypeOK} } -func (app *Application) CheckTx(req types.RequestCheckTx) types.ResponseCheckTx { +func (app *Application) CheckTxSync(req types.RequestCheckTx) types.ResponseCheckTx { + return app.checkTx(req) +} + +func (app *Application) CheckTxAsync(req types.RequestCheckTx, callback types.CheckTxCallback) { + callback(app.checkTx(req)) +} + +func (app *Application) checkTx(req types.RequestCheckTx) types.ResponseCheckTx { if app.serial { if len(req.Tx) > 8 { return types.ResponseCheckTx{ diff --git a/abci/example/example_test.go b/abci/example/example_test.go index 1d2497ca2..3e67afdc8 100644 --- a/abci/example/example_test.go +++ b/abci/example/example_test.go @@ -76,7 +76,7 @@ func testStream(t *testing.T, app types.Application) { done := make(chan struct{}) counter := 0 - client.SetResponseCallback(func(req *types.Request, res *types.Response) { + client.SetGlobalCallback(func(req *types.Request, res *types.Response) { // Process response switch r := res.Value.(type) { case *types.Response_DeliverTx: @@ -104,19 +104,19 @@ func testStream(t *testing.T, app types.Application) { // Write requests for counter := 0; counter < numDeliverTxs; counter++ { // Send request - reqRes := client.DeliverTxAsync(types.RequestDeliverTx{Tx: []byte("test")}) + reqRes := client.DeliverTxAsync(types.RequestDeliverTx{Tx: []byte("test")}, nil) _ = reqRes // check err ? // Sometimes send flush messages if counter%123 == 0 { - client.FlushAsync() + client.FlushAsync(nil) // check err ? } } // Send final flush message - client.FlushAsync() + client.FlushAsync(nil) <-done } diff --git a/abci/example/kvstore/kvstore.go b/abci/example/kvstore/kvstore.go index d41759564..4b1e76553 100644 --- a/abci/example/kvstore/kvstore.go +++ b/abci/example/kvstore/kvstore.go @@ -6,7 +6,8 @@ import ( "encoding/json" "fmt" - dbm "github.com/tendermint/tm-db" + dbm "github.com/line/tm-db/v2" + "github.com/line/tm-db/v2/memdb" "github.com/line/ostracon/abci/example/code" "github.com/line/ostracon/abci/types" @@ -71,7 +72,7 @@ type Application struct { } func NewApplication() *Application { - state := loadState(dbm.NewMemDB()) + state := loadState(memdb.NewDB()) return &Application{state: state} } @@ -116,7 +117,15 @@ func (app *Application) DeliverTx(req types.RequestDeliverTx) types.ResponseDeli return types.ResponseDeliverTx{Code: code.CodeTypeOK, Events: events} } -func (app *Application) CheckTx(req types.RequestCheckTx) types.ResponseCheckTx { +func (app *Application) CheckTxSync(req types.RequestCheckTx) types.ResponseCheckTx { + return app.checkTx(req) +} + +func (app *Application) CheckTxAsync(req types.RequestCheckTx, callback types.CheckTxCallback) { + callback(app.checkTx(req)) +} + +func (app *Application) checkTx(req types.RequestCheckTx) types.ResponseCheckTx { return types.ResponseCheckTx{Code: code.CodeTypeOK, GasWanted: 1} } diff --git a/abci/example/kvstore/persistent_kvstore.go b/abci/example/kvstore/persistent_kvstore.go index 5eba55553..bc269bf37 100644 --- a/abci/example/kvstore/persistent_kvstore.go +++ b/abci/example/kvstore/persistent_kvstore.go @@ -7,13 +7,12 @@ import ( "strconv" "strings" - dbm "github.com/tendermint/tm-db" - "github.com/line/ostracon/abci/example/code" "github.com/line/ostracon/abci/types" cryptoenc "github.com/line/ostracon/crypto/encoding" "github.com/line/ostracon/libs/log" pc "github.com/line/ostracon/proto/ostracon/crypto" + "github.com/line/tm-db/v2/goleveldb" ) const ( @@ -37,7 +36,7 @@ type PersistentKVStoreApplication struct { func NewPersistentKVStoreApplication(dbDir string) *PersistentKVStoreApplication { name := "kvstore" - db, err := dbm.NewGoLevelDB(name, dbDir) + db, err := goleveldb.NewDB(name, dbDir) if err != nil { panic(err) } @@ -80,8 +79,20 @@ func (app *PersistentKVStoreApplication) DeliverTx(req types.RequestDeliverTx) t return app.app.DeliverTx(req) } -func (app *PersistentKVStoreApplication) CheckTx(req types.RequestCheckTx) types.ResponseCheckTx { - return app.app.CheckTx(req) +func (app *PersistentKVStoreApplication) CheckTxSync(req types.RequestCheckTx) types.ResponseCheckTx { + return app.app.CheckTxSync(req) +} + +func (app *PersistentKVStoreApplication) CheckTxAsync(req types.RequestCheckTx, callback types.CheckTxCallback) { + app.app.CheckTxAsync(req, callback) +} + +func (app *PersistentKVStoreApplication) BeginRecheckTx(req types.RequestBeginRecheckTx) types.ResponseBeginRecheckTx { + return app.app.BeginRecheckTx(req) +} + +func (app *PersistentKVStoreApplication) EndRecheckTx(req types.RequestEndRecheckTx) types.ResponseEndRecheckTx { + return app.app.EndRecheckTx(req) } // Commit will panic if InitChain was not called diff --git a/abci/server/socket_server.go b/abci/server/socket_server.go index 7711e4fae..42e7b6ad1 100644 --- a/abci/server/socket_server.go +++ b/abci/server/socket_server.go @@ -207,7 +207,7 @@ func (s *SocketServer) handleRequest(req *types.Request, responses chan<- *types res := s.app.DeliverTx(*r.DeliverTx) responses <- types.ToResponseDeliverTx(res) case *types.Request_CheckTx: - res := s.app.CheckTx(*r.CheckTx) + res := s.app.CheckTxSync(*r.CheckTx) responses <- types.ToResponseCheckTx(res) case *types.Request_Commit: res := s.app.Commit() @@ -224,6 +224,12 @@ func (s *SocketServer) handleRequest(req *types.Request, responses chan<- *types case *types.Request_EndBlock: res := s.app.EndBlock(*r.EndBlock) responses <- types.ToResponseEndBlock(res) + case *types.Request_BeginRecheckTx: + res := s.app.BeginRecheckTx(*r.BeginRecheckTx) + responses <- types.ToResponseBeginRecheckTx(res) + case *types.Request_EndRecheckTx: + res := s.app.EndRecheckTx(*r.EndRecheckTx) + responses <- types.ToResponseEndRecheckTx(res) case *types.Request_ListSnapshots: res := s.app.ListSnapshots(*r.ListSnapshots) responses <- types.ToResponseListSnapshots(res) diff --git a/abci/tests/test_app/app.go b/abci/tests/test_app/app.go index 27931c830..946096f0e 100644 --- a/abci/tests/test_app/app.go +++ b/abci/tests/test_app/app.go @@ -16,7 +16,7 @@ func startClient(abciType string) abcicli.Client { if err != nil { panic(err.Error()) } - logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) + logger := log.NewOCLogger(log.NewSyncWriter(os.Stdout)) client.SetLogger(logger.With("module", "abcicli")) if err := client.Start(); err != nil { panicf("connecting to abci_app: %v", err.Error()) diff --git a/abci/types/application.go b/abci/types/application.go index 65cc78b8c..37ecae3d9 100644 --- a/abci/types/application.go +++ b/abci/types/application.go @@ -4,6 +4,8 @@ import ( context "golang.org/x/net/context" ) +type CheckTxCallback func(ResponseCheckTx) + // 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, @@ -15,10 +17,13 @@ type Application interface { Query(RequestQuery) ResponseQuery // Query for state // Mempool Connection - CheckTx(RequestCheckTx) ResponseCheckTx // Validate a tx for the mempool + CheckTxSync(RequestCheckTx) ResponseCheckTx // Validate a tx for the mempool + CheckTxAsync(RequestCheckTx, CheckTxCallback) // Asynchronously validate a tx for the mempool + BeginRecheckTx(RequestBeginRecheckTx) ResponseBeginRecheckTx // Signals the beginning of rechecking + EndRecheckTx(RequestEndRecheckTx) ResponseEndRecheckTx // Signals the end of rechecking // Consensus Connection - InitChain(RequestInitChain) ResponseInitChain // Initialize blockchain w validators/other info from TendermintCore + InitChain(RequestInitChain) ResponseInitChain // Initialize blockchain w validators/other info from OstraconCore 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 @@ -55,10 +60,22 @@ func (BaseApplication) DeliverTx(req RequestDeliverTx) ResponseDeliverTx { return ResponseDeliverTx{Code: CodeTypeOK} } -func (BaseApplication) CheckTx(req RequestCheckTx) ResponseCheckTx { +func (BaseApplication) CheckTxSync(req RequestCheckTx) ResponseCheckTx { return ResponseCheckTx{Code: CodeTypeOK} } +func (BaseApplication) CheckTxAsync(req RequestCheckTx, callback CheckTxCallback) { + callback(ResponseCheckTx{Code: CodeTypeOK}) +} + +func (BaseApplication) BeginRecheckTx(req RequestBeginRecheckTx) ResponseBeginRecheckTx { + return ResponseBeginRecheckTx{Code: CodeTypeOK} +} + +func (BaseApplication) EndRecheckTx(req RequestEndRecheckTx) ResponseEndRecheckTx { + return ResponseEndRecheckTx{Code: CodeTypeOK} +} + func (BaseApplication) Commit() ResponseCommit { return ResponseCommit{} } @@ -130,7 +147,18 @@ func (app *GRPCApplication) DeliverTx(ctx context.Context, req *RequestDeliverTx } func (app *GRPCApplication) CheckTx(ctx context.Context, req *RequestCheckTx) (*ResponseCheckTx, error) { - res := app.app.CheckTx(*req) + res := app.app.CheckTxSync(*req) + return &res, nil +} + +func (app *GRPCApplication) BeginRecheckTx(ctx context.Context, req *RequestBeginRecheckTx) ( + *ResponseBeginRecheckTx, error) { + res := app.app.BeginRecheckTx(*req) + return &res, nil +} + +func (app *GRPCApplication) EndRecheckTx(ctx context.Context, req *RequestEndRecheckTx) (*ResponseEndRecheckTx, error) { + res := app.app.EndRecheckTx(*req) return &res, nil } diff --git a/abci/types/messages.go b/abci/types/messages.go index 531f75fed..e617f8593 100644 --- a/abci/types/messages.go +++ b/abci/types/messages.go @@ -135,6 +135,18 @@ func ToRequestEndBlock(req RequestEndBlock) *Request { } } +func ToRequestBeginRecheckTx(req RequestBeginRecheckTx) *Request { + return &Request{ + Value: &Request_BeginRecheckTx{&req}, + } +} + +func ToRequestEndRecheckTx(req RequestEndRecheckTx) *Request { + return &Request{ + Value: &Request_EndRecheckTx{&req}, + } +} + func ToRequestListSnapshots(req RequestListSnapshots) *Request { return &Request{ Value: &Request_ListSnapshots{&req}, @@ -233,6 +245,18 @@ func ToResponseEndBlock(res ResponseEndBlock) *Response { } } +func ToResponseBeginRecheckTx(res ResponseBeginRecheckTx) *Response { + return &Response{ + Value: &Response_BeginRecheckTx{&res}, + } +} + +func ToResponseEndRecheckTx(res ResponseEndRecheckTx) *Response { + return &Response{ + Value: &Response_EndRecheckTx{&res}, + } +} + func ToResponseListSnapshots(res ResponseListSnapshots) *Response { return &Response{ Value: &Response_ListSnapshots{&res}, diff --git a/abci/types/types.pb.go b/abci/types/types.pb.go index d3501f910..8f1ae41d4 100644 --- a/abci/types/types.pb.go +++ b/abci/types/types.pb.go @@ -120,7 +120,7 @@ func (x ResponseOfferSnapshot_Result) String() string { } func (ResponseOfferSnapshot_Result) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_addf585b2317eb36, []int{30, 0} + return fileDescriptor_addf585b2317eb36, []int{32, 0} } type ResponseApplySnapshotChunk_Result int32 @@ -157,7 +157,7 @@ func (x ResponseApplySnapshotChunk_Result) String() string { } func (ResponseApplySnapshotChunk_Result) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_addf585b2317eb36, []int{32, 0} + return fileDescriptor_addf585b2317eb36, []int{34, 0} } type Request struct { @@ -177,6 +177,8 @@ type Request struct { // *Request_OfferSnapshot // *Request_LoadSnapshotChunk // *Request_ApplySnapshotChunk + // *Request_BeginRecheckTx + // *Request_EndRecheckTx Value isRequest_Value `protobuf_oneof:"value"` } @@ -264,6 +266,12 @@ type Request_LoadSnapshotChunk struct { type Request_ApplySnapshotChunk struct { ApplySnapshotChunk *RequestApplySnapshotChunk `protobuf:"bytes,15,opt,name=apply_snapshot_chunk,json=applySnapshotChunk,proto3,oneof" json:"apply_snapshot_chunk,omitempty"` } +type Request_BeginRecheckTx struct { + BeginRecheckTx *RequestBeginRecheckTx `protobuf:"bytes,100,opt,name=begin_recheck_tx,json=beginRecheckTx,proto3,oneof" json:"begin_recheck_tx,omitempty"` +} +type Request_EndRecheckTx struct { + EndRecheckTx *RequestEndRecheckTx `protobuf:"bytes,101,opt,name=end_recheck_tx,json=endRecheckTx,proto3,oneof" json:"end_recheck_tx,omitempty"` +} func (*Request_Echo) isRequest_Value() {} func (*Request_Flush) isRequest_Value() {} @@ -280,6 +288,8 @@ func (*Request_ListSnapshots) isRequest_Value() {} func (*Request_OfferSnapshot) isRequest_Value() {} func (*Request_LoadSnapshotChunk) isRequest_Value() {} func (*Request_ApplySnapshotChunk) isRequest_Value() {} +func (*Request_BeginRecheckTx) isRequest_Value() {} +func (*Request_EndRecheckTx) isRequest_Value() {} func (m *Request) GetValue() isRequest_Value { if m != nil { @@ -393,6 +403,20 @@ func (m *Request) GetApplySnapshotChunk() *RequestApplySnapshotChunk { return nil } +func (m *Request) GetBeginRecheckTx() *RequestBeginRecheckTx { + if x, ok := m.GetValue().(*Request_BeginRecheckTx); ok { + return x.BeginRecheckTx + } + return nil +} + +func (m *Request) GetEndRecheckTx() *RequestEndRecheckTx { + if x, ok := m.GetValue().(*Request_EndRecheckTx); ok { + return x.EndRecheckTx + } + return nil +} + // XXX_OneofWrappers is for the internal use of the proto package. func (*Request) XXX_OneofWrappers() []interface{} { return []interface{}{ @@ -411,6 +435,8 @@ func (*Request) XXX_OneofWrappers() []interface{} { (*Request_OfferSnapshot)(nil), (*Request_LoadSnapshotChunk)(nil), (*Request_ApplySnapshotChunk)(nil), + (*Request_BeginRecheckTx)(nil), + (*Request_EndRecheckTx)(nil), } } @@ -1215,6 +1241,94 @@ func (m *RequestApplySnapshotChunk) GetSender() string { return "" } +type RequestBeginRecheckTx struct { + Header types1.Header `protobuf:"bytes,1,opt,name=header,proto3" json:"header"` +} + +func (m *RequestBeginRecheckTx) Reset() { *m = RequestBeginRecheckTx{} } +func (m *RequestBeginRecheckTx) String() string { return proto.CompactTextString(m) } +func (*RequestBeginRecheckTx) ProtoMessage() {} +func (*RequestBeginRecheckTx) Descriptor() ([]byte, []int) { + return fileDescriptor_addf585b2317eb36, []int{16} +} +func (m *RequestBeginRecheckTx) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RequestBeginRecheckTx) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RequestBeginRecheckTx.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 *RequestBeginRecheckTx) XXX_Merge(src proto.Message) { + xxx_messageInfo_RequestBeginRecheckTx.Merge(m, src) +} +func (m *RequestBeginRecheckTx) XXX_Size() int { + return m.Size() +} +func (m *RequestBeginRecheckTx) XXX_DiscardUnknown() { + xxx_messageInfo_RequestBeginRecheckTx.DiscardUnknown(m) +} + +var xxx_messageInfo_RequestBeginRecheckTx proto.InternalMessageInfo + +func (m *RequestBeginRecheckTx) GetHeader() types1.Header { + if m != nil { + return m.Header + } + return types1.Header{} +} + +type RequestEndRecheckTx struct { + Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"` +} + +func (m *RequestEndRecheckTx) Reset() { *m = RequestEndRecheckTx{} } +func (m *RequestEndRecheckTx) String() string { return proto.CompactTextString(m) } +func (*RequestEndRecheckTx) ProtoMessage() {} +func (*RequestEndRecheckTx) Descriptor() ([]byte, []int) { + return fileDescriptor_addf585b2317eb36, []int{17} +} +func (m *RequestEndRecheckTx) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RequestEndRecheckTx) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RequestEndRecheckTx.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 *RequestEndRecheckTx) XXX_Merge(src proto.Message) { + xxx_messageInfo_RequestEndRecheckTx.Merge(m, src) +} +func (m *RequestEndRecheckTx) XXX_Size() int { + return m.Size() +} +func (m *RequestEndRecheckTx) XXX_DiscardUnknown() { + xxx_messageInfo_RequestEndRecheckTx.DiscardUnknown(m) +} + +var xxx_messageInfo_RequestEndRecheckTx proto.InternalMessageInfo + +func (m *RequestEndRecheckTx) GetHeight() int64 { + if m != nil { + return m.Height + } + return 0 +} + type Response struct { // Types that are valid to be assigned to Value: // *Response_Exception @@ -1233,6 +1347,8 @@ type Response struct { // *Response_OfferSnapshot // *Response_LoadSnapshotChunk // *Response_ApplySnapshotChunk + // *Response_BeginRecheckTx + // *Response_EndRecheckTx Value isResponse_Value `protobuf_oneof:"value"` } @@ -1240,7 +1356,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_addf585b2317eb36, []int{16} + return fileDescriptor_addf585b2317eb36, []int{18} } func (m *Response) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1323,6 +1439,12 @@ type Response_LoadSnapshotChunk struct { type Response_ApplySnapshotChunk struct { ApplySnapshotChunk *ResponseApplySnapshotChunk `protobuf:"bytes,16,opt,name=apply_snapshot_chunk,json=applySnapshotChunk,proto3,oneof" json:"apply_snapshot_chunk,omitempty"` } +type Response_BeginRecheckTx struct { + BeginRecheckTx *ResponseBeginRecheckTx `protobuf:"bytes,100,opt,name=begin_recheck_tx,json=beginRecheckTx,proto3,oneof" json:"begin_recheck_tx,omitempty"` +} +type Response_EndRecheckTx struct { + EndRecheckTx *ResponseEndRecheckTx `protobuf:"bytes,101,opt,name=end_recheck_tx,json=endRecheckTx,proto3,oneof" json:"end_recheck_tx,omitempty"` +} func (*Response_Exception) isResponse_Value() {} func (*Response_Echo) isResponse_Value() {} @@ -1340,6 +1462,8 @@ func (*Response_ListSnapshots) isResponse_Value() {} func (*Response_OfferSnapshot) isResponse_Value() {} func (*Response_LoadSnapshotChunk) isResponse_Value() {} func (*Response_ApplySnapshotChunk) isResponse_Value() {} +func (*Response_BeginRecheckTx) isResponse_Value() {} +func (*Response_EndRecheckTx) isResponse_Value() {} func (m *Response) GetValue() isResponse_Value { if m != nil { @@ -1460,6 +1584,20 @@ func (m *Response) GetApplySnapshotChunk() *ResponseApplySnapshotChunk { return nil } +func (m *Response) GetBeginRecheckTx() *ResponseBeginRecheckTx { + if x, ok := m.GetValue().(*Response_BeginRecheckTx); ok { + return x.BeginRecheckTx + } + return nil +} + +func (m *Response) GetEndRecheckTx() *ResponseEndRecheckTx { + if x, ok := m.GetValue().(*Response_EndRecheckTx); ok { + return x.EndRecheckTx + } + return nil +} + // XXX_OneofWrappers is for the internal use of the proto package. func (*Response) XXX_OneofWrappers() []interface{} { return []interface{}{ @@ -1479,6 +1617,8 @@ func (*Response) XXX_OneofWrappers() []interface{} { (*Response_OfferSnapshot)(nil), (*Response_LoadSnapshotChunk)(nil), (*Response_ApplySnapshotChunk)(nil), + (*Response_BeginRecheckTx)(nil), + (*Response_EndRecheckTx)(nil), } } @@ -1491,7 +1631,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_addf585b2317eb36, []int{17} + return fileDescriptor_addf585b2317eb36, []int{19} } func (m *ResponseException) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1535,7 +1675,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_addf585b2317eb36, []int{18} + return fileDescriptor_addf585b2317eb36, []int{20} } func (m *ResponseEcho) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1578,7 +1718,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_addf585b2317eb36, []int{19} + return fileDescriptor_addf585b2317eb36, []int{21} } func (m *ResponseFlush) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1619,7 +1759,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_addf585b2317eb36, []int{20} + return fileDescriptor_addf585b2317eb36, []int{22} } func (m *ResponseInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1695,7 +1835,7 @@ func (m *ResponseSetOption) Reset() { *m = ResponseSetOption{} } func (m *ResponseSetOption) String() string { return proto.CompactTextString(m) } func (*ResponseSetOption) ProtoMessage() {} func (*ResponseSetOption) Descriptor() ([]byte, []int) { - return fileDescriptor_addf585b2317eb36, []int{21} + return fileDescriptor_addf585b2317eb36, []int{23} } func (m *ResponseSetOption) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1755,7 +1895,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_addf585b2317eb36, []int{22} + return fileDescriptor_addf585b2317eb36, []int{24} } func (m *ResponseInitChain) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1822,7 +1962,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_addf585b2317eb36, []int{23} + return fileDescriptor_addf585b2317eb36, []int{25} } func (m *ResponseQuery) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1922,7 +2062,7 @@ 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_addf585b2317eb36, []int{24} + return fileDescriptor_addf585b2317eb36, []int{26} } func (m *ResponseBeginBlock) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1973,7 +2113,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_addf585b2317eb36, []int{25} + return fileDescriptor_addf585b2317eb36, []int{27} } func (m *ResponseCheckTx) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2073,7 +2213,7 @@ 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_addf585b2317eb36, []int{26} + return fileDescriptor_addf585b2317eb36, []int{28} } func (m *ResponseDeliverTx) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2168,7 +2308,7 @@ 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_addf585b2317eb36, []int{27} + return fileDescriptor_addf585b2317eb36, []int{29} } func (m *ResponseEndBlock) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2228,7 +2368,7 @@ 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_addf585b2317eb36, []int{28} + return fileDescriptor_addf585b2317eb36, []int{30} } func (m *ResponseCommit) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2279,7 +2419,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_addf585b2317eb36, []int{29} + return fileDescriptor_addf585b2317eb36, []int{31} } func (m *ResponseListSnapshots) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2323,7 +2463,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_addf585b2317eb36, []int{30} + return fileDescriptor_addf585b2317eb36, []int{32} } func (m *ResponseOfferSnapshot) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2367,7 +2507,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_addf585b2317eb36, []int{31} + return fileDescriptor_addf585b2317eb36, []int{33} } func (m *ResponseLoadSnapshotChunk) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2413,7 +2553,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_addf585b2317eb36, []int{32} + return fileDescriptor_addf585b2317eb36, []int{34} } func (m *ResponseApplySnapshotChunk) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2463,6 +2603,94 @@ func (m *ResponseApplySnapshotChunk) GetRejectSenders() []string { return nil } +type ResponseBeginRecheckTx struct { + Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` +} + +func (m *ResponseBeginRecheckTx) Reset() { *m = ResponseBeginRecheckTx{} } +func (m *ResponseBeginRecheckTx) String() string { return proto.CompactTextString(m) } +func (*ResponseBeginRecheckTx) ProtoMessage() {} +func (*ResponseBeginRecheckTx) Descriptor() ([]byte, []int) { + return fileDescriptor_addf585b2317eb36, []int{35} +} +func (m *ResponseBeginRecheckTx) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResponseBeginRecheckTx) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ResponseBeginRecheckTx.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 *ResponseBeginRecheckTx) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResponseBeginRecheckTx.Merge(m, src) +} +func (m *ResponseBeginRecheckTx) XXX_Size() int { + return m.Size() +} +func (m *ResponseBeginRecheckTx) XXX_DiscardUnknown() { + xxx_messageInfo_ResponseBeginRecheckTx.DiscardUnknown(m) +} + +var xxx_messageInfo_ResponseBeginRecheckTx proto.InternalMessageInfo + +func (m *ResponseBeginRecheckTx) GetCode() uint32 { + if m != nil { + return m.Code + } + return 0 +} + +type ResponseEndRecheckTx struct { + Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` +} + +func (m *ResponseEndRecheckTx) Reset() { *m = ResponseEndRecheckTx{} } +func (m *ResponseEndRecheckTx) String() string { return proto.CompactTextString(m) } +func (*ResponseEndRecheckTx) ProtoMessage() {} +func (*ResponseEndRecheckTx) Descriptor() ([]byte, []int) { + return fileDescriptor_addf585b2317eb36, []int{36} +} +func (m *ResponseEndRecheckTx) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResponseEndRecheckTx) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ResponseEndRecheckTx.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 *ResponseEndRecheckTx) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResponseEndRecheckTx.Merge(m, src) +} +func (m *ResponseEndRecheckTx) XXX_Size() int { + return m.Size() +} +func (m *ResponseEndRecheckTx) XXX_DiscardUnknown() { + xxx_messageInfo_ResponseEndRecheckTx.DiscardUnknown(m) +} + +var xxx_messageInfo_ResponseEndRecheckTx proto.InternalMessageInfo + +func (m *ResponseEndRecheckTx) GetCode() uint32 { + if m != nil { + return m.Code + } + return 0 +} + // ConsensusParams contains all consensus-relevant parameters // that can be adjusted by the abci app type ConsensusParams struct { @@ -2476,7 +2704,7 @@ func (m *ConsensusParams) Reset() { *m = ConsensusParams{} } func (m *ConsensusParams) String() string { return proto.CompactTextString(m) } func (*ConsensusParams) ProtoMessage() {} func (*ConsensusParams) Descriptor() ([]byte, []int) { - return fileDescriptor_addf585b2317eb36, []int{33} + return fileDescriptor_addf585b2317eb36, []int{37} } func (m *ConsensusParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2545,7 +2773,7 @@ func (m *BlockParams) Reset() { *m = BlockParams{} } func (m *BlockParams) String() string { return proto.CompactTextString(m) } func (*BlockParams) ProtoMessage() {} func (*BlockParams) Descriptor() ([]byte, []int) { - return fileDescriptor_addf585b2317eb36, []int{34} + return fileDescriptor_addf585b2317eb36, []int{38} } func (m *BlockParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2597,7 +2825,7 @@ func (m *LastCommitInfo) Reset() { *m = LastCommitInfo{} } func (m *LastCommitInfo) String() string { return proto.CompactTextString(m) } func (*LastCommitInfo) ProtoMessage() {} func (*LastCommitInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_addf585b2317eb36, []int{35} + return fileDescriptor_addf585b2317eb36, []int{39} } func (m *LastCommitInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2652,7 +2880,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_addf585b2317eb36, []int{36} + return fileDescriptor_addf585b2317eb36, []int{40} } func (m *Event) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2706,7 +2934,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_addf585b2317eb36, []int{37} + return fileDescriptor_addf585b2317eb36, []int{41} } func (m *EventAttribute) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2770,7 +2998,7 @@ 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_addf585b2317eb36, []int{38} + return fileDescriptor_addf585b2317eb36, []int{42} } func (m *TxResult) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2838,7 +3066,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_addf585b2317eb36, []int{39} + return fileDescriptor_addf585b2317eb36, []int{43} } func (m *Validator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2891,7 +3119,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_addf585b2317eb36, []int{40} + return fileDescriptor_addf585b2317eb36, []int{44} } func (m *ValidatorUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2946,7 +3174,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_addf585b2317eb36, []int{41} + return fileDescriptor_addf585b2317eb36, []int{45} } func (m *VoteInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3014,7 +3242,7 @@ func (m *Evidence) Reset() { *m = Evidence{} } func (m *Evidence) String() string { return proto.CompactTextString(m) } func (*Evidence) ProtoMessage() {} func (*Evidence) Descriptor() ([]byte, []int) { - return fileDescriptor_addf585b2317eb36, []int{42} + return fileDescriptor_addf585b2317eb36, []int{46} } func (m *Evidence) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3090,7 +3318,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_addf585b2317eb36, []int{43} + return fileDescriptor_addf585b2317eb36, []int{47} } func (m *Snapshot) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3175,6 +3403,8 @@ func init() { proto.RegisterType((*RequestOfferSnapshot)(nil), "ostracon.abci.RequestOfferSnapshot") proto.RegisterType((*RequestLoadSnapshotChunk)(nil), "ostracon.abci.RequestLoadSnapshotChunk") proto.RegisterType((*RequestApplySnapshotChunk)(nil), "ostracon.abci.RequestApplySnapshotChunk") + proto.RegisterType((*RequestBeginRecheckTx)(nil), "ostracon.abci.RequestBeginRecheckTx") + proto.RegisterType((*RequestEndRecheckTx)(nil), "ostracon.abci.RequestEndRecheckTx") proto.RegisterType((*Response)(nil), "ostracon.abci.Response") proto.RegisterType((*ResponseException)(nil), "ostracon.abci.ResponseException") proto.RegisterType((*ResponseEcho)(nil), "ostracon.abci.ResponseEcho") @@ -3192,6 +3422,8 @@ func init() { proto.RegisterType((*ResponseOfferSnapshot)(nil), "ostracon.abci.ResponseOfferSnapshot") proto.RegisterType((*ResponseLoadSnapshotChunk)(nil), "ostracon.abci.ResponseLoadSnapshotChunk") proto.RegisterType((*ResponseApplySnapshotChunk)(nil), "ostracon.abci.ResponseApplySnapshotChunk") + proto.RegisterType((*ResponseBeginRecheckTx)(nil), "ostracon.abci.ResponseBeginRecheckTx") + proto.RegisterType((*ResponseEndRecheckTx)(nil), "ostracon.abci.ResponseEndRecheckTx") proto.RegisterType((*ConsensusParams)(nil), "ostracon.abci.ConsensusParams") proto.RegisterType((*BlockParams)(nil), "ostracon.abci.BlockParams") proto.RegisterType((*LastCommitInfo)(nil), "ostracon.abci.LastCommitInfo") @@ -3208,180 +3440,188 @@ func init() { func init() { proto.RegisterFile("ostracon/abci/types.proto", fileDescriptor_addf585b2317eb36) } var fileDescriptor_addf585b2317eb36 = []byte{ - // 2759 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x5a, 0xcd, 0x93, 0x1b, 0x47, - 0x15, 0xd7, 0xe8, 0x5b, 0x4f, 0x2b, 0xad, 0xb6, 0xbd, 0xb1, 0xe5, 0x71, 0xb2, 0x6b, 0xc6, 0x84, - 0x24, 0x26, 0xec, 0xc6, 0x1f, 0x24, 0xc4, 0xc1, 0x21, 0x92, 0x2c, 0x47, 0xcb, 0xae, 0x77, 0xd7, - 0xb3, 0xf2, 0xa6, 0xe2, 0x04, 0x26, 0x23, 0xa9, 0x57, 0x1a, 0x2c, 0xcd, 0x4c, 0x34, 0xad, 0xf5, - 0x2e, 0x37, 0xa0, 0xa8, 0xa2, 0x72, 0xca, 0x89, 0xe2, 0x92, 0xff, 0x83, 0x03, 0x55, 0x9c, 0xa8, - 0xe4, 0x98, 0x23, 0xa7, 0x40, 0xd9, 0x17, 0x8a, 0x2b, 0x45, 0x51, 0x5c, 0x28, 0xaa, 0x3f, 0xe6, - 0x73, 0x35, 0x92, 0x9c, 0x70, 0xe3, 0x36, 0xfd, 0xe6, 0xbd, 0x37, 0xdd, 0xad, 0x7e, 0xbf, 0xf7, - 0x7b, 0xaf, 0x05, 0x17, 0x2d, 0x87, 0x8c, 0xf5, 0xae, 0x65, 0x6e, 0xea, 0x9d, 0xae, 0xb1, 0x49, - 0x4e, 0x6d, 0xec, 0x6c, 0xd8, 0x63, 0x8b, 0x58, 0xa8, 0xe4, 0xbe, 0xda, 0xa0, 0xaf, 0xe4, 0x4b, - 0x9e, 0x66, 0x77, 0x7c, 0x6a, 0x13, 0x6b, 0xd3, 0x1e, 0x5b, 0xd6, 0x11, 0xd7, 0x95, 0x65, 0xef, - 0x25, 0xf3, 0x10, 0xf4, 0x13, 0x78, 0x27, 0x0c, 0x1f, 0xe1, 0x53, 0xf7, 0xdd, 0xa5, 0x88, 0x9d, - 0xad, 0x8f, 0xf5, 0x91, 0xfb, 0x72, 0xbd, 0x6f, 0x59, 0xfd, 0x21, 0xde, 0x64, 0xa3, 0xce, 0xe4, - 0x68, 0x93, 0x18, 0x23, 0xec, 0x10, 0x7d, 0x64, 0x0b, 0x85, 0xd5, 0xbe, 0xd5, 0xb7, 0xd8, 0xe3, - 0x26, 0x7d, 0xe2, 0x52, 0xe5, 0x1f, 0x39, 0xc8, 0xa9, 0xf8, 0xe3, 0x09, 0x76, 0x08, 0x7a, 0x0d, - 0xd2, 0xb8, 0x3b, 0xb0, 0xaa, 0xd2, 0x65, 0xe9, 0xe5, 0xe2, 0x75, 0x79, 0x23, 0xb4, 0xa4, 0x0d, - 0xa1, 0xd5, 0xec, 0x0e, 0xac, 0x56, 0x42, 0x65, 0x9a, 0xe8, 0x06, 0x64, 0x8e, 0x86, 0x13, 0x67, - 0x50, 0x4d, 0x32, 0x93, 0x4b, 0xd3, 0x4d, 0xee, 0x52, 0x95, 0x56, 0x42, 0xe5, 0xba, 0xf4, 0x33, - 0x86, 0x79, 0x64, 0x55, 0x53, 0xb3, 0x3e, 0xb3, 0x65, 0x1e, 0xb1, 0xcf, 0x50, 0x4d, 0xf4, 0x0e, - 0x80, 0x83, 0x89, 0x66, 0xd9, 0xc4, 0xb0, 0xcc, 0x6a, 0x9a, 0xd9, 0xad, 0x4f, 0xb7, 0x3b, 0xc0, - 0x64, 0x8f, 0xa9, 0xb5, 0x12, 0x6a, 0xc1, 0x71, 0x07, 0xd4, 0x83, 0x61, 0x1a, 0x44, 0xeb, 0x0e, - 0x74, 0xc3, 0xac, 0x66, 0x66, 0x79, 0xd8, 0x32, 0x0d, 0xd2, 0xa0, 0x6a, 0xd4, 0x83, 0xe1, 0x0e, - 0xe8, 0x52, 0x3f, 0x9e, 0xe0, 0xf1, 0x69, 0x35, 0x3b, 0x6b, 0xa9, 0xf7, 0xa9, 0x0a, 0x5d, 0x2a, - 0xd3, 0x45, 0x0d, 0x28, 0x76, 0x70, 0xdf, 0x30, 0xb5, 0xce, 0xd0, 0xea, 0x3e, 0xaa, 0xe6, 0x98, - 0xe9, 0xe5, 0xe9, 0xa6, 0x75, 0xaa, 0x58, 0xa7, 0x7a, 0xad, 0x84, 0x0a, 0x1d, 0x6f, 0x84, 0x6e, - 0x41, 0xbe, 0x3b, 0xc0, 0xdd, 0x47, 0x1a, 0x39, 0xa9, 0xe6, 0x99, 0x87, 0x17, 0xa6, 0x7b, 0x68, - 0x50, 0xad, 0xf6, 0x49, 0x2b, 0xa1, 0xe6, 0xba, 0xfc, 0x91, 0xae, 0xbb, 0x87, 0x87, 0xc6, 0x31, - 0x1e, 0x53, 0xeb, 0xc2, 0xac, 0x75, 0xdf, 0xe1, 0x7a, 0xcc, 0xbe, 0xd0, 0x73, 0x07, 0xe8, 0x36, - 0x14, 0xb0, 0xd9, 0x13, 0x0b, 0x00, 0xe6, 0x60, 0x2d, 0xe6, 0x64, 0x98, 0x3d, 0x77, 0xfa, 0x79, - 0x2c, 0x9e, 0xd1, 0xeb, 0x90, 0xed, 0x5a, 0xa3, 0x91, 0x41, 0xaa, 0x45, 0x66, 0xfb, 0x7c, 0xcc, - 0xd4, 0x99, 0x4e, 0x2b, 0xa1, 0x0a, 0x6d, 0xb4, 0x03, 0xe5, 0xa1, 0xe1, 0x10, 0xcd, 0x31, 0x75, - 0xdb, 0x19, 0x58, 0xc4, 0xa9, 0x2e, 0x31, 0xfb, 0x2b, 0xd3, 0xed, 0x77, 0x0c, 0x87, 0x1c, 0xb8, - 0xaa, 0xad, 0x84, 0x5a, 0x1a, 0x06, 0x05, 0xd4, 0x9b, 0x75, 0x74, 0x84, 0xc7, 0x9e, 0xbb, 0x6a, - 0x69, 0x96, 0xb7, 0x3d, 0xaa, 0xeb, 0x5a, 0x53, 0x6f, 0x56, 0x50, 0x80, 0xde, 0x87, 0x73, 0x43, - 0x4b, 0xef, 0x79, 0xce, 0xb4, 0xee, 0x60, 0x62, 0x3e, 0xaa, 0x96, 0x99, 0xcb, 0x97, 0x62, 0x26, - 0x68, 0xe9, 0x3d, 0xd7, 0x41, 0x83, 0xaa, 0xb7, 0x12, 0xea, 0xca, 0x30, 0x2a, 0x44, 0x1f, 0xc2, - 0xaa, 0x6e, 0xdb, 0xc3, 0xd3, 0xa8, 0xef, 0x65, 0xe6, 0xfb, 0xe5, 0xe9, 0xbe, 0x6b, 0xd4, 0x22, - 0xea, 0x1c, 0xe9, 0x67, 0xa4, 0xf5, 0x1c, 0x64, 0x8e, 0xf5, 0xe1, 0x04, 0x2b, 0x2f, 0x41, 0x31, - 0x10, 0xce, 0xa8, 0x0a, 0xb9, 0x11, 0x76, 0x1c, 0xbd, 0x8f, 0x59, 0xec, 0x17, 0x54, 0x77, 0xa8, - 0x94, 0x61, 0x29, 0x18, 0xc4, 0xca, 0xc8, 0x33, 0xa4, 0x01, 0x4a, 0x0d, 0x8f, 0xf1, 0xd8, 0xa1, - 0x51, 0x29, 0x0c, 0xc5, 0x10, 0x5d, 0x81, 0x12, 0x3b, 0x32, 0x9a, 0xfb, 0x9e, 0x22, 0x44, 0x5a, - 0x5d, 0x62, 0xc2, 0x43, 0xa1, 0xb4, 0x0e, 0x45, 0xfb, 0xba, 0xed, 0xa9, 0xa4, 0x98, 0x0a, 0xd8, - 0xd7, 0x6d, 0xa1, 0xa0, 0xdc, 0x82, 0x4a, 0x34, 0xae, 0x51, 0x05, 0x52, 0x8f, 0xf0, 0xa9, 0xf8, - 0x1e, 0x7d, 0x44, 0xab, 0x62, 0x59, 0xec, 0x1b, 0x05, 0x55, 0xac, 0xf1, 0xf3, 0xa4, 0x67, 0xec, - 0x85, 0x34, 0xfa, 0x01, 0xa4, 0x29, 0x2e, 0x7a, 0x10, 0xc7, 0x41, 0x73, 0xc3, 0x05, 0xcd, 0x8d, - 0xb6, 0x0b, 0x9a, 0xf5, 0xfc, 0x17, 0x5f, 0xad, 0x27, 0x3e, 0xfd, 0xcb, 0xba, 0xa4, 0x32, 0x0b, - 0x74, 0x91, 0x46, 0xa1, 0x6e, 0x98, 0x9a, 0xd1, 0x13, 0xdf, 0xc9, 0xb1, 0xf1, 0x56, 0x0f, 0x6d, - 0x41, 0xa5, 0x6b, 0x99, 0x0e, 0x36, 0x9d, 0x89, 0xa3, 0x71, 0x50, 0x16, 0xe0, 0x16, 0x8d, 0x94, - 0x86, 0xab, 0xb6, 0xcf, 0xb4, 0xd4, 0xe5, 0x6e, 0x58, 0x80, 0xee, 0x00, 0x1c, 0xeb, 0x43, 0xa3, - 0xa7, 0x13, 0x6b, 0xec, 0x54, 0xd3, 0x97, 0x53, 0x53, 0x9c, 0x1c, 0xba, 0x0a, 0x0f, 0xec, 0x9e, - 0x4e, 0x70, 0x3d, 0x4d, 0x67, 0xaa, 0x06, 0xec, 0xd0, 0x77, 0x60, 0x59, 0xb7, 0x6d, 0xcd, 0x21, - 0x3a, 0xc1, 0x5a, 0xe7, 0x94, 0x60, 0x87, 0x41, 0xde, 0x92, 0x5a, 0xd2, 0x6d, 0xfb, 0x80, 0x4a, - 0xeb, 0x54, 0x88, 0x5e, 0x84, 0x32, 0x05, 0x38, 0x43, 0x1f, 0x6a, 0x03, 0x6c, 0xf4, 0x07, 0x84, - 0x81, 0x5b, 0x4a, 0x2d, 0x09, 0x69, 0x8b, 0x09, 0x95, 0x9e, 0x77, 0x08, 0x18, 0xbc, 0x21, 0x04, - 0xe9, 0x9e, 0x4e, 0x74, 0xb6, 0x89, 0x4b, 0x2a, 0x7b, 0xa6, 0x32, 0x5b, 0x27, 0x03, 0xb1, 0x35, - 0xec, 0x19, 0x9d, 0x87, 0xac, 0x70, 0x9b, 0x62, 0x6e, 0xc5, 0x88, 0xfe, 0x5e, 0xf6, 0xd8, 0x3a, - 0xc6, 0x0c, 0xc9, 0xf3, 0x2a, 0x1f, 0x28, 0xff, 0x91, 0x60, 0xe5, 0x0c, 0x14, 0x52, 0xbf, 0x03, - 0xdd, 0x19, 0xb8, 0xdf, 0xa2, 0xcf, 0xe8, 0x26, 0xf5, 0xab, 0xf7, 0xf0, 0x58, 0xa4, 0x9d, 0xf3, - 0xfe, 0x06, 0xf1, 0x54, 0xda, 0x62, 0x6f, 0xc5, 0xc6, 0x08, 0x5d, 0x74, 0x0f, 0x2a, 0x43, 0xdd, - 0x21, 0x1a, 0x07, 0x18, 0x2d, 0x90, 0x82, 0xa2, 0x70, 0xba, 0xa3, 0xbb, 0x80, 0x44, 0x0f, 0xb9, - 0x70, 0x53, 0x1e, 0x86, 0xa4, 0x68, 0x1f, 0x56, 0x3b, 0xa7, 0x3f, 0xd7, 0x4d, 0x62, 0x98, 0x58, - 0x3b, 0xf3, 0x9b, 0x5d, 0x88, 0xb8, 0x6c, 0x1e, 0x1b, 0x3d, 0x6c, 0x76, 0xdd, 0x1f, 0xeb, 0x9c, - 0x67, 0xea, 0xfd, 0x98, 0x8e, 0xb2, 0x0f, 0xe5, 0x30, 0x90, 0xa3, 0x32, 0x24, 0xc9, 0x89, 0x58, - 0x7a, 0x92, 0x9c, 0xa0, 0x0d, 0x48, 0xd3, 0x05, 0xb2, 0x65, 0x97, 0xcf, 0x64, 0x4e, 0x61, 0xd5, - 0x3e, 0xb5, 0xb1, 0xca, 0xf4, 0x14, 0xc5, 0x8b, 0x00, 0x0f, 0xdc, 0xa3, 0x3e, 0x95, 0x57, 0x60, - 0x39, 0x82, 0xdf, 0x81, 0xdf, 0x4d, 0x0a, 0xfe, 0x6e, 0xca, 0x32, 0x94, 0x42, 0x70, 0xad, 0x9c, - 0x87, 0xd5, 0x69, 0xf8, 0xab, 0x1c, 0x79, 0xf2, 0x10, 0x92, 0xa2, 0x1b, 0x90, 0xf7, 0x00, 0x98, - 0x47, 0x60, 0x74, 0x9f, 0x5c, 0x55, 0xd5, 0x53, 0xa4, 0x81, 0x47, 0x0f, 0x33, 0x3b, 0x05, 0x49, - 0x36, 0xed, 0x9c, 0x6e, 0xdb, 0x2d, 0xdd, 0x19, 0x28, 0x1f, 0x41, 0x35, 0x0e, 0x5e, 0x23, 0x8b, - 0x48, 0x7b, 0x87, 0xef, 0x3c, 0x64, 0x8f, 0xac, 0xf1, 0x48, 0x27, 0xcc, 0x59, 0x49, 0x15, 0x23, - 0x7a, 0x28, 0x39, 0xd4, 0xa6, 0x98, 0x98, 0x0f, 0x14, 0x0d, 0x2e, 0xc6, 0x82, 0x2c, 0x35, 0x31, - 0xcc, 0x1e, 0xe6, 0xbb, 0x59, 0x52, 0xf9, 0xc0, 0x77, 0xc4, 0x27, 0xcb, 0x07, 0xf4, 0xb3, 0x0e, - 0x36, 0xe9, 0x99, 0x4d, 0xb1, 0x08, 0x11, 0x23, 0xe5, 0x4f, 0x79, 0xc8, 0xab, 0xd8, 0xb1, 0x29, - 0x0e, 0xa0, 0x77, 0xa0, 0x80, 0x4f, 0xba, 0x98, 0xd3, 0x1c, 0x29, 0x86, 0x2c, 0x70, 0xdd, 0xa6, - 0xab, 0x47, 0xb3, 0xb5, 0x67, 0x84, 0xae, 0x09, 0x0a, 0x17, 0xc7, 0xc7, 0x84, 0x71, 0x90, 0xc3, - 0xdd, 0x74, 0x39, 0x5c, 0x2a, 0x26, 0x41, 0x73, 0x9b, 0x08, 0x89, 0xbb, 0x26, 0x48, 0x5c, 0x7a, - 0xe6, 0x87, 0x42, 0x2c, 0xae, 0x16, 0x62, 0x71, 0x99, 0x99, 0xcb, 0x8b, 0xa1, 0x71, 0xb5, 0x10, - 0x8d, 0xcb, 0xce, 0x74, 0x11, 0xc3, 0xe3, 0x6e, 0xba, 0x3c, 0x2e, 0x37, 0x73, 0xb9, 0x11, 0x22, - 0x77, 0x27, 0x4c, 0xe4, 0x38, 0x0d, 0xfb, 0x56, 0x8c, 0x6d, 0x2c, 0x93, 0x7b, 0x2b, 0xc0, 0xe4, - 0x0a, 0x31, 0x54, 0x8a, 0xbb, 0x98, 0x42, 0xe5, 0x6a, 0x21, 0x2a, 0x07, 0x33, 0xd7, 0x1e, 0xc3, - 0xe5, 0xde, 0x0e, 0x72, 0xb9, 0x62, 0x0c, 0x19, 0x14, 0x47, 0x64, 0x1a, 0x99, 0x7b, 0xc3, 0x23, - 0x73, 0x4b, 0x31, 0x3c, 0x54, 0xcc, 0x3e, 0xca, 0xe6, 0xee, 0x9d, 0x61, 0x73, 0x9c, 0x7f, 0x7d, - 0x3b, 0xc6, 0xc1, 0x1c, 0x3a, 0x77, 0xef, 0x0c, 0x9d, 0x2b, 0xcf, 0x74, 0x37, 0x87, 0xcf, 0x3d, - 0x9c, 0xce, 0xe7, 0xe2, 0x38, 0x97, 0x98, 0xe2, 0x62, 0x84, 0xee, 0x27, 0x31, 0x84, 0xae, 0xc2, - 0x9c, 0xbf, 0x12, 0xe3, 0xfc, 0xd9, 0x19, 0xdd, 0x2b, 0x34, 0x79, 0x46, 0xa0, 0x81, 0x42, 0x11, - 0x1e, 0x8f, 0xad, 0xb1, 0x20, 0x4b, 0x7c, 0xa0, 0xbc, 0x4c, 0xd3, 0xb9, 0x0f, 0x04, 0x33, 0xd8, - 0x1f, 0x03, 0xfc, 0x40, 0xf8, 0x2b, 0xbf, 0x97, 0x7c, 0x5b, 0x96, 0x05, 0x83, 0x54, 0xa0, 0x20, - 0xa8, 0x40, 0x80, 0x14, 0x26, 0xc3, 0xa4, 0x70, 0x1d, 0x8a, 0x14, 0xca, 0x23, 0x7c, 0x4f, 0xb7, - 0x5d, 0xbe, 0x87, 0xae, 0xc2, 0x0a, 0xcb, 0xd1, 0x9c, 0x3a, 0x0a, 0xfc, 0x4e, 0xb3, 0x24, 0xb4, - 0x4c, 0x5f, 0xf0, 0x23, 0xc9, 0x81, 0xfc, 0x7b, 0x70, 0x2e, 0xa0, 0xeb, 0xa5, 0x08, 0x4e, 0x74, - 0x2a, 0x9e, 0x76, 0x4d, 0xe4, 0x8a, 0x7b, 0xfe, 0x06, 0xf9, 0x5c, 0x12, 0x41, 0xba, 0x6b, 0xf5, - 0xb0, 0x00, 0x70, 0xf6, 0x4c, 0xf9, 0xe5, 0xd0, 0xea, 0x0b, 0x98, 0xa6, 0x8f, 0x54, 0xcb, 0xc3, - 0xba, 0x02, 0x07, 0x33, 0xe5, 0x8f, 0x92, 0xef, 0xcf, 0xa7, 0x97, 0xd3, 0x98, 0xa0, 0xf4, 0xbf, - 0x60, 0x82, 0xc9, 0xaf, 0xc9, 0x04, 0x83, 0xc9, 0x33, 0x15, 0x4e, 0x9e, 0xff, 0x94, 0xfc, 0x5f, - 0xd7, 0xe3, 0x75, 0x5f, 0x6f, 0x37, 0xfc, 0x4c, 0x98, 0x61, 0xbf, 0x95, 0xc8, 0x84, 0x82, 0xa9, - 0x67, 0xd9, 0x77, 0xc3, 0x4c, 0x3d, 0xc7, 0x73, 0x23, 0x1b, 0xa0, 0xd7, 0xa1, 0xc0, 0xda, 0x23, - 0x9a, 0x65, 0x3b, 0x02, 0x5a, 0x2f, 0xfa, 0x2b, 0xe5, 0x7d, 0x90, 0x8d, 0x7d, 0xaa, 0xb1, 0x67, - 0x3b, 0x6a, 0xde, 0x16, 0x4f, 0x81, 0x14, 0x5f, 0x08, 0xf1, 0xcb, 0xe7, 0xa1, 0x40, 0xe7, 0xee, - 0xd8, 0x7a, 0x17, 0x33, 0xa0, 0x2c, 0xa8, 0xbe, 0x40, 0xf9, 0x10, 0xd0, 0x59, 0xa0, 0x46, 0x77, - 0x21, 0x8b, 0x8f, 0xb1, 0x49, 0xe8, 0xef, 0x45, 0xb7, 0x7a, 0xf5, 0x0c, 0x81, 0xc3, 0x26, 0xa9, - 0x57, 0xe9, 0x06, 0xff, 0xfd, 0xab, 0xf5, 0x0a, 0xd7, 0x7d, 0xd5, 0x1a, 0x19, 0x04, 0x8f, 0x6c, - 0x72, 0xaa, 0x0a, 0x6b, 0xe5, 0x17, 0x49, 0xca, 0xa7, 0x42, 0x20, 0x3e, 0x75, 0x5f, 0xdd, 0xc0, - 0x49, 0x06, 0x38, 0xf4, 0x62, 0x7b, 0xbd, 0x06, 0xd0, 0xd7, 0x1d, 0xed, 0xb1, 0x6e, 0x12, 0xdc, - 0x13, 0x1b, 0x1e, 0x90, 0x20, 0x19, 0xf2, 0x74, 0x34, 0x71, 0x70, 0x4f, 0xd0, 0x79, 0x6f, 0x1c, - 0x58, 0x65, 0xee, 0x9b, 0xac, 0x32, 0xbc, 0xc3, 0xf9, 0xe8, 0x0e, 0xff, 0x2a, 0xe9, 0xc7, 0x86, - 0x4f, 0x3c, 0xff, 0xdf, 0x76, 0xe1, 0xd7, 0xac, 0xfe, 0x0c, 0x67, 0x53, 0x74, 0x1f, 0x56, 0xbc, - 0xe8, 0xd4, 0x26, 0x2c, 0x6a, 0xdd, 0x13, 0xb7, 0x58, 0x70, 0x57, 0x8e, 0xc3, 0x62, 0x07, 0x1d, - 0xc2, 0x85, 0x08, 0xe6, 0x78, 0x8e, 0x93, 0x0b, 0x41, 0xcf, 0x73, 0x61, 0xe8, 0x71, 0xfd, 0xfa, - 0xbb, 0x94, 0xfa, 0x46, 0x11, 0xb1, 0x45, 0xcb, 0x9a, 0x20, 0x2f, 0x98, 0xfa, 0xab, 0x5f, 0x81, - 0xd2, 0x18, 0x13, 0x5a, 0x5f, 0x87, 0x4a, 0xc6, 0x25, 0x2e, 0x14, 0x85, 0xe8, 0x2e, 0x3c, 0x37, - 0x95, 0x21, 0xa0, 0xef, 0x43, 0xc1, 0xa7, 0x16, 0xd2, 0xd4, 0x0a, 0xcc, 0xab, 0x2c, 0x7c, 0x4d, - 0xe5, 0x0f, 0x92, 0xef, 0x30, 0x5c, 0xa9, 0x34, 0x20, 0x3b, 0xc6, 0xce, 0x64, 0xc8, 0xab, 0x87, - 0xf2, 0xf5, 0xef, 0x2e, 0xc2, 0x2c, 0xa8, 0x74, 0x32, 0x24, 0xaa, 0x30, 0x55, 0x7e, 0x0a, 0x59, - 0x2e, 0x41, 0x45, 0xc8, 0x3d, 0xd8, 0xdd, 0xde, 0xdd, 0x7b, 0x6f, 0xb7, 0x92, 0x40, 0x00, 0xd9, - 0x5a, 0xa3, 0xd1, 0xdc, 0x6f, 0x57, 0x24, 0x54, 0x80, 0x4c, 0xad, 0xbe, 0xa7, 0xb6, 0x2b, 0x49, - 0x2a, 0x56, 0x9b, 0x3f, 0x6e, 0x36, 0xda, 0x95, 0x14, 0x5a, 0x81, 0x12, 0x7f, 0xd6, 0xee, 0xee, - 0xa9, 0xf7, 0x6a, 0xed, 0x4a, 0x3a, 0x20, 0x3a, 0x68, 0xee, 0xde, 0x69, 0xaa, 0x95, 0x8c, 0x72, - 0x8d, 0x16, 0x27, 0x31, 0x6c, 0xc4, 0x2f, 0x43, 0xa4, 0x40, 0x19, 0xa2, 0xfc, 0x36, 0x09, 0x72, - 0x3c, 0xc9, 0x40, 0xad, 0xc8, 0xb2, 0x5f, 0x5b, 0x98, 0x9f, 0x44, 0xd6, 0x8e, 0x5e, 0x84, 0xf2, - 0x18, 0x1f, 0x61, 0xd2, 0x1d, 0x70, 0xc2, 0xc3, 0x53, 0x58, 0x49, 0x2d, 0x09, 0x29, 0x33, 0x72, - 0xb8, 0xda, 0xcf, 0x70, 0x97, 0x68, 0xbc, 0x1e, 0xe2, 0x87, 0xad, 0x40, 0xd5, 0xa8, 0xf4, 0x80, - 0x0b, 0x95, 0x8f, 0x9e, 0x69, 0x27, 0x0b, 0x90, 0x51, 0x9b, 0x6d, 0xf5, 0xfd, 0x4a, 0x0a, 0x21, - 0x28, 0xb3, 0x47, 0xed, 0x60, 0xb7, 0xb6, 0x7f, 0xd0, 0xda, 0xa3, 0x3b, 0x79, 0x0e, 0x96, 0xdd, - 0x9d, 0x74, 0x85, 0x19, 0xe5, 0x5f, 0x12, 0x2c, 0x47, 0x02, 0x03, 0xbd, 0x06, 0x19, 0x4e, 0x95, - 0xa7, 0x37, 0xc4, 0x59, 0x44, 0x8b, 0x18, 0xe2, 0x8a, 0xe8, 0x16, 0xe4, 0xb1, 0xa8, 0xf4, 0xcf, - 0x06, 0x1f, 0xef, 0x4d, 0xb8, 0x9d, 0x00, 0x61, 0xe8, 0xe9, 0xa3, 0xdb, 0x50, 0xf0, 0x62, 0x5b, - 0xd4, 0x62, 0xeb, 0x51, 0x63, 0x0f, 0x13, 0x84, 0xb5, 0x6f, 0x81, 0xde, 0xf0, 0x59, 0x57, 0x3a, - 0x4a, 0xce, 0x85, 0x31, 0x7f, 0x2d, 0x4c, 0x5d, 0x6d, 0xa5, 0x01, 0xc5, 0xc0, 0x4a, 0xd0, 0x25, - 0x28, 0x8c, 0xf4, 0x13, 0xd1, 0x35, 0xe2, 0xf5, 0x7f, 0x7e, 0xa4, 0x9f, 0xf0, 0x86, 0xd1, 0x05, - 0xc8, 0xd1, 0x97, 0x7d, 0x9d, 0x63, 0x4b, 0x4a, 0xcd, 0x8e, 0xf4, 0x93, 0x77, 0x75, 0x47, 0xf9, - 0x00, 0xca, 0xe1, 0xae, 0x09, 0x3d, 0x7f, 0x63, 0x6b, 0x62, 0xf6, 0x98, 0x8f, 0x8c, 0xca, 0x07, - 0xe8, 0x06, 0x64, 0x8e, 0x2d, 0x0e, 0x4d, 0xd3, 0x82, 0xf4, 0xd0, 0x22, 0x38, 0xd0, 0x73, 0xe1, - 0xba, 0xca, 0x09, 0x64, 0x18, 0xd8, 0x50, 0xe0, 0x60, 0xfd, 0x0f, 0xc1, 0x36, 0xe9, 0x33, 0xfa, - 0x00, 0x40, 0x27, 0x64, 0x6c, 0x74, 0x26, 0xbe, 0xdb, 0x17, 0xa6, 0x41, 0x55, 0xcd, 0xd5, 0xaa, - 0x3f, 0x2f, 0x30, 0x6b, 0xd5, 0x37, 0x0c, 0xe0, 0x56, 0xc0, 0x9d, 0xb2, 0x0b, 0xe5, 0xb0, 0x6d, - 0xb0, 0xfb, 0xb8, 0x34, 0xa5, 0xfb, 0xe8, 0x71, 0x1a, 0x8f, 0x11, 0xa5, 0x78, 0x8f, 0x8b, 0x0d, - 0x94, 0xdf, 0x48, 0x90, 0x6f, 0x9f, 0x88, 0xa3, 0x1c, 0xd3, 0x66, 0xf1, 0x4d, 0x93, 0xc1, 0xb6, - 0x02, 0xef, 0xdb, 0xa4, 0xbc, 0x5e, 0xd0, 0xdb, 0x5e, 0xa8, 0xa6, 0x17, 0x2b, 0x05, 0xdd, 0x76, - 0x98, 0x00, 0xa7, 0xb7, 0xa0, 0xe0, 0x9d, 0x26, 0x4a, 0xd9, 0xf5, 0x5e, 0x6f, 0x8c, 0x1d, 0x47, - 0xac, 0xcc, 0x1d, 0xb2, 0x5e, 0x9d, 0xf5, 0x58, 0xb4, 0x2d, 0x52, 0x2a, 0x1f, 0x28, 0x1d, 0x58, - 0x8e, 0xa4, 0x27, 0xf4, 0x26, 0xe4, 0xec, 0x49, 0x47, 0x73, 0x37, 0x27, 0x14, 0x2e, 0x2e, 0x85, - 0x9b, 0x74, 0x86, 0x46, 0x77, 0x1b, 0x9f, 0xba, 0x53, 0xb1, 0x27, 0x9d, 0x6d, 0xbe, 0x83, 0xfc, - 0x1b, 0xc9, 0xe0, 0x37, 0x7e, 0x27, 0x41, 0xde, 0x3d, 0x0f, 0xe8, 0x87, 0xc1, 0xe0, 0xe0, 0xfe, - 0xab, 0x71, 0xf9, 0x52, 0x78, 0x0f, 0xc4, 0xc6, 0x55, 0x58, 0x71, 0x8c, 0xbe, 0x89, 0x7b, 0x9a, - 0x5f, 0x31, 0xb0, 0x8f, 0xe5, 0xd5, 0x65, 0xfe, 0x62, 0xc7, 0x2d, 0x17, 0x90, 0x02, 0x4b, 0xc7, - 0x16, 0x31, 0xcc, 0xbe, 0xc6, 0xe7, 0xf4, 0xb7, 0x1c, 0x9b, 0x54, 0x91, 0x0b, 0xf7, 0xd9, 0xd4, - 0xfe, 0x2d, 0x41, 0xde, 0x8d, 0x63, 0xb4, 0x19, 0x38, 0x94, 0xe5, 0x33, 0x9d, 0x10, 0x57, 0xcd, - 0xef, 0xca, 0x85, 0xd7, 0x92, 0x7c, 0xd6, 0xb5, 0xc4, 0x35, 0x55, 0xdd, 0xce, 0x76, 0xfa, 0x99, - 0x3b, 0xdb, 0xaf, 0x02, 0x22, 0x16, 0xd1, 0x87, 0x5a, 0x68, 0xdd, 0x9c, 0x52, 0x55, 0xd8, 0x9b, - 0xc3, 0xc0, 0xda, 0x7f, 0x29, 0x41, 0xde, 0x4b, 0x93, 0xcf, 0xda, 0x64, 0x3b, 0x0f, 0x59, 0x91, - 0x0d, 0x78, 0x97, 0x4d, 0x8c, 0xbc, 0x2e, 0x6f, 0x3a, 0xd0, 0xe5, 0x95, 0x21, 0x3f, 0xc2, 0x44, - 0x67, 0x4c, 0x81, 0x17, 0x75, 0xde, 0xf8, 0xea, 0x9b, 0x50, 0x0c, 0x74, 0x3b, 0x69, 0x50, 0xee, - 0x36, 0xdf, 0xab, 0x24, 0xe4, 0xdc, 0x27, 0x9f, 0x5d, 0x4e, 0xed, 0xe2, 0xc7, 0xf4, 0x40, 0xab, - 0xcd, 0x46, 0xab, 0xd9, 0xd8, 0xae, 0x48, 0x72, 0xf1, 0x93, 0xcf, 0x2e, 0xe7, 0x54, 0xcc, 0x1a, - 0x29, 0x57, 0x5b, 0xb0, 0x14, 0xfc, 0x4d, 0xc2, 0x09, 0x05, 0x41, 0xf9, 0xce, 0x83, 0xfd, 0x9d, - 0xad, 0x46, 0xad, 0xdd, 0xd4, 0x0e, 0xf7, 0xda, 0xcd, 0x8a, 0x84, 0x2e, 0xc0, 0xb9, 0x9d, 0xad, - 0x77, 0x5b, 0x6d, 0xad, 0xb1, 0xb3, 0xd5, 0xdc, 0x6d, 0x6b, 0xb5, 0x76, 0xbb, 0xd6, 0xd8, 0xae, - 0x24, 0xaf, 0x7f, 0x5e, 0x80, 0xe5, 0x5a, 0xbd, 0xb1, 0x45, 0x93, 0xa1, 0xd1, 0xd5, 0x59, 0x41, - 0xf9, 0x23, 0x48, 0xb3, 0x9a, 0x7a, 0xc6, 0xe5, 0xa9, 0x3c, 0xab, 0x2b, 0x87, 0xea, 0x90, 0x61, - 0xa5, 0x36, 0x9a, 0x75, 0x97, 0x2a, 0xcf, 0x6c, 0xd2, 0xd1, 0x49, 0xb0, 0xa0, 0x99, 0x71, 0xb5, - 0x2a, 0xcf, 0xea, 0xd8, 0xa1, 0x5d, 0x28, 0xf8, 0x35, 0xf2, 0xbc, 0x8b, 0x56, 0x79, 0x6e, 0x0f, - 0x8f, 0xfa, 0xf3, 0xeb, 0x80, 0x79, 0xd7, 0x8f, 0xf2, 0x5c, 0x24, 0x43, 0x2d, 0xc8, 0xb9, 0xb5, - 0xd5, 0xec, 0xab, 0x50, 0x79, 0x4e, 0x7f, 0x8d, 0x6e, 0x37, 0xaf, 0x7d, 0x67, 0xdd, 0xe7, 0xca, - 0x33, 0x9b, 0x84, 0xa8, 0x09, 0x59, 0x41, 0x6c, 0x67, 0x5e, 0x6e, 0xca, 0xb3, 0xbb, 0x65, 0x74, - 0x93, 0xfc, 0x46, 0xc2, 0xbc, 0xbb, 0x69, 0x79, 0x6e, 0xd7, 0x13, 0xdd, 0x07, 0x08, 0xd4, 0xb7, - 0x73, 0x2f, 0x9d, 0xe5, 0xf9, 0xdd, 0x4c, 0xb4, 0x0d, 0x79, 0xaf, 0x92, 0x99, 0x73, 0x09, 0x2c, - 0xcf, 0x6b, 0x2c, 0xa2, 0x87, 0x50, 0x0a, 0x93, 0xf8, 0x45, 0xae, 0x76, 0xe5, 0x85, 0x3a, 0x86, - 0xd4, 0x77, 0x98, 0xcf, 0x2f, 0x72, 0xd1, 0x2b, 0x2f, 0xd4, 0x3e, 0x44, 0x47, 0xb0, 0x72, 0x96, - 0x6d, 0x2f, 0x7a, 0xeb, 0x2b, 0x2f, 0xdc, 0x4e, 0x44, 0x06, 0xa0, 0x29, 0x0c, 0x7d, 0xe1, 0x2b, - 0x60, 0x79, 0xf1, 0xde, 0x62, 0xfd, 0xf6, 0x17, 0x4f, 0xd6, 0xa4, 0x2f, 0x9f, 0xac, 0x49, 0x7f, - 0x7d, 0xb2, 0x26, 0x7d, 0xfa, 0x74, 0x2d, 0xf1, 0xe5, 0xd3, 0xb5, 0xc4, 0x9f, 0x9f, 0xae, 0x25, - 0x1e, 0x5e, 0xe9, 0x1b, 0x64, 0x30, 0xe9, 0x6c, 0x74, 0xad, 0xd1, 0xe6, 0xd0, 0x30, 0xf1, 0xe6, - 0x94, 0x7f, 0xc0, 0x74, 0xb2, 0x2c, 0xc9, 0xdc, 0xf8, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x9b, - 0x97, 0x59, 0xff, 0x1f, 0x23, 0x00, 0x00, + // 2889 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x5a, 0xcb, 0x73, 0xe3, 0xc6, + 0xd1, 0x27, 0xf8, 0x46, 0x4b, 0xa4, 0xa8, 0x59, 0x79, 0x97, 0x8b, 0xb5, 0xa5, 0xfd, 0xb0, 0x9f, + 0x63, 0x7b, 0x63, 0x4b, 0xf6, 0xae, 0x63, 0xc7, 0x76, 0xec, 0x98, 0xe2, 0xd2, 0xa6, 0x2c, 0xad, + 0xa4, 0x85, 0x68, 0xb9, 0xfc, 0x0a, 0x0c, 0x82, 0x23, 0x12, 0x59, 0x12, 0x80, 0x09, 0x50, 0x96, + 0x72, 0x4b, 0x52, 0xa9, 0x4a, 0xf9, 0xe4, 0x5c, 0x52, 0xb9, 0xf8, 0xff, 0xc8, 0x21, 0x55, 0x39, + 0xc6, 0x47, 0x1f, 0x73, 0x72, 0x52, 0xde, 0x4a, 0x55, 0x2a, 0xf7, 0x54, 0x2a, 0x97, 0x24, 0x35, + 0x0f, 0x3c, 0x05, 0x80, 0x5c, 0x3b, 0xb7, 0xdc, 0x66, 0x1a, 0xdd, 0x8d, 0xe9, 0x41, 0x4f, 0xf7, + 0xaf, 0x7b, 0x00, 0x57, 0x2d, 0xc7, 0x9d, 0x6a, 0xba, 0x65, 0x6e, 0x69, 0x7d, 0xdd, 0xd8, 0x72, + 0xcf, 0x6d, 0xec, 0x6c, 0xda, 0x53, 0xcb, 0xb5, 0x50, 0xcd, 0x7b, 0xb4, 0x49, 0x1e, 0x49, 0xd7, + 0x7c, 0x4e, 0x7d, 0x7a, 0x6e, 0xbb, 0xd6, 0x96, 0x3d, 0xb5, 0xac, 0x13, 0xc6, 0x2b, 0x49, 0xfe, + 0x43, 0xaa, 0x21, 0xac, 0x27, 0xf4, 0x8c, 0x0b, 0xde, 0xc7, 0xe7, 0xde, 0xb3, 0x6b, 0x31, 0x39, + 0x5b, 0x9b, 0x6a, 0x13, 0xef, 0xe1, 0xc6, 0xd0, 0xb2, 0x86, 0x63, 0xbc, 0x45, 0x67, 0xfd, 0xd9, + 0xc9, 0x96, 0x6b, 0x4c, 0xb0, 0xe3, 0x6a, 0x13, 0x9b, 0x33, 0xac, 0x0d, 0xad, 0xa1, 0x45, 0x87, + 0x5b, 0x64, 0xc4, 0xa8, 0xf2, 0xaf, 0x44, 0xa8, 0x28, 0xf8, 0xe3, 0x19, 0x76, 0x5c, 0xf4, 0x2c, + 0x14, 0xb1, 0x3e, 0xb2, 0x9a, 0xc2, 0x75, 0xe1, 0xc9, 0xa5, 0x5b, 0xd2, 0x66, 0xc4, 0xa4, 0x4d, + 0xce, 0xd5, 0xd1, 0x47, 0x56, 0x37, 0xa7, 0x50, 0x4e, 0x74, 0x1b, 0x4a, 0x27, 0xe3, 0x99, 0x33, + 0x6a, 0xe6, 0xa9, 0xc8, 0xb5, 0x64, 0x91, 0x37, 0x08, 0x4b, 0x37, 0xa7, 0x30, 0x5e, 0xf2, 0x1a, + 0xc3, 0x3c, 0xb1, 0x9a, 0x85, 0xac, 0xd7, 0xec, 0x98, 0x27, 0xf4, 0x35, 0x84, 0x13, 0xbd, 0x0e, + 0xe0, 0x60, 0x57, 0xb5, 0x6c, 0xd7, 0xb0, 0xcc, 0x66, 0x91, 0xca, 0x6d, 0x24, 0xcb, 0x1d, 0x61, + 0xf7, 0x80, 0xb2, 0x75, 0x73, 0x8a, 0xe8, 0x78, 0x13, 0xa2, 0xc1, 0x30, 0x0d, 0x57, 0xd5, 0x47, + 0x9a, 0x61, 0x36, 0x4b, 0x59, 0x1a, 0x76, 0x4c, 0xc3, 0x6d, 0x13, 0x36, 0xa2, 0xc1, 0xf0, 0x26, + 0xc4, 0xd4, 0x8f, 0x67, 0x78, 0x7a, 0xde, 0x2c, 0x67, 0x99, 0x7a, 0x8f, 0xb0, 0x10, 0x53, 0x29, + 0x2f, 0x6a, 0xc3, 0x52, 0x1f, 0x0f, 0x0d, 0x53, 0xed, 0x8f, 0x2d, 0xfd, 0x7e, 0xb3, 0x42, 0x45, + 0xaf, 0x27, 0x8b, 0x6e, 0x13, 0xc6, 0x6d, 0xc2, 0xd7, 0xcd, 0x29, 0xd0, 0xf7, 0x67, 0xe8, 0x65, + 0xa8, 0xea, 0x23, 0xac, 0xdf, 0x57, 0xdd, 0xb3, 0x66, 0x95, 0x6a, 0x78, 0x2c, 0x59, 0x43, 0x9b, + 0x70, 0xf5, 0xce, 0xba, 0x39, 0xa5, 0xa2, 0xb3, 0x21, 0xb1, 0x7b, 0x80, 0xc7, 0xc6, 0x29, 0x9e, + 0x12, 0x69, 0x31, 0xcb, 0xee, 0x3b, 0x8c, 0x8f, 0xca, 0x8b, 0x03, 0x6f, 0x82, 0x5e, 0x05, 0x11, + 0x9b, 0x03, 0x6e, 0x00, 0x50, 0x05, 0xeb, 0x29, 0x9e, 0x61, 0x0e, 0xbc, 0xe5, 0x57, 0x31, 0x1f, + 0xa3, 0x17, 0xa0, 0xac, 0x5b, 0x93, 0x89, 0xe1, 0x36, 0x97, 0xa8, 0xec, 0xa3, 0x29, 0x4b, 0xa7, + 0x3c, 0xdd, 0x9c, 0xc2, 0xb9, 0xd1, 0x1e, 0xd4, 0xc7, 0x86, 0xe3, 0xaa, 0x8e, 0xa9, 0xd9, 0xce, + 0xc8, 0x72, 0x9d, 0xe6, 0x32, 0x95, 0xbf, 0x91, 0x2c, 0xbf, 0x67, 0x38, 0xee, 0x91, 0xc7, 0xda, + 0xcd, 0x29, 0xb5, 0x71, 0x98, 0x40, 0xb4, 0x59, 0x27, 0x27, 0x78, 0xea, 0xab, 0x6b, 0xd6, 0xb2, + 0xb4, 0x1d, 0x10, 0x5e, 0x4f, 0x9a, 0x68, 0xb3, 0xc2, 0x04, 0xf4, 0x2e, 0x5c, 0x1a, 0x5b, 0xda, + 0xc0, 0x57, 0xa6, 0xea, 0xa3, 0x99, 0x79, 0xbf, 0x59, 0xa7, 0x2a, 0x9f, 0x48, 0x59, 0xa0, 0xa5, + 0x0d, 0x3c, 0x05, 0x6d, 0xc2, 0xde, 0xcd, 0x29, 0xab, 0xe3, 0x38, 0x11, 0x7d, 0x00, 0x6b, 0x9a, + 0x6d, 0x8f, 0xcf, 0xe3, 0xba, 0x57, 0xa8, 0xee, 0x27, 0x93, 0x75, 0xb7, 0x88, 0x44, 0x5c, 0x39, + 0xd2, 0x2e, 0x50, 0xd1, 0x21, 0x34, 0x98, 0x3b, 0x4e, 0xb1, 0xef, 0x51, 0x03, 0xaa, 0xf9, 0xff, + 0x33, 0x7c, 0x52, 0xc1, 0xba, 0xef, 0x58, 0xf5, 0x7e, 0x84, 0x82, 0xde, 0x82, 0x3a, 0xf1, 0x8e, + 0x90, 0x3e, 0x4c, 0xf5, 0xc9, 0xa9, 0x2e, 0x12, 0xd6, 0xb6, 0x8c, 0x43, 0xf3, 0xed, 0x0a, 0x94, + 0x4e, 0xb5, 0xf1, 0x0c, 0xcb, 0x4f, 0xc0, 0x52, 0x28, 0xd8, 0xa0, 0x26, 0x54, 0x26, 0xd8, 0x71, + 0xb4, 0x21, 0xa6, 0x91, 0x49, 0x54, 0xbc, 0xa9, 0x5c, 0x87, 0xe5, 0x70, 0x88, 0x91, 0x27, 0xbe, + 0x20, 0x09, 0x1f, 0x44, 0xf0, 0x14, 0x4f, 0x1d, 0x12, 0x33, 0xb8, 0x20, 0x9f, 0xa2, 0x1b, 0x50, + 0xa3, 0x0e, 0xad, 0x7a, 0xcf, 0x49, 0xfc, 0x2a, 0x2a, 0xcb, 0x94, 0x78, 0xcc, 0x99, 0x36, 0x60, + 0xc9, 0xbe, 0x65, 0xfb, 0x2c, 0x05, 0xca, 0x02, 0xf6, 0x2d, 0x9b, 0x33, 0xc8, 0x2f, 0x43, 0x23, + 0x1e, 0x75, 0x50, 0x03, 0x0a, 0xf7, 0xf1, 0x39, 0x7f, 0x1f, 0x19, 0xa2, 0x35, 0x6e, 0x16, 0x7d, + 0x87, 0xa8, 0x70, 0x1b, 0xff, 0x90, 0xf7, 0x85, 0xfd, 0x80, 0x83, 0xbe, 0x0f, 0x45, 0x12, 0xb5, + 0xfd, 0x00, 0xcc, 0x42, 0xfa, 0xa6, 0x17, 0xd2, 0x37, 0x7b, 0x5e, 0x48, 0xdf, 0xae, 0x7e, 0xf1, + 0xd5, 0x46, 0xee, 0xb3, 0x3f, 0x6d, 0x08, 0x0a, 0x95, 0x40, 0x57, 0x49, 0x8c, 0xd0, 0x0c, 0x53, + 0x35, 0x06, 0xfc, 0x3d, 0x15, 0x3a, 0xdf, 0x19, 0xa0, 0x1d, 0x68, 0xe8, 0x96, 0xe9, 0x60, 0xd3, + 0x99, 0x39, 0x2a, 0x4b, 0x19, 0x3c, 0xf4, 0xc6, 0xcf, 0x71, 0xdb, 0x63, 0x3b, 0xa4, 0x5c, 0xca, + 0x8a, 0x1e, 0x25, 0xa0, 0x3b, 0x00, 0xa7, 0xda, 0xd8, 0x18, 0x68, 0xae, 0x35, 0x75, 0x9a, 0xc5, + 0xeb, 0x85, 0x04, 0x25, 0xc7, 0x1e, 0xc3, 0xdb, 0xf6, 0x40, 0x73, 0xf1, 0x76, 0x91, 0xac, 0x54, + 0x09, 0xc9, 0xa1, 0xef, 0xc0, 0x8a, 0x66, 0xdb, 0xaa, 0xe3, 0x6a, 0x2e, 0x56, 0xfb, 0xe7, 0x2e, + 0x76, 0x68, 0x40, 0x5e, 0x56, 0x6a, 0x9a, 0x6d, 0x1f, 0x11, 0xea, 0x36, 0x21, 0xa2, 0xc7, 0xa1, + 0x4e, 0xc2, 0xaf, 0xa1, 0x8d, 0xd5, 0x11, 0x36, 0x86, 0x23, 0x97, 0x86, 0xde, 0x82, 0x52, 0xe3, + 0xd4, 0x2e, 0x25, 0xca, 0x03, 0xdf, 0x09, 0x68, 0xf0, 0x45, 0x08, 0x8a, 0x03, 0xcd, 0xd5, 0xe8, + 0x26, 0x2e, 0x2b, 0x74, 0x4c, 0x68, 0xb6, 0xe6, 0x8e, 0xf8, 0xd6, 0xd0, 0x31, 0xba, 0x0c, 0x65, + 0xae, 0xb6, 0x40, 0xd5, 0xf2, 0x19, 0xf9, 0x5e, 0xf6, 0xd4, 0x3a, 0xc5, 0x34, 0xcf, 0x54, 0x15, + 0x36, 0x91, 0xff, 0x25, 0xc0, 0xea, 0x85, 0x40, 0x4d, 0xf4, 0x8e, 0x34, 0x67, 0xe4, 0xbd, 0x8b, + 0x8c, 0xd1, 0xf3, 0x44, 0xaf, 0x36, 0xc0, 0x53, 0x9e, 0x14, 0x2f, 0x07, 0x1b, 0xc4, 0x12, 0x7d, + 0x97, 0x3e, 0xe5, 0x1b, 0xc3, 0x79, 0xd1, 0x5d, 0x68, 0x8c, 0x35, 0xc7, 0x55, 0x59, 0xf8, 0x53, + 0x43, 0x09, 0x32, 0x1e, 0xec, 0xf7, 0x34, 0x2f, 0x5c, 0x12, 0x27, 0xe7, 0x6a, 0xea, 0xe3, 0x08, + 0x15, 0x1d, 0xc2, 0x5a, 0xff, 0xfc, 0x27, 0x9a, 0xe9, 0x1a, 0x26, 0x56, 0x2f, 0x7c, 0xb3, 0x2b, + 0x31, 0x95, 0x9d, 0x53, 0x63, 0x80, 0x4d, 0xdd, 0xfb, 0x58, 0x97, 0x7c, 0x51, 0xff, 0x63, 0x3a, + 0xf2, 0x21, 0xd4, 0xa3, 0x69, 0x06, 0xd5, 0x21, 0xef, 0x9e, 0x71, 0xd3, 0xf3, 0xee, 0x19, 0xda, + 0x84, 0x22, 0x31, 0x90, 0x9a, 0x5d, 0xbf, 0x90, 0xd7, 0xb9, 0x54, 0xef, 0xdc, 0xc6, 0x0a, 0xe5, + 0x93, 0x65, 0xff, 0x04, 0xf8, 0xa9, 0x27, 0xae, 0x53, 0x7e, 0x0a, 0x56, 0x62, 0xd9, 0x25, 0xf4, + 0xdd, 0x84, 0xf0, 0x77, 0x93, 0x57, 0xa0, 0x16, 0x49, 0x26, 0xf2, 0x65, 0x58, 0x4b, 0xca, 0x0e, + 0xf2, 0x89, 0x4f, 0x8f, 0xc4, 0x79, 0x74, 0x1b, 0xaa, 0x7e, 0x7a, 0x60, 0x27, 0x30, 0xbe, 0x4f, + 0x1e, 0xab, 0xe2, 0x33, 0x92, 0x83, 0x47, 0x9c, 0x99, 0x7a, 0x41, 0x9e, 0x2e, 0xbb, 0xa2, 0xd9, + 0x76, 0x57, 0x73, 0x46, 0xf2, 0x47, 0xd0, 0x4c, 0x0b, 0xfe, 0x31, 0x23, 0x8a, 0xbe, 0xf3, 0x5d, + 0x86, 0xf2, 0x89, 0x35, 0x9d, 0x68, 0x2e, 0x55, 0x56, 0x53, 0xf8, 0x8c, 0x38, 0x25, 0x4b, 0x04, + 0x05, 0x4a, 0x66, 0x13, 0x59, 0x85, 0xab, 0xa9, 0x29, 0x80, 0x88, 0x18, 0xe6, 0x00, 0xb3, 0xdd, + 0xac, 0x29, 0x6c, 0x12, 0x28, 0x62, 0x8b, 0x65, 0x13, 0xf2, 0x5a, 0x07, 0x9b, 0xc4, 0x67, 0x0b, + 0xf4, 0x84, 0xf0, 0x99, 0x7c, 0x17, 0x1e, 0x49, 0xcc, 0x04, 0x21, 0x27, 0x17, 0x16, 0x77, 0x72, + 0xf9, 0x19, 0xb8, 0x94, 0x90, 0x08, 0x52, 0xbf, 0xe8, 0x5f, 0x44, 0xa8, 0x2a, 0xd8, 0xb1, 0x49, + 0x14, 0x42, 0xaf, 0x83, 0x88, 0xcf, 0x74, 0xcc, 0x20, 0xa0, 0x90, 0x02, 0xa4, 0x18, 0x6f, 0xc7, + 0xe3, 0x23, 0x48, 0xc6, 0x17, 0x42, 0xcf, 0x71, 0x78, 0x9b, 0x86, 0x55, 0xb9, 0x70, 0x18, 0xdf, + 0x3e, 0xef, 0xe1, 0xdb, 0x42, 0x0a, 0x78, 0x61, 0x32, 0x31, 0x80, 0xfb, 0x1c, 0x07, 0xb8, 0xc5, + 0xcc, 0x17, 0x45, 0x10, 0x6e, 0x2b, 0x82, 0x70, 0x4b, 0x99, 0xe6, 0xa5, 0x40, 0xdc, 0x56, 0x04, + 0xe2, 0x96, 0x33, 0x55, 0xa4, 0x60, 0xdc, 0xe7, 0x3d, 0x8c, 0x5b, 0xc9, 0x34, 0x37, 0x06, 0x72, + 0xef, 0x44, 0x41, 0x2e, 0x83, 0xa8, 0xff, 0x97, 0x22, 0x9b, 0x8a, 0x72, 0x5f, 0x09, 0xa1, 0x5c, + 0x31, 0x05, 0x66, 0x32, 0x15, 0x09, 0x30, 0xb7, 0x15, 0x81, 0xb9, 0x90, 0x69, 0x7b, 0x0a, 0xce, + 0x7d, 0x2d, 0x8c, 0x73, 0x97, 0x52, 0x80, 0x32, 0x77, 0x91, 0x24, 0xa0, 0xfb, 0xa2, 0x0f, 0x74, + 0x97, 0x53, 0x30, 0x3a, 0x5f, 0x7d, 0x1c, 0xe9, 0xde, 0xbd, 0x80, 0x74, 0x6b, 0x29, 0x90, 0x8c, + 0x29, 0x98, 0x03, 0x75, 0xef, 0x5e, 0x80, 0xba, 0xf5, 0x4c, 0x75, 0x73, 0xb0, 0xee, 0x7b, 0xc9, + 0x58, 0x37, 0x0d, 0x8f, 0xf2, 0x25, 0x2e, 0x06, 0x76, 0x3f, 0x4c, 0x01, 0xbb, 0x0d, 0xaa, 0xfc, + 0xa9, 0x14, 0xe5, 0x0b, 0xa3, 0xdd, 0x7b, 0xa9, 0x68, 0xf7, 0xf1, 0x2c, 0xe7, 0xcc, 0x82, 0xbb, + 0xbb, 0x29, 0x70, 0xf7, 0x46, 0xba, 0xa7, 0x2c, 0x80, 0x77, 0x9f, 0x22, 0xd0, 0x22, 0x16, 0xba, + 0x48, 0xa0, 0xc6, 0xd3, 0xa9, 0x35, 0xe5, 0x50, 0x92, 0x4d, 0xe4, 0x27, 0x09, 0xd8, 0x09, 0x02, + 0x55, 0x06, 0x36, 0xa6, 0xe9, 0x30, 0x14, 0x9e, 0xe4, 0xdf, 0x0a, 0x81, 0x2c, 0xc5, 0x08, 0x61, + 0xa0, 0x24, 0x72, 0xa0, 0x14, 0x82, 0xcc, 0xf9, 0x28, 0x64, 0xde, 0x80, 0x25, 0x92, 0xe8, 0x62, + 0x68, 0x58, 0xb3, 0x3d, 0x34, 0x8c, 0x6e, 0xc2, 0x2a, 0x45, 0x30, 0x0c, 0x58, 0xf3, 0x80, 0x5e, + 0xa4, 0x01, 0x7d, 0x85, 0x3c, 0x60, 0x47, 0x86, 0xa5, 0xb9, 0x67, 0xe0, 0x52, 0x88, 0xd7, 0x4f, + 0xa0, 0x0c, 0x06, 0x36, 0x7c, 0xee, 0x16, 0xcf, 0xa4, 0x77, 0x83, 0x0d, 0x0a, 0x90, 0x36, 0x82, + 0xa2, 0x6e, 0x0d, 0x30, 0x4f, 0x6f, 0x74, 0x4c, 0xd0, 0xf7, 0xd8, 0x1a, 0xf2, 0x24, 0x46, 0x86, + 0x84, 0xcb, 0x8f, 0xc5, 0x22, 0x0b, 0xb6, 0xf2, 0xef, 0x85, 0x40, 0x5f, 0x00, 0xbe, 0x93, 0x70, + 0xb2, 0xf0, 0xdf, 0xc0, 0xc9, 0xf9, 0x6f, 0x88, 0x93, 0xc3, 0xd0, 0xa2, 0x10, 0x85, 0x16, 0x7f, + 0x17, 0x82, 0xaf, 0xeb, 0xa3, 0xde, 0x6f, 0xb6, 0x1b, 0x01, 0x4e, 0x28, 0xd1, 0x6f, 0xc5, 0x71, + 0x02, 0xaf, 0x63, 0xca, 0xf4, 0xbd, 0xd1, 0x3a, 0xa6, 0xc2, 0x90, 0x03, 0x9d, 0xa0, 0x17, 0x40, + 0xa4, 0xad, 0x2d, 0xd5, 0xb2, 0x1d, 0x1e, 0xfa, 0xaf, 0x06, 0x96, 0xb2, 0x1e, 0xd6, 0xe6, 0x21, + 0xe1, 0x38, 0xb0, 0x1d, 0xa5, 0x6a, 0xf3, 0x51, 0x28, 0xe7, 0x8b, 0x11, 0xf4, 0xfd, 0x28, 0x88, + 0x64, 0xed, 0x8e, 0xad, 0xe9, 0x98, 0x06, 0x72, 0x51, 0x09, 0x08, 0xf2, 0x07, 0x80, 0x2e, 0x26, + 0x12, 0xf4, 0x06, 0x94, 0xf1, 0x29, 0x36, 0x5d, 0xf2, 0xbd, 0xc8, 0x56, 0xaf, 0x5d, 0x80, 0xb7, + 0xd8, 0x74, 0xb7, 0x9b, 0x64, 0x83, 0xff, 0xf6, 0xd5, 0x46, 0x83, 0xf1, 0x3e, 0x6d, 0x4d, 0x0c, + 0x17, 0x4f, 0x6c, 0xf7, 0x5c, 0xe1, 0xd2, 0xf2, 0x4f, 0xf3, 0x04, 0x6d, 0x46, 0x92, 0x4c, 0xe2, + 0xbe, 0x7a, 0x07, 0x27, 0x1f, 0xaa, 0x30, 0x16, 0xdb, 0xeb, 0x75, 0x80, 0xa1, 0xe6, 0xa8, 0x9f, + 0x68, 0xa6, 0x8b, 0x07, 0x7c, 0xc3, 0x43, 0x14, 0x24, 0x41, 0x95, 0xcc, 0x66, 0x0e, 0x1e, 0xf0, + 0x62, 0xc7, 0x9f, 0x87, 0xac, 0xac, 0x7c, 0x1b, 0x2b, 0xa3, 0x3b, 0x5c, 0x8d, 0xef, 0xf0, 0xcf, + 0xf3, 0xc1, 0xd9, 0x08, 0x60, 0xf9, 0xff, 0xda, 0x2e, 0xfc, 0x82, 0x56, 0xe7, 0xd1, 0x6c, 0x8f, + 0xee, 0xc1, 0xaa, 0x7f, 0x3a, 0xd5, 0x19, 0x3d, 0xb5, 0x9e, 0xc7, 0x2d, 0x76, 0xb8, 0x1b, 0xa7, + 0x51, 0xb2, 0x83, 0x8e, 0xe1, 0x4a, 0x2c, 0xe6, 0xf8, 0x8a, 0xf3, 0x0b, 0x85, 0x9e, 0x47, 0xa2, + 0xa1, 0xc7, 0xd3, 0x1b, 0xec, 0x52, 0xe1, 0x5b, 0x9d, 0x88, 0x1d, 0x52, 0xf4, 0x85, 0x71, 0x4b, + 0xe2, 0x57, 0xbf, 0x01, 0xb5, 0x29, 0x76, 0x35, 0xc3, 0x54, 0x23, 0x05, 0xf5, 0x32, 0x23, 0xf2, + 0x32, 0x7d, 0x9f, 0x94, 0x12, 0x09, 0x08, 0x06, 0x7d, 0x0f, 0xc4, 0x00, 0xfa, 0x08, 0x89, 0xf5, + 0xa9, 0x5f, 0x77, 0x05, 0x9c, 0xf2, 0xef, 0x84, 0x40, 0x61, 0xb4, 0x8e, 0x6b, 0x43, 0x79, 0x8a, + 0x9d, 0xd9, 0x98, 0x95, 0x13, 0xf5, 0x5b, 0xdf, 0x5d, 0x04, 0xf9, 0x10, 0xea, 0x6c, 0xec, 0x2a, + 0x5c, 0x54, 0xfe, 0x11, 0x94, 0x19, 0x05, 0x2d, 0x41, 0xe5, 0xed, 0xfd, 0xdd, 0xfd, 0x83, 0x77, + 0xf6, 0x1b, 0x39, 0x04, 0x50, 0x6e, 0xb5, 0xdb, 0x9d, 0xc3, 0x5e, 0x43, 0x40, 0x22, 0x94, 0x5a, + 0xdb, 0x07, 0x4a, 0xaf, 0x91, 0x27, 0x64, 0xa5, 0xf3, 0x56, 0xa7, 0xdd, 0x6b, 0x14, 0xd0, 0x2a, + 0xd4, 0xd8, 0x58, 0x7d, 0xe3, 0x40, 0xb9, 0xdb, 0xea, 0x35, 0x8a, 0x21, 0xd2, 0x51, 0x67, 0xff, + 0x4e, 0x47, 0x69, 0x94, 0xe4, 0xe7, 0x48, 0xe9, 0x96, 0x82, 0x96, 0x82, 0x22, 0x4d, 0x08, 0x15, + 0x69, 0xf2, 0xaf, 0xf3, 0x20, 0xa5, 0x83, 0x20, 0xd4, 0x8d, 0x99, 0xfd, 0xec, 0xc2, 0xf8, 0x29, + 0x66, 0x3b, 0x7a, 0x1c, 0xea, 0x53, 0x7c, 0x82, 0x5d, 0x7d, 0xc4, 0x00, 0x19, 0x4b, 0x61, 0x35, + 0xa5, 0xc6, 0xa9, 0x54, 0xc8, 0x61, 0x6c, 0x3f, 0xc6, 0xba, 0xab, 0xb2, 0x6a, 0x91, 0x39, 0x9b, + 0x48, 0xd8, 0x08, 0xf5, 0x88, 0x11, 0xe5, 0x8f, 0x1e, 0x6a, 0x27, 0x45, 0x28, 0x29, 0x9d, 0x9e, + 0xf2, 0x6e, 0xa3, 0x80, 0x10, 0xd4, 0xe9, 0x50, 0x3d, 0xda, 0x6f, 0x1d, 0x1e, 0x75, 0x0f, 0xc8, + 0x4e, 0x5e, 0x82, 0x15, 0x6f, 0x27, 0x3d, 0x62, 0x49, 0x7e, 0x1a, 0x2e, 0x27, 0x23, 0xb8, 0xa4, + 0xb8, 0x25, 0xdf, 0x24, 0xe5, 0xff, 0x45, 0x78, 0x96, 0xc8, 0xfb, 0x0f, 0x01, 0x56, 0x62, 0x47, + 0x0e, 0x3d, 0x0b, 0x25, 0x56, 0x24, 0x24, 0x5f, 0x93, 0xd0, 0x58, 0xc1, 0x4f, 0x27, 0x63, 0x44, + 0x2f, 0x43, 0x15, 0xf3, 0x0e, 0xcb, 0xc5, 0x63, 0xcd, 0xca, 0x65, 0xaf, 0x03, 0xc3, 0x05, 0x7d, + 0x7e, 0xf4, 0x2a, 0x88, 0x7e, 0xd4, 0xe0, 0x55, 0xe8, 0x46, 0x5c, 0xd8, 0x8f, 0x36, 0x5c, 0x3a, + 0x90, 0x40, 0x2f, 0x06, 0x78, 0xae, 0x18, 0x2f, 0x4b, 0xb8, 0x30, 0x7b, 0xcc, 0x45, 0x3d, 0x6e, + 0xb9, 0x0d, 0x4b, 0x21, 0x4b, 0xd0, 0x35, 0x10, 0x27, 0xda, 0x19, 0xef, 0xd6, 0xb1, 0x2a, 0xbd, + 0x3a, 0xd1, 0xce, 0x58, 0xa3, 0xee, 0x0a, 0x54, 0xc8, 0xc3, 0xa1, 0xc6, 0xa2, 0x56, 0x41, 0x29, + 0x4f, 0xb4, 0xb3, 0x37, 0x35, 0x47, 0x7e, 0x1f, 0xea, 0xd1, 0x6e, 0x15, 0xf1, 0xec, 0xa9, 0x35, + 0x33, 0x07, 0x54, 0x47, 0x49, 0x61, 0x13, 0x74, 0x1b, 0x4a, 0xa7, 0x16, 0x0b, 0x7a, 0x49, 0xc7, + 0xff, 0xd8, 0x72, 0x71, 0xa8, 0xd7, 0xc5, 0x78, 0xe5, 0x33, 0x28, 0xd1, 0x30, 0x46, 0x3e, 0x1c, + 0xed, 0x3b, 0x71, 0x1c, 0x4b, 0xc6, 0xe8, 0x7d, 0x00, 0xcd, 0x75, 0xa7, 0x46, 0x7f, 0x16, 0xa8, + 0x7d, 0x2c, 0x29, 0x08, 0xb6, 0x3c, 0xae, 0xed, 0x47, 0x79, 0x34, 0x5c, 0x0b, 0x04, 0x43, 0x11, + 0x31, 0xa4, 0x4e, 0xde, 0x87, 0x7a, 0x54, 0x36, 0xdc, 0xf5, 0x5d, 0x4e, 0xe8, 0xfa, 0xfa, 0x68, + 0xc9, 0xc7, 0x5a, 0x05, 0xd6, 0x5b, 0xa4, 0x13, 0xf9, 0x97, 0x02, 0x54, 0x7b, 0x67, 0xfc, 0x90, + 0xa4, 0x34, 0x43, 0x02, 0xd1, 0x7c, 0xb8, 0x9d, 0xc3, 0xfa, 0x65, 0x05, 0xbf, 0x07, 0xf7, 0x9a, + 0x1f, 0x04, 0x8a, 0x8b, 0x15, 0xc1, 0x5e, 0x87, 0x86, 0x87, 0xbd, 0x57, 0x40, 0xf4, 0xbd, 0x89, + 0x14, 0x03, 0xda, 0x60, 0x30, 0xc5, 0x8e, 0xc3, 0x2d, 0xf3, 0xa6, 0xb4, 0x47, 0x6a, 0x7d, 0xc2, + 0xdb, 0x45, 0x05, 0x85, 0x4d, 0xe4, 0x3e, 0xac, 0xc4, 0x12, 0x1f, 0x7a, 0x09, 0x2a, 0xf6, 0xac, + 0xaf, 0x7a, 0x9b, 0x13, 0x39, 0x2e, 0x1e, 0x38, 0x9c, 0xf5, 0xc7, 0x86, 0xbe, 0x8b, 0xcf, 0xbd, + 0xa5, 0xd8, 0xb3, 0xfe, 0x2e, 0xdb, 0x41, 0xf6, 0x8e, 0x7c, 0xf8, 0x1d, 0xbf, 0x11, 0xa0, 0xea, + 0xf9, 0x03, 0xfa, 0x41, 0xf8, 0x70, 0x30, 0xfd, 0xcd, 0xb4, 0x4c, 0xcc, 0xb5, 0x87, 0xce, 0xc6, + 0x4d, 0x58, 0x75, 0x8c, 0xa1, 0x89, 0x07, 0x6a, 0x50, 0x8b, 0xd0, 0x97, 0x55, 0x95, 0x15, 0xf6, + 0x60, 0xcf, 0x2b, 0x44, 0x90, 0x0c, 0xcb, 0xa7, 0x96, 0x6b, 0x98, 0x43, 0x95, 0xad, 0xe9, 0xaf, + 0x15, 0xba, 0xa8, 0x25, 0x46, 0x3c, 0xa4, 0x4b, 0xfb, 0xa7, 0x00, 0x55, 0xef, 0x1c, 0xa3, 0xad, + 0x90, 0x53, 0xd6, 0x2f, 0xf4, 0x80, 0x3c, 0xb6, 0xa0, 0x1b, 0x1a, 0xb5, 0x25, 0xff, 0xb0, 0xb6, + 0xa4, 0x35, 0xb3, 0xbd, 0x1b, 0x85, 0xe2, 0x43, 0xdf, 0x28, 0x3c, 0x0d, 0xc8, 0xb5, 0x5c, 0x6d, + 0xac, 0x46, 0xec, 0x66, 0x60, 0xad, 0x41, 0x9f, 0x1c, 0x87, 0x6c, 0xff, 0x99, 0x00, 0x55, 0x3f, + 0x01, 0x3f, 0x6c, 0x73, 0xf3, 0x32, 0x94, 0x79, 0x9e, 0x61, 0xdd, 0x4d, 0x3e, 0xf3, 0xbb, 0xeb, + 0xc5, 0x50, 0x77, 0x5d, 0x82, 0xea, 0x04, 0xbb, 0x1a, 0xc5, 0x20, 0xac, 0x5c, 0xf4, 0xe7, 0x37, + 0x5f, 0x82, 0xa5, 0x50, 0x97, 0x99, 0x1c, 0xca, 0xfd, 0xce, 0x3b, 0x8d, 0x9c, 0x54, 0xf9, 0xf4, + 0xf3, 0xeb, 0x85, 0x7d, 0xfc, 0x09, 0x71, 0x68, 0xa5, 0xd3, 0xee, 0x76, 0xda, 0xbb, 0x0d, 0x41, + 0x5a, 0xfa, 0xf4, 0xf3, 0xeb, 0x15, 0x1e, 0xfe, 0x6f, 0x76, 0x61, 0x39, 0xfc, 0x4d, 0xa2, 0xa9, + 0x0a, 0x41, 0xfd, 0xce, 0xdb, 0x87, 0x7b, 0x3b, 0xed, 0x56, 0xaf, 0xa3, 0x1e, 0x1f, 0xf4, 0x3a, + 0x0d, 0x01, 0x5d, 0x81, 0x4b, 0x7b, 0x3b, 0x6f, 0x76, 0x7b, 0x6a, 0x7b, 0x6f, 0xa7, 0xb3, 0xdf, + 0x53, 0x5b, 0xbd, 0x5e, 0xab, 0xbd, 0xdb, 0xc8, 0xdf, 0xfa, 0x37, 0xc0, 0x4a, 0x6b, 0xbb, 0xbd, + 0x43, 0xd2, 0xac, 0xa1, 0x6b, 0xb4, 0x54, 0xfd, 0x21, 0x14, 0x69, 0xb5, 0x9e, 0x71, 0xa5, 0x2e, + 0x65, 0xf5, 0x23, 0xd1, 0x36, 0x94, 0x68, 0x11, 0x8f, 0xb2, 0x6e, 0xd8, 0xa5, 0xcc, 0xf6, 0x24, + 0x59, 0x04, 0x3d, 0x34, 0x19, 0x17, 0xee, 0x52, 0x56, 0xaf, 0x12, 0xed, 0x83, 0x18, 0x54, 0xdf, + 0xf3, 0xae, 0xdf, 0xa5, 0xb9, 0xdd, 0x4b, 0xa2, 0x2f, 0xa8, 0x30, 0xe6, 0x5d, 0x4a, 0x4b, 0x73, + 0x23, 0x19, 0xea, 0x42, 0xc5, 0xab, 0xda, 0xb2, 0x2f, 0xc8, 0xa5, 0x39, 0x9d, 0x45, 0xb2, 0xdd, + 0xac, 0xaa, 0xce, 0xba, 0xe5, 0x97, 0x32, 0xdb, 0xa3, 0xa8, 0x03, 0x65, 0x0e, 0x99, 0x33, 0xaf, + 0xbc, 0xa5, 0xec, 0x3e, 0x21, 0xd9, 0xa4, 0xa0, 0x45, 0x31, 0xef, 0x8f, 0x05, 0x69, 0x6e, 0xbf, + 0x17, 0xdd, 0x03, 0x08, 0x55, 0xce, 0x73, 0x7f, 0x45, 0x90, 0xe6, 0xf7, 0x71, 0xd1, 0x2e, 0x54, + 0xfd, 0x1a, 0x69, 0xce, 0xaf, 0x01, 0xd2, 0xbc, 0x96, 0x2a, 0x7a, 0x0f, 0x6a, 0xd1, 0xf2, 0x60, + 0x91, 0x0b, 0x7f, 0x69, 0xa1, 0x5e, 0x29, 0xd1, 0x1d, 0xad, 0x14, 0x16, 0xb9, 0xfe, 0x97, 0x16, + 0x6a, 0x9c, 0xa2, 0x13, 0x58, 0xbd, 0x88, 0xe3, 0x17, 0xfd, 0x17, 0x40, 0x5a, 0xb8, 0x91, 0x8a, + 0x0c, 0x40, 0x09, 0xd8, 0x7f, 0xe1, 0x1f, 0x03, 0xa4, 0xc5, 0xbb, 0xaa, 0xe8, 0x43, 0xa8, 0xc7, + 0xe0, 0xf4, 0x42, 0x7f, 0x09, 0x48, 0x8b, 0x75, 0x57, 0xd1, 0x3b, 0xb0, 0x1c, 0xc1, 0xdf, 0x0b, + 0xfc, 0x32, 0x20, 0x2d, 0xd2, 0x67, 0xdd, 0x7e, 0xf5, 0x8b, 0xaf, 0xd7, 0x85, 0x2f, 0xbf, 0x5e, + 0x17, 0xfe, 0xfc, 0xf5, 0xba, 0xf0, 0xd9, 0x83, 0xf5, 0xdc, 0x97, 0x0f, 0xd6, 0x73, 0x7f, 0x7c, + 0xb0, 0x9e, 0x7b, 0xef, 0xc6, 0xd0, 0x70, 0x47, 0xb3, 0xfe, 0xa6, 0x6e, 0x4d, 0xb6, 0xc6, 0x86, + 0x89, 0xb7, 0x12, 0xfe, 0xe7, 0xea, 0x97, 0x69, 0x72, 0xbc, 0xfd, 0x9f, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xce, 0x35, 0xbc, 0x15, 0xed, 0x25, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3411,6 +3651,8 @@ type ABCIApplicationClient interface { 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) + BeginRecheckTx(ctx context.Context, in *RequestBeginRecheckTx, opts ...grpc.CallOption) (*ResponseBeginRecheckTx, error) + EndRecheckTx(ctx context.Context, in *RequestEndRecheckTx, opts ...grpc.CallOption) (*ResponseEndRecheckTx, error) } type aBCIApplicationClient struct { @@ -3556,6 +3798,24 @@ func (c *aBCIApplicationClient) ApplySnapshotChunk(ctx context.Context, in *Requ return out, nil } +func (c *aBCIApplicationClient) BeginRecheckTx(ctx context.Context, in *RequestBeginRecheckTx, opts ...grpc.CallOption) (*ResponseBeginRecheckTx, error) { + out := new(ResponseBeginRecheckTx) + err := c.cc.Invoke(ctx, "/ostracon.abci.ABCIApplication/BeginRecheckTx", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *aBCIApplicationClient) EndRecheckTx(ctx context.Context, in *RequestEndRecheckTx, opts ...grpc.CallOption) (*ResponseEndRecheckTx, error) { + out := new(ResponseEndRecheckTx) + err := c.cc.Invoke(ctx, "/ostracon.abci.ABCIApplication/EndRecheckTx", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // ABCIApplicationServer is the server API for ABCIApplication service. type ABCIApplicationServer interface { Echo(context.Context, *RequestEcho) (*ResponseEcho, error) @@ -3573,6 +3833,8 @@ type ABCIApplicationServer interface { OfferSnapshot(context.Context, *RequestOfferSnapshot) (*ResponseOfferSnapshot, error) LoadSnapshotChunk(context.Context, *RequestLoadSnapshotChunk) (*ResponseLoadSnapshotChunk, error) ApplySnapshotChunk(context.Context, *RequestApplySnapshotChunk) (*ResponseApplySnapshotChunk, error) + BeginRecheckTx(context.Context, *RequestBeginRecheckTx) (*ResponseBeginRecheckTx, error) + EndRecheckTx(context.Context, *RequestEndRecheckTx) (*ResponseEndRecheckTx, error) } // UnimplementedABCIApplicationServer can be embedded to have forward compatible implementations. @@ -3624,6 +3886,12 @@ func (*UnimplementedABCIApplicationServer) LoadSnapshotChunk(ctx context.Context func (*UnimplementedABCIApplicationServer) ApplySnapshotChunk(ctx context.Context, req *RequestApplySnapshotChunk) (*ResponseApplySnapshotChunk, error) { return nil, status.Errorf(codes.Unimplemented, "method ApplySnapshotChunk not implemented") } +func (*UnimplementedABCIApplicationServer) BeginRecheckTx(ctx context.Context, req *RequestBeginRecheckTx) (*ResponseBeginRecheckTx, error) { + return nil, status.Errorf(codes.Unimplemented, "method BeginRecheckTx not implemented") +} +func (*UnimplementedABCIApplicationServer) EndRecheckTx(ctx context.Context, req *RequestEndRecheckTx) (*ResponseEndRecheckTx, error) { + return nil, status.Errorf(codes.Unimplemented, "method EndRecheckTx not implemented") +} func RegisterABCIApplicationServer(s *grpc.Server, srv ABCIApplicationServer) { s.RegisterService(&_ABCIApplication_serviceDesc, srv) @@ -3899,6 +4167,42 @@ func _ABCIApplication_ApplySnapshotChunk_Handler(srv interface{}, ctx context.Co return interceptor(ctx, in, info, handler) } +func _ABCIApplication_BeginRecheckTx_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RequestBeginRecheckTx) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ABCIApplicationServer).BeginRecheckTx(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ostracon.abci.ABCIApplication/BeginRecheckTx", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ABCIApplicationServer).BeginRecheckTx(ctx, req.(*RequestBeginRecheckTx)) + } + return interceptor(ctx, in, info, handler) +} + +func _ABCIApplication_EndRecheckTx_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RequestEndRecheckTx) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ABCIApplicationServer).EndRecheckTx(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ostracon.abci.ABCIApplication/EndRecheckTx", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ABCIApplicationServer).EndRecheckTx(ctx, req.(*RequestEndRecheckTx)) + } + return interceptor(ctx, in, info, handler) +} + var _ABCIApplication_serviceDesc = grpc.ServiceDesc{ ServiceName: "ostracon.abci.ABCIApplication", HandlerType: (*ABCIApplicationServer)(nil), @@ -3963,6 +4267,14 @@ var _ABCIApplication_serviceDesc = grpc.ServiceDesc{ MethodName: "ApplySnapshotChunk", Handler: _ABCIApplication_ApplySnapshotChunk_Handler, }, + { + MethodName: "BeginRecheckTx", + Handler: _ABCIApplication_BeginRecheckTx_Handler, + }, + { + MethodName: "EndRecheckTx", + Handler: _ABCIApplication_EndRecheckTx_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "ostracon/abci/types.proto", @@ -4315,22 +4627,68 @@ func (m *Request_ApplySnapshotChunk) MarshalToSizedBuffer(dAtA []byte) (int, err } return len(dAtA) - i, nil } -func (m *RequestEcho) Marshal() (dAtA []byte, err error) { +func (m *Request_BeginRecheckTx) MarshalTo(dAtA []byte) (int, error) { size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil + return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *RequestEcho) MarshalTo(dAtA []byte) (int, error) { +func (m *Request_BeginRecheckTx) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.BeginRecheckTx != nil { + { + size, err := m.BeginRecheckTx.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x6 + i-- + dAtA[i] = 0xa2 + } + return len(dAtA) - i, nil +} +func (m *Request_EndRecheckTx) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *RequestEcho) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *Request_EndRecheckTx) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.EndRecheckTx != nil { + { + size, err := m.EndRecheckTx.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x6 + i-- + dAtA[i] = 0xaa + } + return len(dAtA) - i, nil +} +func (m *RequestEcho) 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 *RequestEcho) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RequestEcho) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -4510,12 +4868,12 @@ func (m *RequestInitChain) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x12 } - n17, err17 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) - if err17 != nil { - return 0, err17 + n19, err19 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) + if err19 != nil { + return 0, err19 } - i -= n17 - i = encodeVarintTypes(dAtA, i, uint64(n17)) + i -= n19 + i = encodeVarintTypes(dAtA, i, uint64(n19)) i-- dAtA[i] = 0xa return len(dAtA) - i, nil @@ -4898,6 +5256,67 @@ func (m *RequestApplySnapshotChunk) MarshalToSizedBuffer(dAtA []byte) (int, erro return len(dAtA) - i, nil } +func (m *RequestBeginRecheckTx) 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 *RequestBeginRecheckTx) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RequestBeginRecheckTx) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Header.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 *RequestEndRecheckTx) 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 *RequestEndRecheckTx) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RequestEndRecheckTx) 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 *Response) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -5268,6 +5687,52 @@ func (m *Response_ApplySnapshotChunk) MarshalToSizedBuffer(dAtA []byte) (int, er } return len(dAtA) - i, nil } +func (m *Response_BeginRecheckTx) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Response_BeginRecheckTx) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.BeginRecheckTx != nil { + { + size, err := m.BeginRecheckTx.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x6 + i-- + dAtA[i] = 0xa2 + } + return len(dAtA) - i, nil +} +func (m *Response_EndRecheckTx) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Response_EndRecheckTx) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.EndRecheckTx != nil { + { + size, err := m.EndRecheckTx.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x6 + i-- + dAtA[i] = 0xaa + } + return len(dAtA) - i, nil +} func (m *ResponseException) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -6008,20 +6473,20 @@ func (m *ResponseApplySnapshotChunk) MarshalToSizedBuffer(dAtA []byte) (int, err } } if len(m.RefetchChunks) > 0 { - dAtA41 := make([]byte, len(m.RefetchChunks)*10) - var j40 int + dAtA46 := make([]byte, len(m.RefetchChunks)*10) + var j45 int for _, num := range m.RefetchChunks { for num >= 1<<7 { - dAtA41[j40] = uint8(uint64(num)&0x7f | 0x80) + dAtA46[j45] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j40++ + j45++ } - dAtA41[j40] = uint8(num) - j40++ + dAtA46[j45] = uint8(num) + j45++ } - i -= j40 - copy(dAtA[i:], dAtA41[:j40]) - i = encodeVarintTypes(dAtA, i, uint64(j40)) + i -= j45 + copy(dAtA[i:], dAtA46[:j45]) + i = encodeVarintTypes(dAtA, i, uint64(j45)) i-- dAtA[i] = 0x12 } @@ -6033,6 +6498,62 @@ func (m *ResponseApplySnapshotChunk) MarshalToSizedBuffer(dAtA []byte) (int, err return len(dAtA) - i, nil } +func (m *ResponseBeginRecheckTx) 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 *ResponseBeginRecheckTx) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResponseBeginRecheckTx) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Code != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Code)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *ResponseEndRecheckTx) 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 *ResponseEndRecheckTx) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResponseEndRecheckTx) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Code != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Code)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func (m *ConsensusParams) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -6468,12 +6989,12 @@ func (m *Evidence) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x28 } - n49, err49 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) - if err49 != nil { - return 0, err49 + n54, err54 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) + if err54 != nil { + return 0, err54 } - i -= n49 - i = encodeVarintTypes(dAtA, i, uint64(n49)) + i -= n54 + i = encodeVarintTypes(dAtA, i, uint64(n54)) i-- dAtA[i] = 0x22 if m.Height != 0 { @@ -6754,6 +7275,30 @@ func (m *Request_ApplySnapshotChunk) Size() (n int) { } return n } +func (m *Request_BeginRecheckTx) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.BeginRecheckTx != nil { + l = m.BeginRecheckTx.Size() + n += 2 + l + sovTypes(uint64(l)) + } + return n +} +func (m *Request_EndRecheckTx) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.EndRecheckTx != nil { + l = m.EndRecheckTx.Size() + n += 2 + l + sovTypes(uint64(l)) + } + return n +} func (m *RequestEcho) Size() (n int) { if m == nil { return 0 @@ -7004,6 +7549,29 @@ func (m *RequestApplySnapshotChunk) Size() (n int) { return n } +func (m *RequestBeginRecheckTx) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Header.Size() + n += 1 + l + sovTypes(uint64(l)) + return n +} + +func (m *RequestEndRecheckTx) 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 *Response) Size() (n int) { if m == nil { return 0 @@ -7208,6 +7776,30 @@ func (m *Response_ApplySnapshotChunk) Size() (n int) { } return n } +func (m *Response_BeginRecheckTx) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.BeginRecheckTx != nil { + l = m.BeginRecheckTx.Size() + n += 2 + l + sovTypes(uint64(l)) + } + return n +} +func (m *Response_EndRecheckTx) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.EndRecheckTx != nil { + l = m.EndRecheckTx.Size() + n += 2 + l + sovTypes(uint64(l)) + } + return n +} func (m *ResponseException) Size() (n int) { if m == nil { return 0 @@ -7556,6 +8148,30 @@ func (m *ResponseApplySnapshotChunk) Size() (n int) { return n } +func (m *ResponseBeginRecheckTx) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Code != 0 { + n += 1 + sovTypes(uint64(m.Code)) + } + return n +} + +func (m *ResponseEndRecheckTx) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Code != 0 { + n += 1 + sovTypes(uint64(m.Code)) + } + return n +} + func (m *ConsensusParams) Size() (n int) { if m == nil { return 0 @@ -8329,14 +8945,84 @@ func (m *Request) Unmarshal(dAtA []byte) error { } m.Value = &Request_ApplySnapshotChunk{v} iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipTypes(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTypes + case 100: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BeginRecheckTx", 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 := &RequestBeginRecheckTx{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &Request_BeginRecheckTx{v} + iNdEx = postIndex + case 101: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EndRecheckTx", 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 := &RequestEndRecheckTx{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &Request_EndRecheckTx{v} + 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 @@ -10011,6 +10697,158 @@ func (m *RequestApplySnapshotChunk) Unmarshal(dAtA []byte) error { } return nil } +func (m *RequestBeginRecheckTx) 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: RequestBeginRecheckTx: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RequestBeginRecheckTx: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + 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 + 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 *RequestEndRecheckTx) 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: RequestEndRecheckTx: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RequestEndRecheckTx: 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 *Response) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -10600,6 +11438,76 @@ func (m *Response) Unmarshal(dAtA []byte) error { } m.Value = &Response_ApplySnapshotChunk{v} iNdEx = postIndex + case 100: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BeginRecheckTx", 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 := &ResponseBeginRecheckTx{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &Response_BeginRecheckTx{v} + iNdEx = postIndex + case 101: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EndRecheckTx", 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 := &ResponseEndRecheckTx{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Value = &Response_EndRecheckTx{v} + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -12912,6 +13820,144 @@ func (m *ResponseApplySnapshotChunk) Unmarshal(dAtA []byte) error { } return nil } +func (m *ResponseBeginRecheckTx) 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: ResponseBeginRecheckTx: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResponseBeginRecheckTx: 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 + } + } + 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 *ResponseEndRecheckTx) 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: ResponseEndRecheckTx: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResponseEndRecheckTx: 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 + } + } + 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 *ConsensusParams) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/blockchain/v0/reactor.go b/blockchain/v0/reactor.go index 70f87339c..cb22e60f5 100644 --- a/blockchain/v0/reactor.go +++ b/blockchain/v0/reactor.go @@ -401,7 +401,7 @@ FOR_LOOP: // TODO: same thing for app - but we would need a way to // get the hash without persisting the state var err error - state, _, err = bcR.blockExec.ApplyBlock(state, firstID, first) + state, _, err = bcR.blockExec.ApplyBlock(state, firstID, first, nil) if err != nil { // TODO This is bad, are we zombie? panic(fmt.Sprintf("Failed to process committed block (%d:%X): %v", first.Height, first.Hash(), err)) diff --git a/blockchain/v0/reactor_test.go b/blockchain/v0/reactor_test.go index 1453ec84f..ce5c2da93 100644 --- a/blockchain/v0/reactor_test.go +++ b/blockchain/v0/reactor_test.go @@ -7,11 +7,10 @@ import ( "testing" "time" + "github.com/line/tm-db/v2/memdb" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - dbm "github.com/tendermint/tm-db" - abci "github.com/line/ostracon/abci/types" cfg "github.com/line/ostracon/config" "github.com/line/ostracon/libs/log" @@ -70,8 +69,8 @@ func newBlockchainReactor( panic(fmt.Errorf("error start app: %w", err)) } - blockDB := dbm.NewMemDB() - stateDB := dbm.NewMemDB() + blockDB := memdb.NewDB() + stateDB := memdb.NewDB() stateStore := sm.NewStore(stateDB) blockStore := store.NewBlockStore(blockDB) @@ -84,7 +83,7 @@ func newBlockchainReactor( // NOTE we have to create and commit the blocks first because // pool.height is determined from the store. fastSync := true - db := dbm.NewMemDB() + db := memdb.NewDB() stateStore = sm.NewStore(db) blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyApp.Consensus(), mock.Mempool{}, sm.EmptyEvidencePool{}) @@ -119,7 +118,7 @@ func newBlockchainReactor( thisParts := thisBlock.MakePartSet(types.BlockPartSizeBytes) blockID := types.BlockID{Hash: thisBlock.Hash(), PartSetHeader: thisParts.Header()} - state, _, err = blockExec.ApplyBlock(state, blockID, thisBlock) + state, _, err = blockExec.ApplyBlock(state, blockID, thisBlock, nil) if err != nil { panic(fmt.Errorf("error apply block: %w", err)) } @@ -333,10 +332,14 @@ func (app *testApp) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx return abci.ResponseDeliverTx{Events: []abci.Event{}} } -func (app *testApp) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx { +func (app *testApp) CheckTxSync(req abci.RequestCheckTx) abci.ResponseCheckTx { return abci.ResponseCheckTx{} } +func (app *testApp) CheckTxAsync(req abci.RequestCheckTx, callback abci.CheckTxCallback) { + callback(abci.ResponseCheckTx{}) +} + func (app *testApp) Commit() abci.ResponseCommit { return abci.ResponseCommit{} } diff --git a/blockchain/v1/reactor.go b/blockchain/v1/reactor.go index 97241940d..0c9a0b495 100644 --- a/blockchain/v1/reactor.go +++ b/blockchain/v1/reactor.go @@ -488,7 +488,7 @@ func (bcR *BlockchainReactor) processBlock() error { bcR.store.SaveBlock(first, firstParts, second.LastCommit) - bcR.state, _, err = bcR.blockExec.ApplyBlock(bcR.state, firstID, first) + bcR.state, _, err = bcR.blockExec.ApplyBlock(bcR.state, firstID, first, nil) if err != nil { panic(fmt.Sprintf("failed to process committed block (%d:%X): %v", first.Height, first.Hash(), err)) } diff --git a/blockchain/v1/reactor_test.go b/blockchain/v1/reactor_test.go index cb8f28ec3..d26c0295c 100644 --- a/blockchain/v1/reactor_test.go +++ b/blockchain/v1/reactor_test.go @@ -8,11 +8,10 @@ import ( "testing" "time" + "github.com/line/tm-db/v2/memdb" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - dbm "github.com/tendermint/tm-db" - abci "github.com/line/ostracon/abci/types" cfg "github.com/line/ostracon/config" "github.com/line/ostracon/libs/log" @@ -100,8 +99,8 @@ func newBlockchainReactor( panic(fmt.Errorf("error start app: %w", err)) } - blockDB := dbm.NewMemDB() - stateDB := dbm.NewMemDB() + blockDB := memdb.NewDB() + stateDB := memdb.NewDB() stateStore := sm.NewStore(stateDB) blockStore := store.NewBlockStore(blockDB) @@ -114,7 +113,7 @@ func newBlockchainReactor( // NOTE we have to create and commit the blocks first because // pool.height is determined from the store. fastSync := true - db := dbm.NewMemDB() + db := memdb.NewDB() stateStore = sm.NewStore(db) blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyApp.Consensus(), mock.Mempool{}, sm.EmptyEvidencePool{}) @@ -138,7 +137,7 @@ func newBlockchainReactor( thisParts := thisBlock.MakePartSet(types.BlockPartSizeBytes) blockID := types.BlockID{Hash: thisBlock.Hash(), PartSetHeader: thisParts.Header()} - state, _, err = blockExec.ApplyBlock(state, blockID, thisBlock) + state, _, err = blockExec.ApplyBlock(state, blockID, thisBlock, nil) if err != nil { panic(fmt.Errorf("error apply block: %w", err)) } diff --git a/blockchain/v2/processor_context.go b/blockchain/v2/processor_context.go index dbfad04e4..156074a63 100644 --- a/blockchain/v2/processor_context.go +++ b/blockchain/v2/processor_context.go @@ -30,7 +30,7 @@ func newProcessorContext(st blockStore, ex blockApplier, s state.State) *pContex } func (pc *pContext) applyBlock(blockID types.BlockID, block *types.Block) error { - newState, _, err := pc.applier.ApplyBlock(pc.state, blockID, block) + newState, _, err := pc.applier.ApplyBlock(pc.state, blockID, block, nil) pc.state = newState return err } diff --git a/blockchain/v2/reactor.go b/blockchain/v2/reactor.go index ad8dcfeaa..30c860d9a 100644 --- a/blockchain/v2/reactor.go +++ b/blockchain/v2/reactor.go @@ -53,7 +53,8 @@ type blockVerifier interface { } type blockApplier interface { - ApplyBlock(state state.State, blockID types.BlockID, block *types.Block) (state.State, int64, error) + ApplyBlock(state state.State, blockID types.BlockID, block *types.Block, times *state.CommitStepTimes) (state.State, + int64, error) } // XXX: unify naming in this package around tmState diff --git a/blockchain/v2/reactor_test.go b/blockchain/v2/reactor_test.go index b7ae49d3f..3cf94c1b0 100644 --- a/blockchain/v2/reactor_test.go +++ b/blockchain/v2/reactor_test.go @@ -9,10 +9,6 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - dbm "github.com/tendermint/tm-db" - abci "github.com/line/ostracon/abci/types" "github.com/line/ostracon/behaviour" bc "github.com/line/ostracon/blockchain" @@ -28,6 +24,9 @@ import ( "github.com/line/ostracon/store" "github.com/line/ostracon/types" tmtime "github.com/line/ostracon/types/time" + "github.com/line/tm-db/v2/memdb" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) type mockPeer struct { @@ -83,7 +82,7 @@ type mockBlockApplier struct { // XXX: Add whitelist/blacklist? func (mba *mockBlockApplier) ApplyBlock( - state sm.State, blockID types.BlockID, block *types.Block, + state sm.State, blockID types.BlockID, block *types.Block, times *sm.CommitStepTimes, ) (sm.State, int64, error) { state.LastBlockHeight++ return state, 0, nil @@ -157,7 +156,7 @@ func newTestReactor(p testReactorParams) *BlockchainReactor { if err != nil { panic(fmt.Errorf("error start app: %w", err)) } - db := dbm.NewMemDB() + db := memdb.NewDB() stateStore := sm.NewStore(db) appl = sm.NewBlockExecutor(stateStore, p.logger, proxyApp.Consensus(), mock.Mempool{}, sm.EmptyEvidencePool{}) if err = stateStore.Save(state); err != nil { @@ -503,15 +502,15 @@ func newReactorStore( panic(fmt.Errorf("error start app: %w", err)) } - stateDB := dbm.NewMemDB() - blockStore := store.NewBlockStore(dbm.NewMemDB()) + stateDB := memdb.NewDB() + blockStore := store.NewBlockStore(memdb.NewDB()) stateStore := sm.NewStore(stateDB) state, err := stateStore.LoadFromDBOrGenesisDoc(genDoc) if err != nil { panic(fmt.Errorf("error constructing state from genesis file: %w", err)) } - db := dbm.NewMemDB() + db := memdb.NewDB() stateStore = sm.NewStore(db) blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyApp.Consensus(), mock.Mempool{}, sm.EmptyEvidencePool{}) @@ -545,7 +544,7 @@ func newReactorStore( thisParts := thisBlock.MakePartSet(types.BlockPartSizeBytes) blockID := types.BlockID{Hash: thisBlock.Hash(), PartSetHeader: thisParts.Header()} - state, _, err = blockExec.ApplyBlock(state, blockID, thisBlock) + state, _, err = blockExec.ApplyBlock(state, blockID, thisBlock, nil) if err != nil { panic(fmt.Errorf("error apply block: %w", err)) } diff --git a/cmd/ostracon/commands/debug/debug.go b/cmd/ostracon/commands/debug/debug.go index 187b2a600..d421438ad 100644 --- a/cmd/ostracon/commands/debug/debug.go +++ b/cmd/ostracon/commands/debug/debug.go @@ -17,7 +17,7 @@ var ( flagProfAddr = "pprof-laddr" flagFrequency = "frequency" - logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout)) + logger = log.NewOCLogger(log.NewSyncWriter(os.Stdout)) ) // DebugCmd defines the root command containing subcommands that assist in diff --git a/cmd/ostracon/commands/light.go b/cmd/ostracon/commands/light.go index d8f38b057..14cf6fd71 100644 --- a/cmd/ostracon/commands/light.go +++ b/cmd/ostracon/commands/light.go @@ -12,9 +12,10 @@ import ( "strings" "time" + "github.com/line/tm-db/v2/goleveldb" "github.com/spf13/cobra" - dbm "github.com/tendermint/tm-db" + dbm "github.com/line/tm-db/v2" "github.com/line/ostracon/crypto/merkle" "github.com/line/ostracon/libs/log" @@ -105,7 +106,7 @@ func init() { func runProxy(cmd *cobra.Command, args []string) error { // Initialise logger. - logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) + logger := log.NewOCLogger(log.NewSyncWriter(os.Stdout)) var option log.Option if verbose { option, _ = log.AllowLevel("debug") @@ -122,7 +123,7 @@ func runProxy(cmd *cobra.Command, args []string) error { witnessesAddrs = strings.Split(witnessAddrsJoined, ",") } - db, err := dbm.NewGoLevelDB("light-client-db", home) + db, err := goleveldb.NewDB("light-client-db", home) if err != nil { return fmt.Errorf("can't create a db: %w", err) } diff --git a/cmd/ostracon/commands/root.go b/cmd/ostracon/commands/root.go index 7b08e273a..c585e6891 100644 --- a/cmd/ostracon/commands/root.go +++ b/cmd/ostracon/commands/root.go @@ -16,7 +16,7 @@ import ( var ( config = cfg.DefaultConfig() - logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout)) + logger = log.NewOCLogger(log.NewSyncWriter(os.Stdout)) ) func init() { @@ -58,7 +58,7 @@ var RootCmd = &cobra.Command{ } if config.LogFormat == cfg.LogFormatJSON { - logger = log.NewTMJSONLogger(log.NewSyncWriter(os.Stdout)) + logger = log.NewOCJSONLogger(log.NewSyncWriter(os.Stdout)) } logger, err = tmflags.ParseLogLevel(config.LogLevel, logger, cfg.DefaultLogLevel) diff --git a/cmd/ostracon/commands/root_test.go b/cmd/ostracon/commands/root_test.go index b040d4924..a91540b39 100644 --- a/cmd/ostracon/commands/root_test.go +++ b/cmd/ostracon/commands/root_test.go @@ -24,10 +24,10 @@ var ( // clearConfig clears env vars, the given root dir, and resets viper. func clearConfig(dir string) { - if err := os.Unsetenv("TMHOME"); err != nil { + if err := os.Unsetenv("OCHOME"); err != nil { panic(err) } - if err := os.Unsetenv("TM_HOME"); err != nil { + if err := os.Unsetenv("OC_HOME"); err != nil { panic(err) } @@ -55,7 +55,7 @@ func testSetup(rootDir string, args []string, env map[string]string) error { clearConfig(defaultRoot) rootCmd := testRootCmd() - cmd := cli.PrepareBaseCmd(rootCmd, "TM", defaultRoot) + cmd := cli.PrepareBaseCmd(rootCmd, "OC", defaultRoot) // run with the args and env args = append([]string{rootCmd.Use}, args...) @@ -71,7 +71,7 @@ func TestRootHome(t *testing.T) { }{ {nil, nil, defaultRoot}, {[]string{"--home", newRoot}, nil, newRoot}, - {nil, map[string]string{"TMHOME": newRoot}, newRoot}, + {nil, map[string]string{"OCHOME": newRoot}, newRoot}, } for i, tc := range cases { @@ -100,9 +100,9 @@ func TestRootFlagsEnv(t *testing.T) { }{ {[]string{"--log", "debug"}, nil, defaultLogLvl}, // wrong flag {[]string{"--log_level", "debug"}, nil, "debug"}, // right flag - {nil, map[string]string{"TM_LOW": "debug"}, defaultLogLvl}, // wrong env flag + {nil, map[string]string{"OC_LOW": "debug"}, defaultLogLvl}, // wrong env flag {nil, map[string]string{"MT_LOG_LEVEL": "debug"}, defaultLogLvl}, // wrong env prefix - {nil, map[string]string{"TM_LOG_LEVEL": "debug"}, "debug"}, // right env + {nil, map[string]string{"OC_LOG_LEVEL": "debug"}, "debug"}, // right env } for i, tc := range cases { @@ -131,7 +131,7 @@ func TestRootConfig(t *testing.T) { }{ {nil, nil, nonDefaultLogLvl}, // should load config {[]string{"--log_level=abc:info"}, nil, "abc:info"}, // flag over rides - {nil, map[string]string{"TM_LOG_LEVEL": "abc:info"}, "abc:info"}, // env over rides + {nil, map[string]string{"OC_LOG_LEVEL": "abc:info"}, "abc:info"}, // env over rides } for i, tc := range cases { @@ -149,7 +149,7 @@ func TestRootConfig(t *testing.T) { require.Nil(t, err) rootCmd := testRootCmd() - cmd := cli.PrepareBaseCmd(rootCmd, "TM", defaultRoot) + cmd := cli.PrepareBaseCmd(rootCmd, "OC", defaultRoot) // run with the args and env tc.args = append([]string{rootCmd.Use}, tc.args...) diff --git a/cmd/ostracon/main.go b/cmd/ostracon/main.go index d1ed360ae..17736aaf6 100644 --- a/cmd/ostracon/main.go +++ b/cmd/ostracon/main.go @@ -44,7 +44,7 @@ func main() { rootCmd.AddCommand(cmd.NewInitCmd()) rootCmd.AddCommand(cmd.NewRunNodeCmd(nodeFunc)) - cmd := cli.PrepareBaseCmd(rootCmd, "TM", os.ExpandEnv(filepath.Join("$HOME", cfg.DefaultOstraconDir))) + cmd := cli.PrepareBaseCmd(rootCmd, "OC", os.ExpandEnv(filepath.Join("$HOME", cfg.DefaultOstraconDir))) if err := cmd.Execute(); err != nil { panic(err) } diff --git a/cmd/priv_val_server/main.go b/cmd/priv_val_server/main.go index ad48b28f9..3aa99e52a 100644 --- a/cmd/priv_val_server/main.go +++ b/cmd/priv_val_server/main.go @@ -20,7 +20,7 @@ func main() { privValKeyPath = flag.String("priv-key", "", "priv val key file path") privValStatePath = flag.String("priv-state", "", "priv val state file path") - logger = log.NewTMLogger( + logger = log.NewOCLogger( log.NewSyncWriter(os.Stdout), ).With("module", "priv_val") ) diff --git a/config/config.go b/config/config.go index 2d19d363d..a8325775d 100644 --- a/config/config.go +++ b/config/config.go @@ -10,6 +10,7 @@ import ( "time" "github.com/line/ostracon/privval" + "github.com/line/tm-db/v2/metadb" ) const ( @@ -25,6 +26,8 @@ const ( // DefaultLogLevel defines a default log level as INFO. DefaultLogLevel = "info" + + DefaultDBBackend = "goleveldb" ) // NOTE: Most of the structs & relevant comments + the @@ -56,7 +59,7 @@ var ( defaultAddrBookPath = filepath.Join(defaultConfigDir, defaultAddrBookName) ) -// Config defines the top level configuration for a Tendermint node +// Config defines the top level configuration for an Ostracon node type Config struct { // Top level options use an anonymous struct BaseConfig `mapstructure:",squash"` @@ -72,7 +75,7 @@ type Config struct { Instrumentation *InstrumentationConfig `mapstructure:"instrumentation"` } -// DefaultConfig returns a default configuration for a Tendermint node +// DefaultConfig returns a default configuration for an Ostracon node func DefaultConfig() *Config { return &Config{ BaseConfig: DefaultBaseConfig(), @@ -145,7 +148,7 @@ func (cfg *Config) ValidateBasic() error { //----------------------------------------------------------------------------- // BaseConfig -// BaseConfig defines the base configuration for a Tendermint node +// BaseConfig defines the base configuration for an Ostracon node type BaseConfig struct { //nolint: maligned // chainID is unexposed and immutable but here for convenience chainID string @@ -155,7 +158,7 @@ type BaseConfig struct { //nolint: maligned RootDir string `mapstructure:"home"` // TCP or UNIX socket address of the ABCI application, - // or the name of an ABCI application compiled in with the Tendermint binary + // or the name of an ABCI application compiled in with the Ostracon binary ProxyApp string `mapstructure:"proxy_app"` // A custom human readable name for this node @@ -205,7 +208,7 @@ type BaseConfig struct { //nolint: maligned // Path to the JSON file containing the last sign state of a validator PrivValidatorState string `mapstructure:"priv_validator_state_file"` - // TCP or UNIX socket address for Tendermint to listen on for + // TCP or UNIX socket address for Ostracon to listen on for // connections from an external PrivValidator process PrivValidatorListenAddr string `mapstructure:"priv_validator_laddr"` @@ -223,8 +226,16 @@ type BaseConfig struct { //nolint: maligned PrivKeyType string `mapstructure:"priv_key_type"` } -// DefaultBaseConfig returns a default base configuration for a Tendermint node +// DefaultBaseConfig returns a default base configuration for an Ostracon node func DefaultBaseConfig() BaseConfig { + dbs := metadb.AvailableDBBackends() + defaultDBBackend := DefaultDBBackend + for _, b := range dbs { + defaultDBBackend = string(b) + if defaultDBBackend == DefaultDBBackend { + break + } + } return BaseConfig{ Genesis: defaultGenesisJSONPath, PrivValidatorKey: defaultPrivValKeyPath, @@ -237,13 +248,13 @@ func DefaultBaseConfig() BaseConfig { LogFormat: LogFormatPlain, FastSyncMode: true, FilterPeers: false, - DBBackend: "goleveldb", + DBBackend: defaultDBBackend, DBPath: "data", PrivKeyType: privval.PrivKeyTypeEd25519, } } -// TestBaseConfig returns a base configuration for testing a Tendermint node +// TestBaseConfig returns a base configuration for testing an Ostracon node func TestBaseConfig() BaseConfig { cfg := DefaultBaseConfig() cfg.chainID = "ostracon_test" @@ -300,7 +311,7 @@ func (cfg BaseConfig) ValidateBasic() error { //----------------------------------------------------------------------------- // RPCConfig -// RPCConfig defines the configuration options for the Tendermint RPC server +// RPCConfig defines the configuration options for the Ostracon RPC server type RPCConfig struct { RootDir string `mapstructure:"home"` @@ -342,6 +353,30 @@ type RPCConfig struct { // 1024 - 40 - 10 - 50 = 924 = ~900 MaxOpenConnections int `mapstructure:"max_open_connections"` + // mirrors http.Server#ReadTimeout + // ReadTimeout is the maximum duration for reading the entire + // request, including the body. + // + // Because ReadTimeout does not let Handlers make per-request + // decisions on each request body's acceptable deadline or + // upload rate, most users will prefer to use + // ReadHeaderTimeout. It is valid to use them both. + ReadTimeout time.Duration `mapstructure:"read_timeout"` + + // mirrors http.Server#WriteTimeout + // WriteTimeout is the maximum duration before timing out + // writes of the response. It is reset whenever a new + // request's header is read. Like ReadTimeout, it does not + // let Handlers make decisions on a per-request basis. + WriteTimeout time.Duration `mapstructure:"write_timeout"` + + // mirrors http.Server#IdleTimeout + // IdleTimeout is the maximum amount of time to wait for the + // next request when keep-alives are enabled. If IdleTimeout + // is zero, the value of ReadTimeout is used. If both are + // zero, there is no timeout. + IdleTimeout time.Duration `mapstructure:"idle_timeout"` + // Maximum number of unique clientIDs that can /subscribe // If you're using /broadcast_tx_commit, set to the estimated maximum number // of broadcast_tx_commit calls per block. @@ -353,7 +388,7 @@ type RPCConfig struct { MaxSubscriptionsPerClient int `mapstructure:"max_subscriptions_per_client"` // How long to wait for a tx to be committed during /broadcast_tx_commit - // WARNING: Using a value larger than 10s will result in increasing the + // WARNING: Using a value larger than 'WriteTimeout' will result in increasing the // global HTTP write timeout, which applies to all connections and endpoints. // See https://github.com/tendermint/tendermint/issues/3435 TimeoutBroadcastTxCommit time.Duration `mapstructure:"timeout_broadcast_tx_commit"` @@ -365,20 +400,20 @@ type RPCConfig struct { MaxHeaderBytes int `mapstructure:"max_header_bytes"` // The path to a file containing certificate that is used to create the HTTPS server. - // Might be either absolute path or path related to Tendermint's config directory. + // Might be either absolute path or path related to Ostracon's config directory. // // If the certificate is signed by a certificate authority, // the certFile should be the concatenation of the server's certificate, any intermediates, // and the CA's certificate. // - // NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. + // NOTE: both tls_cert_file and tls_key_file must be present for Ostracon to create HTTPS server. // Otherwise, HTTP server is run. TLSCertFile string `mapstructure:"tls_cert_file"` // The path to a file containing matching private key that is used to create the HTTPS server. - // Might be either absolute path or path related to tendermint's config directory. + // Might be either absolute path or path related to ostracon's config directory. // - // NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. + // NOTE: both tls_cert_file and tls_key_file must be present for Ostracon to create HTTPS server. // Otherwise, HTTP server is run. TLSKeyFile string `mapstructure:"tls_key_file"` @@ -398,6 +433,9 @@ func DefaultRPCConfig() *RPCConfig { Unsafe: false, MaxOpenConnections: 900, + ReadTimeout: 10 * time.Second, + WriteTimeout: 10 * time.Second, + IdleTimeout: 60 * time.Second, MaxSubscriptionClients: 100, MaxSubscriptionsPerClient: 5, @@ -429,6 +467,15 @@ func (cfg *RPCConfig) ValidateBasic() error { if cfg.MaxOpenConnections < 0 { return errors.New("max_open_connections can't be negative") } + if cfg.ReadTimeout < 0 { + return errors.New("read_timeout can't be negative") + } + if cfg.WriteTimeout < 0 { + return errors.New("write_timeout can't be negative") + } + if cfg.IdleTimeout < 0 { + return errors.New("idle_timeout can't be negative") + } if cfg.MaxSubscriptionClients < 0 { return errors.New("max_subscription_clients can't be negative") } @@ -475,7 +522,7 @@ func (cfg RPCConfig) IsTLSEnabled() bool { //----------------------------------------------------------------------------- // P2PConfig -// P2PConfig defines the configuration options for the Tendermint peer-to-peer networking layer +// P2PConfig defines the configuration options for the Ostracon peer-to-peer networking layer type P2PConfig struct { //nolint: maligned RootDir string `mapstructure:"home"` @@ -662,7 +709,7 @@ func DefaultFuzzConnConfig() *FuzzConnConfig { //----------------------------------------------------------------------------- // MempoolConfig -// MempoolConfig defines the configuration options for the Tendermint mempool +// MempoolConfig defines the configuration options for the Ostracon mempool type MempoolConfig struct { RootDir string `mapstructure:"home"` Recheck bool `mapstructure:"recheck"` @@ -689,7 +736,7 @@ type MempoolConfig struct { MaxBatchBytes int `mapstructure:"max_batch_bytes"` } -// DefaultMempoolConfig returns a default configuration for the Tendermint mempool +// DefaultMempoolConfig returns a default configuration for the Ostracon mempool func DefaultMempoolConfig() *MempoolConfig { return &MempoolConfig{ Recheck: true, @@ -704,7 +751,7 @@ func DefaultMempoolConfig() *MempoolConfig { } } -// TestMempoolConfig returns a configuration for testing the Tendermint mempool +// TestMempoolConfig returns a configuration for testing the Ostracon mempool func TestMempoolConfig() *MempoolConfig { cfg := DefaultMempoolConfig() cfg.CacheSize = 1000 @@ -742,7 +789,7 @@ func (cfg *MempoolConfig) ValidateBasic() error { //----------------------------------------------------------------------------- // StateSyncConfig -// StateSyncConfig defines the configuration for the Tendermint state sync service +// StateSyncConfig defines the configuration for the Ostracon state sync service type StateSyncConfig struct { Enable bool `mapstructure:"enable"` TempDir string `mapstructure:"temp_dir"` @@ -809,7 +856,7 @@ func (cfg *StateSyncConfig) ValidateBasic() error { //----------------------------------------------------------------------------- // FastSyncConfig -// FastSyncConfig defines the configuration for the Tendermint fast sync service +// FastSyncConfig defines the configuration for the Ostracon fast sync service type FastSyncConfig struct { Version string `mapstructure:"version"` } @@ -843,7 +890,7 @@ func (cfg *FastSyncConfig) ValidateBasic() error { //----------------------------------------------------------------------------- // ConsensusConfig -// ConsensusConfig defines the configuration for the Tendermint consensus service, +// ConsensusConfig defines the configuration for the Ostracon consensus service, // including timeouts and details about the WAL and the block structure. type ConsensusConfig struct { RootDir string `mapstructure:"home"` diff --git a/config/toml.go b/config/toml.go index 7764567e2..7ca6aa8c2 100644 --- a/config/toml.go +++ b/config/toml.go @@ -49,7 +49,7 @@ func EnsureRoot(rootDir string) { } } -// XXX: this func should probably be called by cmd/tendermint/commands/init.go +// XXX: this func should probably be called by cmd/ostracon/commands/init.go // alongside the writing of the genesis.json and priv_validator.json func writeDefaultConfigFile(configFilePath string) { WriteConfigFile(configFilePath, DefaultConfig()) @@ -73,7 +73,7 @@ const defaultConfigTemplate = `# This is a TOML config file. # NOTE: Any path below can be absolute (e.g. "/var/myawesomeapp/data") or # relative to the home directory (e.g. "data"). The home directory is -# "$HOME/.ostracon" by default, but could be changed via $TMHOME env variable +# "$HOME/.ostracon" by default, but could be changed via $OCHOME env variable # or --home cmd flag. ####################################################################### @@ -81,7 +81,7 @@ const defaultConfigTemplate = `# This is a TOML config file. ####################################################################### # TCP or UNIX socket address of the ABCI application, -# or the name of an ABCI application compiled in with the Tendermint binary +# or the name of an ABCI application compiled in with the Ostracon binary proxy_app = "{{ .BaseConfig.ProxyApp }}" # A custom human readable name for this node @@ -133,7 +133,7 @@ priv_validator_key_file = "{{ js .BaseConfig.PrivValidatorKey }}" # Path to the JSON file containing the last sign state of a validator priv_validator_state_file = "{{ js .BaseConfig.PrivValidatorState }}" -# TCP or UNIX socket address for Tendermint to listen on for +# TCP or UNIX socket address for Ostracon to listen on for # connections from an external PrivValidator process priv_validator_laddr = "{{ .BaseConfig.PrivValidatorListenAddr }}" @@ -196,6 +196,29 @@ unsafe = {{ .RPC.Unsafe }} # 1024 - 40 - 10 - 50 = 924 = ~900 max_open_connections = {{ .RPC.MaxOpenConnections }} +# mirrors http.Server#ReadTimeout +# ReadTimeout is the maximum duration for reading the entire +# request, including the body. +# Because ReadTimeout does not let Handlers make per-request +# decisions on each request body's acceptable deadline or +# upload rate, most users will prefer to use +# ReadHeaderTimeout. It is valid to use them both. +read_timeout = "{{ .RPC.ReadTimeout }}" + +# mirrors http.Server#WriteTimeout +# WriteTimeout is the maximum duration before timing out +# writes of the response. It is reset whenever a new +# request's header is read. Like ReadTimeout, it does not +# let Handlers make decisions on a per-request basis. +write_timeout = "{{ .RPC.WriteTimeout }}" + +# mirrors http.Server#IdleTimeout +# IdleTimeout is the maximum amount of time to wait for the +# next request when keep-alives are enabled. If IdleTimeout +# is zero, the value of ReadTimeout is used. If both are +# zero, there is no timeout. +idle_timeout = "{{ .RPC.IdleTimeout }}" + # Maximum number of unique clientIDs that can /subscribe # If you're using /broadcast_tx_commit, set to the estimated maximum number # of broadcast_tx_commit calls per block. @@ -207,7 +230,7 @@ max_subscription_clients = {{ .RPC.MaxSubscriptionClients }} max_subscriptions_per_client = {{ .RPC.MaxSubscriptionsPerClient }} # How long to wait for a tx to be committed during /broadcast_tx_commit. -# WARNING: Using a value larger than 10s will result in increasing the +# WARNING: Using a value larger than 'WriteTimeout' will result in increasing the # global HTTP write timeout, which applies to all connections and endpoints. # See https://github.com/line/ostracon/issues/3435 timeout_broadcast_tx_commit = "{{ .RPC.TimeoutBroadcastTxCommit }}" @@ -219,17 +242,17 @@ max_body_bytes = {{ .RPC.MaxBodyBytes }} max_header_bytes = {{ .RPC.MaxHeaderBytes }} # The path to a file containing certificate that is used to create the HTTPS server. -# Might be either absolute path or path related to Tendermint's config directory. +# Might be either absolute path or path related to Ostracon's config directory. # If the certificate is signed by a certificate authority, # the certFile should be the concatenation of the server's certificate, any intermediates, # and the CA's certificate. -# NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. +# NOTE: both tls_cert_file and tls_key_file must be present for Ostracon to create HTTPS server. # Otherwise, HTTP server is run. tls_cert_file = "{{ .RPC.TLSCertFile }}" # The path to a file containing matching private key that is used to create the HTTPS server. -# Might be either absolute path or path related to Tendermint's config directory. -# NOTE: both tls-cert-file and tls-key-file must be present for Tendermint to create HTTPS server. +# Might be either absolute path or path related to Ostracon's config directory. +# NOTE: both tls-cert-file and tls-key-file must be present for Ostracon to create HTTPS server. # Otherwise, HTTP server is run. tls_key_file = "{{ .RPC.TLSKeyFile }}" @@ -545,7 +568,7 @@ var testGenesisFmt = `{ "validators": [ { "pub_key": { - "type": "tendermint/PubKeyEd25519", + "type": "ostracon/PubKeyEd25519", "value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE=" }, "power": "10", @@ -563,11 +586,11 @@ var testGenesisFmt = `{ var testPrivValidatorKey = `{ "address": "A3258DCBF45DCA0DF052981870F2D1441A36D145", "pub_key": { - "type": "tendermint/PubKeyEd25519", + "type": "ostracon/PubKeyEd25519", "value": "AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE=" }, "priv_key": { - "type": "tendermint/PrivKeyEd25519", + "type": "ostracon/PrivKeyEd25519", "value": "EVkqJO/jIXp3rkASXfh9YnyToYXRXhBr6g9cQVxPFnQBP/5povV4HTjvsy530kybxKHwEi85iU8YL0qQhSYVoQ==" } }` diff --git a/consensus/byzantine_test.go b/consensus/byzantine_test.go index e2986ce29..1212f2c5e 100644 --- a/consensus/byzantine_test.go +++ b/consensus/byzantine_test.go @@ -9,13 +9,12 @@ import ( "testing" "time" + "github.com/line/tm-db/v2/memdb" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" config2 "github.com/line/ostracon/config" - dbm "github.com/tendermint/tm-db" - abcicli "github.com/line/ostracon/abci/client" abci "github.com/line/ostracon/abci/types" "github.com/line/ostracon/evidence" @@ -51,17 +50,17 @@ func TestByzantinePrevoteEquivocation(t *testing.T) { for i := 0; i < nValidators; i++ { logger := consensusLogger().With("test", "byzantine", "validator", i) - stateDB := dbm.NewMemDB() // each state needs its own db + stateDB := memdb.NewDB() // each state needs its own db stateStore := sm.NewStore(stateDB) state, _ := stateStore.LoadFromDBOrGenesisDoc(genDoc) thisConfig := ResetConfig(fmt.Sprintf("%s_%d", testName, i)) defer os.RemoveAll(thisConfig.RootDir) ensureDir(path.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal app := appFunc() - vals := types.TM2PB.ValidatorUpdates(state.Validators) + vals := types.OC2PB.ValidatorUpdates(state.Validators) app.InitChain(abci.RequestInitChain{Validators: vals}) - blockDB := dbm.NewMemDB() + blockDB := memdb.NewDB() blockStore := store.NewBlockStore(blockDB) // one for mempool, one for consensus @@ -77,7 +76,7 @@ func TestByzantinePrevoteEquivocation(t *testing.T) { } // Make a full instance of the evidence pool - evidenceDB := dbm.NewMemDB() + evidenceDB := memdb.NewDB() evpool, err := evidence.NewPool(evidenceDB, stateStore, blockStore) require.NoError(t, err) evpool.SetLogger(logger.With("module", "evidence")) diff --git a/consensus/common_test.go b/consensus/common_test.go index d171c60ba..18428f0a4 100644 --- a/consensus/common_test.go +++ b/consensus/common_test.go @@ -15,9 +15,10 @@ import ( "time" "github.com/go-kit/kit/log/term" + "github.com/line/tm-db/v2/memdb" "github.com/stretchr/testify/require" - dbm "github.com/tendermint/tm-db" + dbm "github.com/line/tm-db/v2" abcicli "github.com/line/ostracon/abci/client" "github.com/line/ostracon/abci/example/counter" @@ -385,7 +386,7 @@ func newStateWithConfig( pv types.PrivValidator, app abci.Application, ) *State { - blockDB := dbm.NewMemDB() + blockDB := memdb.NewDB() return newStateWithConfigAndBlockStore(thisConfig, state, pv, app, blockDB) } @@ -771,7 +772,7 @@ func randConsensusNet(nValidators int, testName string, tickerFunc func() Timeou logger := consensusLogger() configRootDirs := make([]string, 0, nValidators) for i := 0; i < nValidators; i++ { - stateDB := dbm.NewMemDB() // each state needs its own db + stateDB := memdb.NewDB() // each state needs its own db stateStore := sm.NewStore(stateDB) state, err := stateStore.LoadFromDBOrGenesisDoc(genDoc) if err != nil { @@ -786,7 +787,7 @@ 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) + vals := types.OC2PB.ValidatorUpdates(state.Validators) app.InitChain(abci.RequestInitChain{Validators: vals}) css[i] = newStateWithConfigAndBlockStore(thisConfig, state, privVals[i], app, stateDB) @@ -849,7 +850,7 @@ func createPeersAndValidators(nValidators, nPeers int, testName string, var peer0Config *cfg.Config configRootDirs := make([]string, 0, nPeers) for i := 0; i < nPeers; i++ { - stateDB := dbm.NewMemDB() // each state needs its own db + stateDB := memdb.NewDB() // each state needs its own db stateStore := sm.NewStore(stateDB) state, _ := stateStore.LoadFromDBOrGenesisDoc(genDoc) thisConfig := ResetConfig(fmt.Sprintf("%s_%d", testName, i)) @@ -875,7 +876,7 @@ func createPeersAndValidators(nValidators, nPeers int, testName string, } app := appFunc(path.Join(config.DBDir(), fmt.Sprintf("%s_%d", testName, i))) - vals := types.TM2PB.ValidatorUpdates(state.Validators) + vals := types.OC2PB.ValidatorUpdates(state.Validators) if _, ok := app.(*kvstore.PersistentKVStoreApplication); ok { // simulate handshake, receive app version. If don't do this, replay test will fail state.Version.Consensus.App = kvstore.ProtocolVersion diff --git a/consensus/mempool_test.go b/consensus/mempool_test.go index c7d84c5d3..b4b338172 100644 --- a/consensus/mempool_test.go +++ b/consensus/mempool_test.go @@ -4,14 +4,14 @@ import ( "encoding/binary" "fmt" "os" + "sync" "testing" "time" + "github.com/line/tm-db/v2/memdb" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - dbm "github.com/tendermint/tm-db" - "github.com/line/ostracon/abci/example/code" abci "github.com/line/ostracon/abci/types" mempl "github.com/line/ostracon/mempool" @@ -103,7 +103,7 @@ func deliverTxsRange(cs *State, start, end int) { 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{}) + _, err := assertMempool(cs.txNotifier).CheckTxSync(txBytes, mempl.TxInfo{}) if err != nil { panic(fmt.Sprintf("Error after CheckTx: %v", err)) } @@ -112,7 +112,7 @@ func deliverTxsRange(cs *State, start, end int) { func TestMempoolTxConcurrentWithCommit(t *testing.T) { state, privVals := randGenesisState(1, false, 10, nil) - blockDB := dbm.NewMemDB() + blockDB := memdb.NewDB() stateStore := sm.NewStore(blockDB) cs := newStateWithConfigAndBlockStore(config, state, privVals[0], NewCounterApplication(), blockDB) err := stateStore.Save(state) @@ -137,7 +137,7 @@ func TestMempoolTxConcurrentWithCommit(t *testing.T) { func TestMempoolRmBadTx(t *testing.T) { state, privVals := randGenesisState(1, false, 10, nil) app := NewCounterApplication() - blockDB := dbm.NewMemDB() + blockDB := memdb.NewDB() stateStore := sm.NewStore(blockDB) cs := newStateWithConfigAndBlockStore(config, state, privVals[0], app, blockDB) err := stateStore.Save(state) @@ -153,23 +153,32 @@ func TestMempoolRmBadTx(t *testing.T) { resCommit := app.Commit() assert.True(t, len(resCommit.Data) > 0) - emptyMempoolCh := make(chan struct{}) + resBeginRecheckTx := app.BeginRecheckTx(abci.RequestBeginRecheckTx{}) + assert.Equal(t, code.CodeTypeOK, resBeginRecheckTx.Code) + + // There is no tx to recheck + + resEndRecheckTx := app.EndRecheckTx(abci.RequestEndRecheckTx{}) + assert.Equal(t, code.CodeTypeOK, resEndRecheckTx.Code) + + checkTxErrorCh := make(chan error) checkTxRespCh := make(chan struct{}) + emptyMempoolCh := make(chan struct{}) go func() { // 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) { + assertMempool(cs.txNotifier).CheckTxAsync(txBytes, mempl.TxInfo{}, func(err error) { + checkTxErrorCh <- err + }, func(r *abci.Response) { if r.GetCheckTx().Code != code.CodeTypeBadNonce { t.Errorf("expected checktx to return bad nonce, got %v", r) return } checkTxRespCh <- struct{}{} - }, mempl.TxInfo{}) - if err != nil { - t.Errorf("error after CheckTx: %v", err) - return - } + }) + + <-checkTxErrorCh // check for the tx for { @@ -207,8 +216,9 @@ func TestMempoolRmBadTx(t *testing.T) { type CounterApplication struct { abci.BaseApplication - txCount int - mempoolTxCount int + txCount int + mempoolTxCount int + mempoolTxCountMtx sync.Mutex } func NewCounterApplication() *CounterApplication { @@ -230,8 +240,18 @@ func (app *CounterApplication) DeliverTx(req abci.RequestDeliverTx) abci.Respons return abci.ResponseDeliverTx{Code: code.CodeTypeOK} } -func (app *CounterApplication) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx { +func (app *CounterApplication) CheckTxSync(req abci.RequestCheckTx) abci.ResponseCheckTx { + return app.checkTx(req) +} + +func (app *CounterApplication) CheckTxAsync(req abci.RequestCheckTx, callback abci.CheckTxCallback) { + callback(app.checkTx(req)) +} + +func (app *CounterApplication) checkTx(req abci.RequestCheckTx) abci.ResponseCheckTx { txValue := txAsUint64(req.Tx) + app.mempoolTxCountMtx.Lock() + defer app.mempoolTxCountMtx.Unlock() if txValue != uint64(app.mempoolTxCount) { return abci.ResponseCheckTx{ Code: code.CodeTypeBadNonce, @@ -241,6 +261,11 @@ func (app *CounterApplication) CheckTx(req abci.RequestCheckTx) abci.ResponseChe return abci.ResponseCheckTx{Code: code.CodeTypeOK} } +func (app *CounterApplication) BeginRecheckTx(abci.RequestBeginRecheckTx) abci.ResponseBeginRecheckTx { + app.mempoolTxCount = app.txCount + return abci.ResponseBeginRecheckTx{Code: code.CodeTypeOK} +} + func txAsUint64(tx []byte) uint64 { tx8 := make([]byte, 8) copy(tx8[len(tx8)-len(tx):], tx) @@ -248,7 +273,6 @@ func txAsUint64(tx []byte) uint64 { } func (app *CounterApplication) Commit() abci.ResponseCommit { - app.mempoolTxCount = app.txCount if app.txCount == 0 { return abci.ResponseCommit{} } diff --git a/consensus/metrics.go b/consensus/metrics.go index ab275d0cd..68bd35417 100644 --- a/consensus/metrics.go +++ b/consensus/metrics.go @@ -48,7 +48,7 @@ type Metrics struct { ByzantineVotersPower metrics.Gauge // Time between this and the last block. - BlockIntervalSeconds metrics.Histogram + BlockIntervalSeconds metrics.Gauge // Number of transactions. NumTxs metrics.Gauge @@ -66,6 +66,10 @@ type Metrics struct { // Number of blockparts transmitted by peer. BlockParts metrics.Counter + // //////////////////////////////////// + // Metrics for measuring performance + // //////////////////////////////////// + // Number of blocks that are we couldn't receive MissingProposal metrics.Gauge @@ -73,16 +77,21 @@ type Metrics struct { RoundFailures metrics.Histogram // Execution time profiling of each step - ProposalCreating metrics.Histogram - ProposalWaiting metrics.Histogram - ProposalVerifying metrics.Histogram - ProposalBlockReceiving metrics.Histogram - PrevoteBlockVerifying metrics.Histogram - PrevoteReceiving metrics.Histogram - PrecommitBlockVerifying metrics.Histogram - PrecommitReceiving metrics.Histogram - CommitBlockVerifying metrics.Histogram - CommitBlockApplying metrics.Histogram + DurationProposal metrics.Histogram + DurationPrevote metrics.Histogram + DurationPrecommit metrics.Histogram + DurationCommitExecuting metrics.Histogram + DurationCommitCommitting metrics.Histogram + DurationCommitRechecking metrics.Histogram + DurationWaitingForNewRound metrics.Histogram + + DurationGaugeProposal metrics.Gauge + DurationGaugePrevote metrics.Gauge + DurationGaugePrecommit metrics.Gauge + DurationGaugeCommitExecuting metrics.Gauge + DurationGaugeCommitCommitting metrics.Gauge + DurationGaugeCommitRechecking metrics.Gauge + DurationGaugeWaitingForNewRound metrics.Gauge } // PrometheusMetrics returns Metrics build using Prometheus client library. @@ -173,7 +182,7 @@ func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics { Name: "byzantine_voters_power", Help: "Total power of the byzantine voters.", }, labels).With(labelsAndValues...), - BlockIntervalSeconds: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{ + BlockIntervalSeconds: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ Namespace: namespace, Subsystem: MetricsSubsystem, Name: "block_interval_seconds", @@ -234,75 +243,96 @@ func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics { Help: "Number of rounds failed on consensus", Buckets: stdprometheus.LinearBuckets(0, 1, 5), }, labels).With(labelsAndValues...), - ProposalCreating: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{ + DurationProposal: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{ + Namespace: namespace, + Subsystem: MetricsSubsystem, + Name: "duration_proposal", + Help: "Duration of proposal step", + Buckets: stdprometheus.LinearBuckets(100, 100, 10), + }, labels).With(labelsAndValues...), + DurationPrevote: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{ Namespace: namespace, Subsystem: MetricsSubsystem, - Name: "duration_proposal_creating", - Help: "Duration of creating proposal and block", + Name: "duration_prevote", + Help: "Duration of prevote step", Buckets: stdprometheus.LinearBuckets(100, 100, 10), }, labels).With(labelsAndValues...), - ProposalWaiting: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{ + DurationPrecommit: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{ Namespace: namespace, Subsystem: MetricsSubsystem, - Name: "duration_proposal_waiting", - Help: "Duration between enterNewRound and receiving proposal", + Name: "duration_precommit", + Help: "Duration of precommit step", Buckets: stdprometheus.LinearBuckets(100, 100, 10), }, labels).With(labelsAndValues...), - ProposalVerifying: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{ + DurationCommitExecuting: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{ Namespace: namespace, Subsystem: MetricsSubsystem, - Name: "duration_proposal_verifying", - Help: "Duration of ValidBlock", - Buckets: stdprometheus.LinearBuckets(50, 50, 10), + Name: "duration_commit_executing", + Help: "Duration of executing block txs", + Buckets: stdprometheus.LinearBuckets(100, 100, 10), }, labels).With(labelsAndValues...), - ProposalBlockReceiving: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{ + DurationCommitCommitting: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{ Namespace: namespace, Subsystem: MetricsSubsystem, - Name: "duration_proposal_block_receiving", - Help: "Duration of receiving all proposal block parts", + Name: "duration_commit_committing", + Help: "Duration of committing updated state", Buckets: stdprometheus.LinearBuckets(100, 100, 10), }, labels).With(labelsAndValues...), - PrevoteBlockVerifying: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{ + DurationCommitRechecking: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{ Namespace: namespace, Subsystem: MetricsSubsystem, - Name: "duration_prevote_block_verifying", - Help: "Duration of ValidBlock in prevote", - Buckets: stdprometheus.LinearBuckets(50, 50, 10), + Name: "duration_commit_rechecking", + Help: "Duration of rechecking mempool txs", + Buckets: stdprometheus.LinearBuckets(100, 100, 10), }, labels).With(labelsAndValues...), - PrevoteReceiving: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{ + DurationWaitingForNewRound: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{ Namespace: namespace, Subsystem: MetricsSubsystem, - Name: "duration_prevote_receiving", - Help: "Duration of receiving 2/3+ prevotes", + Name: "duration_waiting_for_new_round", + Help: "Duration of waiting for next new round", Buckets: stdprometheus.LinearBuckets(100, 100, 10), }, labels).With(labelsAndValues...), - PrecommitBlockVerifying: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{ + DurationGaugeProposal: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ Namespace: namespace, Subsystem: MetricsSubsystem, - Name: "duration_precommit_block_verifying", - Help: "Duration of ValidBlock in precommit", - Buckets: stdprometheus.LinearBuckets(50, 50, 10), + Name: "duration_gauge_proposal", + Help: "Duration of proposal step", }, labels).With(labelsAndValues...), - PrecommitReceiving: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{ + DurationGaugePrevote: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ Namespace: namespace, Subsystem: MetricsSubsystem, - Name: "duration_precommit_receiving", - Help: "Duration of receiving 2/3+ precommits", - Buckets: stdprometheus.LinearBuckets(100, 100, 10), + Name: "duration_gauge_prevote", + Help: "Duration of prevote step", }, labels).With(labelsAndValues...), - CommitBlockVerifying: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{ + DurationGaugePrecommit: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ Namespace: namespace, Subsystem: MetricsSubsystem, - Name: "duration_commit_block_verifying", - Help: "Duration of ValidBlock in commit", - Buckets: stdprometheus.LinearBuckets(50, 50, 10), + Name: "duration_gauge_precommit", + Help: "Duration of precommit step", }, labels).With(labelsAndValues...), - CommitBlockApplying: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{ + DurationGaugeCommitExecuting: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ Namespace: namespace, Subsystem: MetricsSubsystem, - Name: "duration_commit_block_applying", - Help: "Duration of applying block", - Buckets: stdprometheus.LinearBuckets(100, 100, 10), + Name: "duration_gauge_commit_executing", + Help: "Duration of executing block txs", + }, labels).With(labelsAndValues...), + DurationGaugeCommitCommitting: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: MetricsSubsystem, + Name: "duration_gauge_commit_committing", + Help: "Duration of committing updated state", + }, labels).With(labelsAndValues...), + DurationGaugeCommitRechecking: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: MetricsSubsystem, + Name: "duration_gauge_commit_rechecking", + Help: "Duration of rechecking mempool txs", + }, labels).With(labelsAndValues...), + DurationGaugeWaitingForNewRound: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: MetricsSubsystem, + Name: "duration_gauge_waiting_for_new_round", + Help: "Duration of waiting for next new round", }, labels).With(labelsAndValues...), } } @@ -327,7 +357,7 @@ func NopMetrics() *Metrics { ByzantineVoters: discard.NewGauge(), ByzantineVotersPower: discard.NewGauge(), - BlockIntervalSeconds: discard.NewHistogram(), + BlockIntervalSeconds: discard.NewGauge(), NumTxs: discard.NewGauge(), BlockSizeBytes: discard.NewGauge(), @@ -340,15 +370,20 @@ func NopMetrics() *Metrics { MissingProposal: discard.NewGauge(), RoundFailures: discard.NewHistogram(), - ProposalCreating: discard.NewHistogram(), - ProposalWaiting: discard.NewHistogram(), - ProposalVerifying: discard.NewHistogram(), - ProposalBlockReceiving: discard.NewHistogram(), - PrevoteBlockVerifying: discard.NewHistogram(), - PrevoteReceiving: discard.NewHistogram(), - PrecommitBlockVerifying: discard.NewHistogram(), - PrecommitReceiving: discard.NewHistogram(), - CommitBlockVerifying: discard.NewHistogram(), - CommitBlockApplying: discard.NewHistogram(), + DurationProposal: discard.NewHistogram(), + DurationPrevote: discard.NewHistogram(), + DurationPrecommit: discard.NewHistogram(), + DurationCommitExecuting: discard.NewHistogram(), + DurationCommitCommitting: discard.NewHistogram(), + DurationCommitRechecking: discard.NewHistogram(), + DurationWaitingForNewRound: discard.NewHistogram(), + + DurationGaugeProposal: discard.NewGauge(), + DurationGaugePrevote: discard.NewGauge(), + DurationGaugePrecommit: discard.NewGauge(), + DurationGaugeCommitExecuting: discard.NewGauge(), + DurationGaugeCommitCommitting: discard.NewGauge(), + DurationGaugeCommitRechecking: discard.NewGauge(), + DurationGaugeWaitingForNewRound: discard.NewGauge(), } } diff --git a/consensus/reactor.go b/consensus/reactor.go index 3e40c4369..d10a48142 100644 --- a/consensus/reactor.go +++ b/consensus/reactor.go @@ -1417,15 +1417,15 @@ type Message interface { } func init() { - tmjson.RegisterType(&NewRoundStepMessage{}, "tendermint/NewRoundStepMessage") - tmjson.RegisterType(&NewValidBlockMessage{}, "tendermint/NewValidBlockMessage") - tmjson.RegisterType(&ProposalMessage{}, "tendermint/Proposal") - tmjson.RegisterType(&ProposalPOLMessage{}, "tendermint/ProposalPOL") - tmjson.RegisterType(&BlockPartMessage{}, "tendermint/BlockPart") - tmjson.RegisterType(&VoteMessage{}, "tendermint/Vote") - tmjson.RegisterType(&HasVoteMessage{}, "tendermint/HasVote") - tmjson.RegisterType(&VoteSetMaj23Message{}, "tendermint/VoteSetMaj23") - tmjson.RegisterType(&VoteSetBitsMessage{}, "tendermint/VoteSetBits") + tmjson.RegisterType(&NewRoundStepMessage{}, "ostracon/NewRoundStepMessage") + tmjson.RegisterType(&NewValidBlockMessage{}, "ostracon/NewValidBlockMessage") + tmjson.RegisterType(&ProposalMessage{}, "ostracon/Proposal") + tmjson.RegisterType(&ProposalPOLMessage{}, "ostracon/ProposalPOL") + tmjson.RegisterType(&BlockPartMessage{}, "ostracon/BlockPart") + tmjson.RegisterType(&VoteMessage{}, "ostracon/Vote") + tmjson.RegisterType(&HasVoteMessage{}, "ostracon/HasVote") + tmjson.RegisterType(&VoteSetMaj23Message{}, "ostracon/VoteSetMaj23") + tmjson.RegisterType(&VoteSetBitsMessage{}, "ostracon/VoteSetBits") } func decodeMsg(bz []byte) (msg Message, err error) { diff --git a/consensus/reactor_test.go b/consensus/reactor_test.go index 1a40631b2..d4bd4a610 100644 --- a/consensus/reactor_test.go +++ b/consensus/reactor_test.go @@ -11,12 +11,11 @@ import ( "testing" "time" + "github.com/line/tm-db/v2/memdb" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - dbm "github.com/tendermint/tm-db" - abcicli "github.com/line/ostracon/abci/client" "github.com/line/ostracon/abci/example/kvstore" abci "github.com/line/ostracon/abci/types" @@ -135,21 +134,21 @@ func TestReactorWithEvidence(t *testing.T) { css := make([]*State, nValidators) logger := consensusLogger() for i := 0; i < nValidators; i++ { - stateDB := dbm.NewMemDB() // each state needs its own db + stateDB := memdb.NewDB() // each state needs its own db stateStore := sm.NewStore(stateDB) state, _ := stateStore.LoadFromDBOrGenesisDoc(genDoc) thisConfig := ResetConfig(fmt.Sprintf("%s_%d", testName, i)) defer os.RemoveAll(thisConfig.RootDir) ensureDir(path.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal app := appFunc() - vals := types.TM2PB.ValidatorUpdates(state.Validators) + vals := types.OC2PB.ValidatorUpdates(state.Validators) app.InitChain(abci.RequestInitChain{Validators: vals}) pv := privVals[i] // duplicate code from: // css[i] = newStateWithConfig(thisConfig, state, privVals[i], app) - blockDB := dbm.NewMemDB() + blockDB := memdb.NewDB() blockStore := store.NewBlockStore(blockDB) // one for mempool, one for consensus @@ -221,7 +220,7 @@ 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).CheckTxSync([]byte{1, 2, 3}, mempl.TxInfo{}); err != nil { t.Error(err) } @@ -549,7 +548,7 @@ func waitForAndValidateBlock( err := validateBlock(newBlock, activeVals) assert.Nil(t, err) for _, tx := range txs { - err := assertMempool(css[j].txNotifier).CheckTx(tx, nil, mempl.TxInfo{}) + _, err := assertMempool(css[j].txNotifier).CheckTxSync(tx, mempl.TxInfo{}) assert.Nil(t, err) } }, css) diff --git a/consensus/replay.go b/consensus/replay.go index 9b23324c3..55ce382aa 100644 --- a/consensus/replay.go +++ b/consensus/replay.go @@ -270,7 +270,7 @@ func (h *Handshaker) Handshake(proxyApp proxy.AppConns) error { return fmt.Errorf("error on replay: %v", err) } - h.logger.Info("Completed ABCI Handshake - Tendermint and App are synced", + h.logger.Info("Completed ABCI Handshake - Ostracon and App are synced", "appHeight", blockHeight, "appHash", appHash) // TODO: (on restart) replay mempool @@ -306,8 +306,8 @@ func (h *Handshaker) ReplayBlocks( validators[i] = types.NewValidator(val.PubKey, val.Power) } validatorSet := types.NewValidatorSet(validators) - nextVals := types.TM2PB.ValidatorUpdates(validatorSet) - csParams := types.TM2PB.ConsensusParams(h.genDoc.ConsensusParams) + nextVals := types.OC2PB.ValidatorUpdates(validatorSet) + csParams := types.OC2PB.ConsensusParams(h.genDoc.ConsensusParams) req := abci.RequestInitChain{ Time: h.genDoc.GenesisTime, ChainId: h.genDoc.ChainID, @@ -332,7 +332,7 @@ func (h *Handshaker) ReplayBlocks( } // If the app returned validators or consensus params, update the state. if len(res.Validators) > 0 { - vals, err := types.PB2TM.ValidatorUpdates(res.Validators) + vals, err := types.PB2OC.ValidatorUpdates(res.Validators) if err != nil { return nil, err } @@ -376,11 +376,11 @@ func (h *Handshaker) ReplayBlocks( return appHash, sm.ErrAppBlockHeightTooHigh{CoreHeight: storeBlockHeight, AppHeight: appBlockHeight} case storeBlockHeight < stateBlockHeight: - // the state should never be ahead of the store (this is under tendermint's control) + // the state should never be ahead of the store (this is under ostracon's control) panic(fmt.Sprintf("StateBlockHeight (%d) > StoreBlockHeight (%d)", stateBlockHeight, storeBlockHeight)) case storeBlockHeight > stateBlockHeight+1: - // store should be at most one ahead of the state (this is under tendermint's control) + // store should be at most one ahead of the state (this is under ostracon's control) panic(fmt.Sprintf("StoreBlockHeight (%d) > StateBlockHeight + 1 (%d)", storeBlockHeight, stateBlockHeight+1)) } @@ -388,7 +388,7 @@ func (h *Handshaker) ReplayBlocks( // Now either store is equal to state, or one ahead. // For each, consider all cases of where the app could be, given app <= store if storeBlockHeight == stateBlockHeight { - // Tendermint ran Commit and saved the state. + // Ostracon ran Commit and saved the state. // Either the app is asking for replay, or we're all synced up. if appBlockHeight < storeBlockHeight { // the app is behind, so replay blocks, but no need to go through WAL (state is already synced to store) @@ -509,7 +509,7 @@ func (h *Handshaker) replayBlock(state sm.State, height int64, proxyApp proxy.Ap blockExec.SetEventBus(h.eventBus) var err error - state, _, err = blockExec.ApplyBlock(state, meta.BlockID, block) + state, _, err = blockExec.ApplyBlock(state, meta.BlockID, block, nil) if err != nil { return sm.State{}, err } @@ -536,7 +536,7 @@ func assertAppHashEqualsOneFromState(appHash []byte, state sm.State) { State: %v -Did you reset Tendermint without resetting your application's data?`, +Did you reset Ostracon without resetting your application's data?`, appHash, state.AppHash, state)) } } diff --git a/consensus/replay_file.go b/consensus/replay_file.go index 43e0ae4e0..8c684e532 100644 --- a/consensus/replay_file.go +++ b/consensus/replay_file.go @@ -10,7 +10,7 @@ import ( "strconv" "strings" - dbm "github.com/tendermint/tm-db" + "github.com/line/tm-db/v2/metadb" cfg "github.com/line/ostracon/config" "github.com/line/ostracon/libs/log" @@ -284,16 +284,16 @@ func (pb *playback) replayConsoleLoop() int { // convenience for replay mode func newConsensusStateForReplay(config cfg.BaseConfig, csConfig *cfg.ConsensusConfig) *State { - dbType := dbm.BackendType(config.DBBackend) + dbType := metadb.BackendType(config.DBBackend) // Get BlockStore - blockStoreDB, err := dbm.NewDB("blockstore", dbType, config.DBDir()) + blockStoreDB, err := metadb.NewDB("blockstore", dbType, config.DBDir()) if err != nil { tmos.Exit(err.Error()) } blockStore := store.NewBlockStore(blockStoreDB) // Get State - stateDB, err := dbm.NewDB("state", dbType, config.DBDir()) + stateDB, err := metadb.NewDB("state", dbType, config.DBDir()) if err != nil { tmos.Exit(err.Error()) } diff --git a/consensus/replay_stubs.go b/consensus/replay_stubs.go index 39c84b578..b21e3cfad 100644 --- a/consensus/replay_stubs.go +++ b/consensus/replay_stubs.go @@ -18,17 +18,17 @@ var _ mempl.Mempool = emptyMempool{} func (emptyMempool) Lock() {} func (emptyMempool) Unlock() {} func (emptyMempool) Size() int { return 0 } -func (emptyMempool) CheckTx(_ types.Tx, _ func(*abci.Response), _ mempl.TxInfo) error { - return nil +func (emptyMempool) CheckTxSync(_ types.Tx, _ mempl.TxInfo) (*abci.Response, error) { + return nil, nil +} +func (emptyMempool) CheckTxAsync(_ types.Tx, _ mempl.TxInfo, _ func(error), _ func(*abci.Response)) { } func (emptyMempool) ReapMaxBytesMaxGas(_, _ int64) types.Txs { return types.Txs{} } func (emptyMempool) ReapMaxTxs(n int) types.Txs { return types.Txs{} } func (emptyMempool) Update( - _ int64, - _ types.Txs, + _ *types.Block, _ []*abci.ResponseDeliverTx, _ mempl.PreCheckFunc, - _ mempl.PostCheckFunc, ) error { return nil } diff --git a/consensus/replay_test.go b/consensus/replay_test.go index a1a3b24d8..b7bdab88e 100644 --- a/consensus/replay_test.go +++ b/consensus/replay_test.go @@ -14,9 +14,10 @@ import ( "time" "github.com/gogo/protobuf/proto" + dbm "github.com/line/tm-db/v2" + "github.com/line/tm-db/v2/memdb" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - dbm "github.com/tendermint/tm-db" "github.com/line/ostracon/abci/example/kvstore" abci "github.com/line/ostracon/abci/types" @@ -112,7 +113,7 @@ func sendTxs(ctx context.Context, cs *State) { return default: tx := []byte{byte(i)} - if err := assertMempool(cs.txNotifier).CheckTx(tx, nil, mempl.TxInfo{}); err != nil { + if _, err := assertMempool(cs.txNotifier).CheckTxSync(tx, mempl.TxInfo{}); err != nil { panic(err) } i++ @@ -124,7 +125,7 @@ func sendTxs(ctx context.Context, cs *State) { func TestWALCrash(t *testing.T) { // TODO The execution result of this test case often fail for indeterminate reasons. // The reason for the fail is a timeout with an "Timed out waiting for new block" or "WAL did not panic for - // XX seconds" message, but the behavior that causes it is not reproducible. This issue also occurs in Tendermint, + // XX seconds" message, but the behavior that causes it is not reproducible. This issue also occurs in Ostracon, // but seems to be somewhat more pronounced with some changes in Ostracon. // See also: https://github.com/tendermint/tendermint/issues/1040 testCases := []struct { @@ -163,7 +164,7 @@ LOOP: // create consensus state from a clean slate logger := log.NewNopLogger() - blockDB := dbm.NewMemDB() + blockDB := memdb.NewDB() stateDB := blockDB stateStore := sm.NewStore(stateDB) state, err := sm.MakeGenesisStateFromFile(consensusReplayConfig.GenesisFile()) @@ -450,7 +451,7 @@ func TestSimulateValidatorsChange(t *testing.T) { valPubKey1ABCI, err := cryptoenc.PubKeyToProto(newValidatorPubKey1) assert.Nil(t, err) newValidatorTx1 := kvstore.MakeValSetChangeTx(valPubKey1ABCI, testMinPower) - err = assertMempool(css[0].txNotifier).CheckTx(newValidatorTx1, nil, mempl.TxInfo{}) + _, err = assertMempool(css[0].txNotifier).CheckTxSync(newValidatorTx1, mempl.TxInfo{}) assert.Nil(t, err) }) @@ -464,15 +465,13 @@ 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).CheckTxSync(updateValidatorTx1, mempl.TxInfo{}) assert.Nil(t, err) }) // height 4 height++ incrementHeight(vss...) - - // re-calculate vss newVss := make([]*validatorStub, nVals+1) copy(newVss, vss[:nVals+1]) sort.Sort(ValidatorStubsByPower(newVss)) @@ -502,14 +501,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).CheckTxSync(newValidatorTx2, mempl.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).CheckTxSync(newValidatorTx3, mempl.TxInfo{}) assert.Nil(t, err) }) @@ -542,7 +541,7 @@ func TestSimulateValidatorsChange(t *testing.T) { newVal3ABCI, err := cryptoenc.PubKeyToProto(newValidatorPubKey3) require.NoError(t, err) removeValidatorTx3 := kvstore.MakeValSetChangeTx(newVal3ABCI, 0) - err = assertMempool(css[0].txNotifier).CheckTx(removeValidatorTx3, nil, mempl.TxInfo{}) + _, err = assertMempool(css[0].txNotifier).CheckTxSync(removeValidatorTx3, mempl.TxInfo{}) assert.Nil(t, err) }) @@ -646,10 +645,10 @@ func TestMockProxyApp(t *testing.T) { txIndex++ } } - mock.SetResponseCallback(proxyCb) + mock.SetGlobalCallback(proxyCb) someTx := []byte("tx") - mock.DeliverTxAsync(abci.RequestDeliverTx{Tx: someTx}) + mock.DeliverTxAsync(abci.RequestDeliverTx{Tx: someTx}, nil) }) assert.True(t, validTxs == 1) assert.True(t, invalidTxs == 0) @@ -681,7 +680,7 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin if testValidatorsChange { testConfig := ResetConfig(fmt.Sprintf("%s_%v_m", t.Name(), mode)) defer os.RemoveAll(testConfig.RootDir) - stateDB = dbm.NewMemDB() + stateDB = memdb.NewDB() // Make the global variable "sim" be initialized forcefully by calling "TestSimulateValidatorChange()" // if it is not initialized as in unit execution. @@ -726,7 +725,7 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin state := genesisState.Copy() // run the chain through state.ApplyBlock to build up the ostracon state - state = buildTMStateFromChain(config, stateStore, state, chain, nBlocks, mode) + state = buildOCStateFromChain(config, stateStore, state, chain, nBlocks, mode) latestAppHash := state.AppHash // make a new client creator @@ -738,7 +737,7 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin // run nBlocks against a new client to build up the app state. // use a throwaway ostracon state proxyApp := proxy.NewAppConns(clientCreator2) - stateDB1 := dbm.NewMemDB() + stateDB1 := memdb.NewDB() stateStore := sm.NewStore(stateDB1) err := stateStore.Save(genesisState) require.NoError(t, err) @@ -807,7 +806,7 @@ func applyBlock(stateStore sm.Store, st sm.State, blk *types.Block, proxyApp pro blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyApp.Consensus(), mempool, evpool) blkID := types.BlockID{Hash: blk.Hash(), PartSetHeader: blk.MakePartSet(testPartSize).Header()} - newState, _, err := blockExec.ApplyBlock(st, blkID, blk) + newState, _, err := blockExec.ApplyBlock(st, blkID, blk, nil) if err != nil { panic(err) } @@ -823,7 +822,7 @@ func buildAppStateFromChain(proxyApp proxy.AppConns, stateStore sm.Store, defer proxyApp.Stop() //nolint:errcheck // ignore state.Version.Consensus.App = kvstore.ProtocolVersion // simulate handshake, receive app version - validators := types.TM2PB.ValidatorUpdates(state.Validators) + validators := types.OC2PB.ValidatorUpdates(state.Validators) if _, err := proxyApp.Consensus().InitChainSync(abci.RequestInitChain{ Validators: validators, }); err != nil { @@ -855,7 +854,7 @@ func buildAppStateFromChain(proxyApp proxy.AppConns, stateStore sm.Store, } -func buildTMStateFromChain( +func buildOCStateFromChain( config *cfg.Config, stateStore sm.Store, state sm.State, @@ -873,7 +872,7 @@ func buildTMStateFromChain( defer proxyApp.Stop() //nolint:errcheck state.Version.Consensus.App = kvstore.ProtocolVersion // simulate handshake, receive app version - validators := types.TM2PB.ValidatorUpdates(state.Validators) + validators := types.OC2PB.ValidatorUpdates(state.Validators) if _, err := proxyApp.Consensus().InitChainSync(abci.RequestInitChain{ Validators: validators, }); err != nil { @@ -925,7 +924,7 @@ func TestHandshakePanicsIfAppReturnsWrongAppHash(t *testing.T) { blocks := makeBlocks(3, &state, privVal) store.chain = blocks - // 2. Tendermint must panic if app returns wrong hash for the first block + // 2. Ostracon must panic if app returns wrong hash for the first block // - RANDOM HASH // - 0x02 // - 0x03 @@ -949,7 +948,7 @@ func TestHandshakePanicsIfAppReturnsWrongAppHash(t *testing.T) { }) } - // 3. Tendermint must panic if app returns wrong hash for the last block + // 3. Ostracon must panic if app returns wrong hash for the last block // - 0x01 // - 0x02 // - RANDOM HASH @@ -1177,7 +1176,7 @@ func stateAndStore( config *cfg.Config, pubKey crypto.PubKey, appVersion uint64) (dbm.DB, sm.State, *mockBlockStore) { - stateDB := dbm.NewMemDB() + stateDB := memdb.NewDB() stateStore := sm.NewStore(stateDB) state, _ := sm.MakeGenesisStateFromFile(config.GenesisFile()) state.Version.Consensus.App = appVersion @@ -1246,7 +1245,7 @@ func (bs *mockBlockStore) PruneBlocks(height int64) (uint64, error) { func TestHandshakeUpdatesValidators(t *testing.T) { val, _ := types.RandValidator(true, 10) vals := types.NewValidatorSet([]*types.Validator{val}) - app := &initChainApp{vals: types.TM2PB.ValidatorUpdates(vals)} + app := &initChainApp{vals: types.OC2PB.ValidatorUpdates(vals)} clientCreator := proxy.NewLocalClientCreator(app) config := ResetConfig("handshake_test_") diff --git a/consensus/state.go b/consensus/state.go index 5e24378ed..53872d897 100644 --- a/consensus/state.go +++ b/consensus/state.go @@ -59,57 +59,62 @@ func (ti *timeoutInfo) String() string { return fmt.Sprintf("%v ; %d/%d %v", ti.Duration, ti.Height, ti.Round, ti.Step) } -// interface to the mempool -type txNotifier interface { - TxsAvailable() <-chan struct{} +type StepTimes struct { + Proposal types.StepDuration + Prevote types.StepDuration + Precommit types.StepDuration + sm.CommitStepTimes + WaitingForNewRound types.StepDuration } -// interface to the evidence pool -type evidencePool interface { - // reports conflicting votes to the evidence pool to be processed into evidence - ReportConflictingVotes(voteA, voteB *types.Vote) +func (st *StepTimes) StartNewRound() time.Time { + now := tmtime.Now() + if st.Current == &st.WaitingForNewRound { + st.Current.End = now + } + st.Current = &st.Proposal + st.Current.Start = now + return now } -type StepDuration struct { - started bool - start time.Time - end time.Time +func (st *StepTimes) ToPrevoteStep() time.Time { + return st.ToNextStep(&st.Proposal, &st.Prevote) } -func (sd *StepDuration) GetDuration() float64 { - if !sd.started && sd.end.After(sd.start) { - return float64(sd.end.Sub(sd.start).Microseconds()) / 1000 - } - return 0 +func (st *StepTimes) ToPrecommitStep() time.Time { + return st.ToNextStep(&st.Prevote, &st.Precommit) } -func (sd *StepDuration) SetStart() time.Time { - sd.start = tmtime.Now() - sd.started = true - return sd.start +func (st *StepTimes) ToCommitExecuting() time.Time { + return st.ToNextStep(&st.Precommit, &st.CommitExecuting) } -func (sd *StepDuration) SetEnd() time.Time { - if sd.started { - // update only once at first; it will be reset when Start is re-assigned - sd.end = tmtime.Now() - sd.started = false +func (st *StepTimes) EndRound() time.Time { + now := tmtime.Now() + if st.Current == &st.CommitRechecking { + st.Current.End = now + st.Current = &st.WaitingForNewRound } - return sd.end + return now } -type StepTimes struct { - ProposalCreatedByMyself bool - ProposalCreating StepDuration - ProposalWaiting StepDuration - ProposalVerifying StepDuration - ProposalBlockReceiving StepDuration - PrevoteBlockVerifying StepDuration - PrevoteReceiving StepDuration - PrecommitBlockVerifying StepDuration - PrecommitReceiving StepDuration - CommitBlockVerifying StepDuration - CommitBlockApplying StepDuration +func (st *StepTimes) StartWaiting() time.Time { + now := tmtime.Now() + if st.Current == &st.WaitingForNewRound { + st.Current.Start = now + } + return now +} + +// interface to the mempool +type txNotifier interface { + TxsAvailable() <-chan struct{} +} + +// interface to the evidence pool +type evidencePool interface { + // reports conflicting votes to the evidence pool to be processed into evidence + ReportConflictingVotes(voteA, voteB *types.Vote) } // State handles execution of the consensus algorithm. @@ -183,7 +188,7 @@ type State struct { metrics *Metrics // times of each step - stepTimes StepTimes + stepTimes *StepTimes } // StateOption sets an optional parameter on the State. @@ -214,6 +219,7 @@ func NewState( evpool: evpool, evsw: tmevents.NewEventSwitch(), metrics: NopMetrics(), + stepTimes: &StepTimes{}, } // set function defaults (may be overwritten before calling Start) @@ -676,7 +682,7 @@ func (cs *State) updateToState(state sm.State) { cs.LastCommit = cs.Votes.Precommits(cs.CommitRound) case cs.LastCommit == nil: - // NOTE: when Tendermint starts, it has no votes. reconstructLastCommit + // NOTE: when Ostracon starts, it has no votes. reconstructLastCommit // must be called to reconstruct LastCommit from SeenCommit. panic(fmt.Sprintf( "last commit cannot be empty after initial block (H:%d)", @@ -810,12 +816,8 @@ func (cs *State) receiveRoutine(maxSteps int) { cs.handleMsg(mi) case mi = <-cs.internalMsgQueue: - err := cs.wal.WriteSync(mi) // NOTE: fsync - if err != nil { - panic(fmt.Sprintf( - "failed to write %v msg to consensus WAL due to %v; check your file system and restart the node", - mi, err, - )) + if err := cs.wal.Write(mi); err != nil { + cs.Logger.Error("failed writing to WAL", "err", err) } if _, ok := mi.Msg.(*VoteMessage); ok { @@ -1016,7 +1018,7 @@ func (cs *State) enterNewRound(height int64, round int32) { return } - now := cs.stepTimes.ProposalWaiting.SetStart() + now := cs.stepTimes.StartNewRound() if cs.StartTime.After(now) { logger.Debug("need to set a buffer and log message here for sanity", "start_time", cs.StartTime, "now", now) } @@ -1133,11 +1135,9 @@ func (cs *State) enterPropose(height int64, round int32) { if cs.isProposer(address) { logger.Debug("propose step; our turn to propose", "proposer", address) cs.decideProposal(height, round) - cs.stepTimes.ProposalCreatedByMyself = true } else { logger.Debug("propose step; not our turn to propose", "proposer", cs.Proposer.Address, "privValidator", cs.privValidator) - cs.stepTimes.ProposalCreatedByMyself = false } if !cs.Voters.HasAddress(address) { @@ -1161,10 +1161,8 @@ func (cs *State) defaultDecideProposal(height int64, round int32) { block, blockParts = cs.ValidBlock, cs.ValidBlockParts } else { // Create a new proposal block from state/txs from the mempool. - cs.stepTimes.ProposalCreating.SetStart() block, blockParts = cs.createProposalBlock(round) if block == nil { // on error - cs.stepTimes.ProposalCreating.SetEnd() return } cs.Logger.Info("Create Block", "Height", height, "Round", round, @@ -1182,7 +1180,6 @@ func (cs *State) defaultDecideProposal(height int64, round int32) { proposal := types.NewProposal(height, round, cs.ValidRound, propBlockID) p := proposal.ToProto() if err := cs.privValidator.SignProposal(cs.state.ChainID, p); err == nil { - cs.stepTimes.ProposalCreating.SetEnd() proposal.Signature = p.Signature // send proposal and block parts on internal msg queue @@ -1196,7 +1193,6 @@ func (cs *State) defaultDecideProposal(height int64, round int32) { cs.Logger.Info("signed proposal", "height", height, "round", round, "proposal", proposal) cs.Logger.Debug("signed proposal block", "block", block) } else if !cs.replayMode { - cs.stepTimes.ProposalCreating.SetEnd() cs.Logger.Error("propose step; failed signing proposal", "height", height, "round", round, "err", err) } } @@ -1288,6 +1284,7 @@ func (cs *State) enterPrevote(height int64, round int32) { logger.Debug("entering prevote step", "current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step)) // Sign and broadcast vote as necessary + cs.stepTimes.ToPrevoteStep() cs.doPrevote(height, round) // Once `addVote` hits any +2/3 prevotes, we will go to PrevoteWait @@ -1307,8 +1304,6 @@ func (cs *State) defaultDoPrevote(height int64, round int32) { // If ProposalBlock is nil, prevote nil. if cs.ProposalBlock == nil { // if it already ends or not starts it will be ignored - cs.stepTimes.ProposalWaiting.SetEnd() - cs.stepTimes.ProposalBlockReceiving.SetEnd() logger.Debug("prevote step: ProposalBlock is nil") cs.signAddVote(tmproto.PrevoteType, nil, types.PartSetHeader{}) // increase missing proposal by one @@ -1316,24 +1311,20 @@ func (cs *State) defaultDoPrevote(height int64, round int32) { return } - cs.stepTimes.PrevoteBlockVerifying.SetStart() // Validate proposal block err := cs.blockExec.ValidateBlock(cs.state, round, cs.ProposalBlock) if err != nil { // ProposalBlock is invalid, prevote nil. logger.Error("prevote step: ProposalBlock is invalid", "err", err) - cs.stepTimes.PrevoteBlockVerifying.SetEnd() cs.signAddVote(tmproto.PrevoteType, nil, types.PartSetHeader{}) return } - cs.stepTimes.PrevoteBlockVerifying.SetEnd() // Prevote cs.ProposalBlock // NOTE: the proposal signature is validated when it is received, // and the proposal block parts are validated as they are received (against the merkle hash in the proposal) logger.Debug("prevote step: ProposalBlock is valid") cs.signAddVote(tmproto.PrevoteType, cs.ProposalBlock.Hash(), cs.ProposalBlockParts.Header()) - cs.stepTimes.PrevoteReceiving.SetStart() } // Enter: any +2/3 prevotes at next round. @@ -1392,6 +1383,8 @@ func (cs *State) enterPrecommit(height int64, round int32) { cs.newStep() }() + cs.stepTimes.ToPrecommitStep() + // check for a polka blockID, ok := cs.Votes.Prevotes(round).TwoThirdsMajority() @@ -1449,7 +1442,6 @@ func (cs *State) enterPrecommit(height int64, round int32) { } cs.signAddVote(tmproto.PrecommitType, blockID.Hash, blockID.PartSetHeader) - cs.stepTimes.PrecommitReceiving.SetStart() return } @@ -1458,13 +1450,11 @@ func (cs *State) enterPrecommit(height int64, round int32) { logger.Debug("precommit step; +2/3 prevoted proposal block; locking", "hash", blockID.Hash) // Validate the block. - cs.stepTimes.PrecommitBlockVerifying.SetStart() if err := cs.blockExec.ValidateBlock(cs.state, round, cs.ProposalBlock); err != nil { cs.Logger.Error(fmt.Sprintf("%v; block=%v", err, cs.ProposalBlock)) panic(fmt.Sprintf("enterPrecommit: +2/3 prevoted for an invalid block: %v", err)) } - cs.stepTimes.PrecommitBlockVerifying.SetEnd() cs.LockedRound = round cs.LockedBlock = cs.ProposalBlock cs.LockedBlockParts = cs.ProposalBlockParts @@ -1474,7 +1464,6 @@ func (cs *State) enterPrecommit(height int64, round int32) { } cs.signAddVote(tmproto.PrecommitType, blockID.Hash, blockID.PartSetHeader) - cs.stepTimes.PrecommitReceiving.SetStart() return } @@ -1637,7 +1626,6 @@ func (cs *State) finalizeCommit(height int64) { blockID, ok := cs.Votes.Precommits(cs.CommitRound).TwoThirdsMajority() block, blockParts := cs.ProposalBlock, cs.ProposalBlockParts - cs.stepTimes.CommitBlockVerifying.SetStart() if !ok { panic("cannot finalize commit; commit does not have 2/3 majority") } @@ -1650,7 +1638,6 @@ func (cs *State) finalizeCommit(height int64) { if err := cs.blockExec.ValidateBlock(cs.state, cs.CommitRound, block); err != nil { panic(fmt.Sprintf("+2/3 committed an invalid block: %v", err)) } - cs.stepTimes.CommitBlockVerifying.SetEnd() logger.Info( "finalizing commit of block", @@ -1704,12 +1691,12 @@ func (cs *State) finalizeCommit(height int64) { // Execute and commit the block, update and save the state, and update the mempool. // NOTE The block.AppHash wont reflect these txs until the next block. - cs.stepTimes.CommitBlockApplying.SetStart() var ( err error retainHeight int64 ) + cs.stepTimes.ToCommitExecuting() stateCopy, retainHeight, err = cs.blockExec.ApplyBlock( stateCopy, types.BlockID{ @@ -1717,12 +1704,12 @@ func (cs *State) finalizeCommit(height int64) { PartSetHeader: blockParts.Header(), }, block, + &cs.stepTimes.CommitStepTimes, ) if err != nil { logger.Error("failed to apply block", "err", err) return } - cs.stepTimes.CommitBlockApplying.SetEnd() fail.Fail() // XXX @@ -1736,6 +1723,8 @@ func (cs *State) finalizeCommit(height int64) { } } + cs.stepTimes.EndRound() + // must be called before we update state cs.recordMetrics(height, block) @@ -1756,6 +1745,8 @@ func (cs *State) finalizeCommit(height int64) { // * cs.Height has been increment to height+1 // * cs.Step is now cstypes.RoundStepNewHeight // * cs.StartTime is set to when we will start round0. + + cs.stepTimes.StartWaiting() } func (cs *State) pruneBlocks(retainHeight int64) (uint64, error) { @@ -1877,7 +1868,7 @@ func (cs *State) recordMetrics(height int64, block *types.Block) { if height > 1 { lastBlockMeta := cs.blockStore.LoadBlockMeta(height - 1) if lastBlockMeta != nil { - cs.metrics.BlockIntervalSeconds.Observe( + cs.metrics.BlockIntervalSeconds.Set( block.Time.Sub(lastBlockMeta.Header.Time).Seconds(), ) } @@ -1889,18 +1880,21 @@ func (cs *State) recordMetrics(height int64, block *types.Block) { cs.metrics.CommittedHeight.Set(float64(block.Height)) cs.metrics.RoundFailures.Observe(float64(cs.Round)) - if cs.stepTimes.ProposalCreatedByMyself { - cs.metrics.ProposalCreating.Observe(cs.stepTimes.ProposalCreating.GetDuration()) - } - cs.metrics.ProposalWaiting.Observe(cs.stepTimes.ProposalWaiting.GetDuration()) - cs.metrics.ProposalVerifying.Observe(cs.stepTimes.ProposalVerifying.GetDuration()) - cs.metrics.ProposalBlockReceiving.Observe(cs.stepTimes.ProposalBlockReceiving.GetDuration()) - cs.metrics.PrevoteBlockVerifying.Observe(cs.stepTimes.PrevoteBlockVerifying.GetDuration()) - cs.metrics.PrevoteReceiving.Observe(cs.stepTimes.PrevoteReceiving.GetDuration()) - cs.metrics.PrecommitBlockVerifying.Observe(cs.stepTimes.PrecommitBlockVerifying.GetDuration()) - cs.metrics.PrecommitReceiving.Observe(cs.stepTimes.PrecommitReceiving.GetDuration()) - cs.metrics.CommitBlockVerifying.Observe(cs.stepTimes.CommitBlockVerifying.GetDuration()) - cs.metrics.CommitBlockApplying.Observe(cs.stepTimes.CommitBlockApplying.GetDuration()) + cs.metrics.DurationProposal.Observe(cs.stepTimes.Proposal.GetDuration()) + cs.metrics.DurationPrevote.Observe(cs.stepTimes.Prevote.GetDuration()) + cs.metrics.DurationPrecommit.Observe(cs.stepTimes.Precommit.GetDuration()) + cs.metrics.DurationCommitExecuting.Observe(cs.stepTimes.CommitExecuting.GetDuration()) + cs.metrics.DurationCommitCommitting.Observe(cs.stepTimes.CommitCommitting.GetDuration()) + cs.metrics.DurationCommitRechecking.Observe(cs.stepTimes.CommitRechecking.GetDuration()) + cs.metrics.DurationWaitingForNewRound.Observe(cs.stepTimes.WaitingForNewRound.GetDuration()) + + cs.metrics.DurationGaugeProposal.Set(cs.stepTimes.Proposal.GetDuration()) + cs.metrics.DurationGaugePrevote.Set(cs.stepTimes.Prevote.GetDuration()) + cs.metrics.DurationGaugePrecommit.Set(cs.stepTimes.Precommit.GetDuration()) + cs.metrics.DurationGaugeCommitExecuting.Set(cs.stepTimes.CommitExecuting.GetDuration()) + cs.metrics.DurationGaugeCommitCommitting.Set(cs.stepTimes.CommitCommitting.GetDuration()) + cs.metrics.DurationGaugeCommitRechecking.Set(cs.stepTimes.CommitRechecking.GetDuration()) + cs.metrics.DurationGaugeWaitingForNewRound.Set(cs.stepTimes.WaitingForNewRound.GetDuration()) } //----------------------------------------------------------------------------- @@ -1922,9 +1916,7 @@ func (cs *State) defaultSetProposal(proposal *types.Proposal) error { (proposal.POLRound >= 0 && proposal.POLRound >= proposal.Round) { return ErrInvalidProposalPOLRound } - cs.stepTimes.ProposalWaiting.SetEnd() - cs.stepTimes.ProposalVerifying.SetStart() // If consensus does not enterNewRound yet, cs.Proposer may be nil or prior proposer, so don't use cs.Proposer proposer := cs.Validators.SelectProposer(cs.state.LastProofHash, proposal.Height, proposal.Round) @@ -1933,13 +1925,11 @@ func (cs *State) defaultSetProposal(proposal *types.Proposal) error { if !proposer.PubKey.VerifySignature( types.ProposalSignBytes(cs.state.ChainID, p), proposal.Signature, ) { - cs.stepTimes.ProposalVerifying.SetEnd() cs.Logger.Error(fmt.Sprintf("proposal signature verification failed: proposer=%X, bytes=%X, signature=%X", cs.Proposer.Address, types.ProposalSignBytes(cs.state.ChainID, p), proposal.Signature)) return ErrInvalidProposalSignature } - cs.stepTimes.ProposalVerifying.SetEnd() proposal.Signature = p.Signature cs.Proposal = proposal @@ -1951,7 +1941,6 @@ func (cs *State) defaultSetProposal(proposal *types.Proposal) error { } cs.Logger.Info("received proposal", "proposal", proposal) - cs.stepTimes.ProposalBlockReceiving.SetStart() return nil } @@ -2008,7 +1997,6 @@ func (cs *State) addProposalBlockPart(msg *BlockPartMessage, peerID p2p.ID) (add } cs.ProposalBlock = block - cs.stepTimes.ProposalBlockReceiving.SetEnd() // NOTE: it's possible to receive complete proposal blocks for future rounds without having the proposal cs.Logger.Info("received complete proposal block", "height", cs.ProposalBlock.Height, "hash", cs.ProposalBlock.Hash()) @@ -2171,7 +2159,6 @@ func (cs *State) addVote(vote *types.Vote, peerID p2p.ID) (added bool, err error // If +2/3 prevotes for a block or nil for *any* round: if blockID, ok := prevotes.TwoThirdsMajority(); ok { - cs.stepTimes.PrevoteReceiving.SetEnd() // There was a polka! // If we're locked but this is a recent polka, unlock. @@ -2252,7 +2239,6 @@ func (cs *State) addVote(vote *types.Vote, peerID p2p.ID) (added bool, err error blockID, ok := precommits.TwoThirdsMajority() if ok { - cs.stepTimes.PrecommitReceiving.SetEnd() // Executed as TwoThirdsMajority could be from a higher round cs.enterNewRound(height, vote.Round) cs.enterPrecommit(height, vote.Round) @@ -2266,7 +2252,6 @@ func (cs *State) addVote(vote *types.Vote, peerID p2p.ID) (added bool, err error cs.enterPrecommitWait(height, vote.Round) } } else if cs.Round <= vote.Round && precommits.HasTwoThirdsAny() { - cs.stepTimes.PrecommitReceiving.SetEnd() cs.enterNewRound(height, vote.Round) cs.enterPrecommitWait(height, vote.Round) } diff --git a/consensus/state_test.go b/consensus/state_test.go index 3b7d8359f..07925cb99 100644 --- a/consensus/state_test.go +++ b/consensus/state_test.go @@ -2349,7 +2349,7 @@ func addValidator(cs *State, vssMap map[string]*validatorStub, height int64) { panic("failed to convert newVal to protobuf") } newValidatorTx := kvstore.MakeValSetChangeTx(val.PubKey, 10) - _ = assertMempool(cs.txNotifier).CheckTx(newValidatorTx, nil, mempl.TxInfo{}) + _, _ = assertMempool(cs.txNotifier).CheckTxSync(newValidatorTx, mempl.TxInfo{}) vssMap[newVal.PubKey.Address().String()] = newValidatorStub(privVal, int32(len(vssMap)+1)) vssMap[newVal.PubKey.Address().String()].Height = height } diff --git a/consensus/wal.go b/consensus/wal.go index f11c3296a..7280e2df6 100644 --- a/consensus/wal.go +++ b/consensus/wal.go @@ -46,9 +46,9 @@ type EndHeightMessage struct { type WALMessage interface{} func init() { - tmjson.RegisterType(msgInfo{}, "tendermint/wal/MsgInfo") - tmjson.RegisterType(timeoutInfo{}, "tendermint/wal/TimeoutInfo") - tmjson.RegisterType(EndHeightMessage{}, "tendermint/wal/EndHeightMessage") + tmjson.RegisterType(msgInfo{}, "ostracon/wal/MsgInfo") + tmjson.RegisterType(timeoutInfo{}, "ostracon/wal/TimeoutInfo") + tmjson.RegisterType(EndHeightMessage{}, "ostracon/wal/EndHeightMessage") } //-------------------------------------------------------- diff --git a/consensus/wal_generator.go b/consensus/wal_generator.go index c5c42a284..0575e4d47 100644 --- a/consensus/wal_generator.go +++ b/consensus/wal_generator.go @@ -9,9 +9,6 @@ import ( "testing" "time" - "github.com/pkg/errors" - db "github.com/tendermint/tm-db" - "github.com/line/ostracon/abci/example/kvstore" cfg "github.com/line/ostracon/config" "github.com/line/ostracon/libs/log" @@ -21,6 +18,8 @@ import ( sm "github.com/line/ostracon/state" "github.com/line/ostracon/store" "github.com/line/ostracon/types" + "github.com/line/tm-db/v2/memdb" + "github.com/pkg/errors" ) // WALGenerateNBlocks generates a consensus WAL. It does this by spinning up a @@ -50,7 +49,7 @@ func WALGenerateNBlocks(t *testing.T, wr io.Writer, numBlocks int) (err error) { if err != nil { return fmt.Errorf("failed to read genesis file: %w", err) } - blockStoreDB := db.NewMemDB() + blockStoreDB := memdb.NewDB() stateDB := blockStoreDB stateStore := sm.NewStore(stateDB) state, err := sm.MakeGenesisState(genDoc) diff --git a/crypto/bls/bls.go b/crypto/bls/bls.go index be5b9bfb9..680fbd0c3 100644 --- a/crypto/bls/bls.go +++ b/crypto/bls/bls.go @@ -17,8 +17,8 @@ import ( var _ crypto.PrivKey = PrivKey{} const ( - PrivKeyName = "tendermint/PrivKeyBLS12" - PubKeyName = "tendermint/PubKeyBLS12" + PrivKeyName = "ostracon/PrivKeyBLS12" + PubKeyName = "ostracon/PubKeyBLS12" PrivKeySize = 32 PubKeySize = 48 SignatureSize = 96 diff --git a/crypto/composite/composite.go b/crypto/composite/composite.go index de1fe40cd..60994ba0f 100644 --- a/crypto/composite/composite.go +++ b/crypto/composite/composite.go @@ -16,8 +16,8 @@ import ( // composite.PubKey and composite.PrivKey are intended to allow public key algorithms to be selected for each function. const ( - PubKeyName = "tendermint/PubKeyComposite" - PrivKeyName = "tendermint/PrivKeyComposite" + PubKeyName = "ostracon/PubKeyComposite" + PrivKeyName = "ostracon/PrivKeyComposite" KeyType = "composite" KeyTypeBlsWithEd25519 = KeyType + "(" + bls.KeyType + "," + ed25519.KeyType + ")" diff --git a/crypto/doc.go b/crypto/doc.go index 95ae0af18..4b929973e 100644 --- a/crypto/doc.go +++ b/crypto/doc.go @@ -1,5 +1,5 @@ // crypto is a customized/convenience cryptography package for supporting -// Tendermint. +// Ostracon. // It wraps select functionality of equivalent functions in the // Go standard library, for easy usage with our libraries. @@ -34,7 +34,7 @@ // We also provide hashing wrappers around algorithms: // Sha256 -// sum := crypto.Sha256([]byte("This is Tendermint")) +// sum := crypto.Sha256([]byte("This is Ostracon")) // fmt.Printf("%x\n", sum) package crypto diff --git a/crypto/ed25519/ed25519.go b/crypto/ed25519/ed25519.go index 1a94bfbbc..88035bbb5 100644 --- a/crypto/ed25519/ed25519.go +++ b/crypto/ed25519/ed25519.go @@ -20,8 +20,8 @@ import ( var _ crypto.PrivKey = PrivKey{} const ( - PrivKeyName = "tendermint/PrivKeyEd25519" - PubKeyName = "tendermint/PubKeyEd25519" + PrivKeyName = "ostracon/PrivKeyEd25519" + PubKeyName = "ostracon/PubKeyEd25519" // PubKeySize is is the size, in bytes, of public keys as used in this package. PubKeySize = 32 // PrivateKeySize is the size, in bytes, of private keys as used in this package. @@ -109,7 +109,7 @@ func (privKey PrivKey) Type() string { // GenPrivKey generates a new ed25519 private key. // It uses OS randomness in conjunction with the current global random seed -// in tendermint/libs/common to generate the private key. +// in ostracon/libs/common to generate the private key. func GenPrivKey() PrivKey { return genPrivKey(crypto.CReader()) } diff --git a/crypto/example_test.go b/crypto/example_test.go index f057cb1bb..fb7bc199a 100644 --- a/crypto/example_test.go +++ b/crypto/example_test.go @@ -21,8 +21,8 @@ import ( ) func ExampleSha256() { - sum := crypto.Sha256([]byte("This is Tendermint")) + sum := crypto.Sha256([]byte("This is Ostracon")) fmt.Printf("%x\n", sum) // Output: - // f91afb642f3d1c87c17eb01aae5cb65c242dfdbe7cf1066cc260f4ce5d33b94e + // e4f6b8545bd63b92f12936eccde66e48cc26895e8e67297ff97cc31c833a38d4 } diff --git a/crypto/merkle/proof_value.go b/crypto/merkle/proof_value.go index 7e0b228f3..428f29943 100644 --- a/crypto/merkle/proof_value.go +++ b/crypto/merkle/proof_value.go @@ -13,7 +13,7 @@ const ProofOpValue = "simple:v" // ValueOp takes a key and a single value as argument and // produces the root hash. The corresponding tree structure is // the SimpleMap tree. SimpleMap takes a Hasher, and currently -// Tendermint uses tmhash. SimpleValueOp should support +// Ostracon uses tmhash. SimpleValueOp should support // the hash function as used in tmhash. TODO support // additional hash functions here as options/args to this // operator. diff --git a/crypto/secp256k1/secp256k1.go b/crypto/secp256k1/secp256k1.go index 8493689ca..9c0a56176 100644 --- a/crypto/secp256k1/secp256k1.go +++ b/crypto/secp256k1/secp256k1.go @@ -17,8 +17,8 @@ import ( //------------------------------------- const ( - PrivKeyName = "tendermint/PrivKeySecp256k1" - PubKeyName = "tendermint/PubKeySecp256k1" + PrivKeyName = "ostracon/PrivKeySecp256k1" + PubKeyName = "ostracon/PubKeySecp256k1" KeyType = "secp256k1" PrivKeySize = 32 diff --git a/crypto/secp256k1/secp256k1_nocgo.go b/crypto/secp256k1/secp256k1_nocgo.go index a99d89a90..9f04c20c1 100644 --- a/crypto/secp256k1/secp256k1_nocgo.go +++ b/crypto/secp256k1/secp256k1_nocgo.go @@ -1,5 +1,3 @@ -// +build !libsecp256k1 - package secp256k1 import ( diff --git a/crypto/sr25519/encoding.go b/crypto/sr25519/encoding.go index e04975164..b55e11c9a 100644 --- a/crypto/sr25519/encoding.go +++ b/crypto/sr25519/encoding.go @@ -8,8 +8,8 @@ import ( var _ crypto.PrivKey = PrivKey{} const ( - PrivKeyName = "tendermint/PrivKeySr25519" - PubKeyName = "tendermint/PubKeySr25519" + PrivKeyName = "ostracon/PrivKeySr25519" + PubKeyName = "ostracon/PubKeySr25519" // SignatureSize is the size of an Edwards25519 signature. Namely the size of a compressed // Sr25519 point, and a field element. Both of which are 32 bytes. diff --git a/evidence/pool.go b/evidence/pool.go index ccfc047dd..373108cac 100644 --- a/evidence/pool.go +++ b/evidence/pool.go @@ -11,7 +11,7 @@ import ( "github.com/gogo/protobuf/proto" gogotypes "github.com/gogo/protobuf/types" - dbm "github.com/tendermint/tm-db" + dbm "github.com/line/tm-db/v2" clist "github.com/line/ostracon/libs/clist" "github.com/line/ostracon/libs/log" @@ -422,7 +422,7 @@ func (evpool *Pool) listEvidence(prefixKey byte, maxBytes int64) ([]types.Eviden evList tmproto.EvidenceList // used for calculating the bytes size ) - iter, err := dbm.IteratePrefix(evpool.evidenceStore, []byte{prefixKey}) + iter, err := evpool.evidenceStore.PrefixIterator([]byte{prefixKey}) if err != nil { return nil, totalSize, fmt.Errorf("database error: %v", err) } @@ -458,7 +458,7 @@ func (evpool *Pool) listEvidence(prefixKey byte, maxBytes int64) ([]types.Eviden } func (evpool *Pool) removeExpiredPendingEvidence() (int64, time.Time) { - iter, err := dbm.IteratePrefix(evpool.evidenceStore, []byte{baseKeyPending}) + iter, err := evpool.evidenceStore.PrefixIterator([]byte{baseKeyPending}) if err != nil { evpool.logger.Error("Unable to iterate over pending evidence", "err", err) return evpool.State().LastBlockHeight, evpool.State().LastBlockTime diff --git a/evidence/pool_test.go b/evidence/pool_test.go index 562d34922..92cd496ab 100644 --- a/evidence/pool_test.go +++ b/evidence/pool_test.go @@ -9,12 +9,13 @@ import ( "github.com/line/ostracon/crypto/bls" "github.com/line/ostracon/crypto/composite" "github.com/line/ostracon/crypto/ed25519" + "github.com/line/tm-db/v2/memdb" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - dbm "github.com/tendermint/tm-db" + dbm "github.com/line/tm-db/v2" "github.com/line/ostracon/evidence" "github.com/line/ostracon/evidence/mocks" @@ -45,7 +46,7 @@ func TestEvidencePoolBasic(t *testing.T) { var ( height = int64(1) stateStore = &smmocks.Store{} - evidenceDB = dbm.NewMemDB() + evidenceDB = memdb.NewDB() blockStore = &mocks.BlockStore{} ) @@ -123,7 +124,7 @@ func TestAddExpiredEvidence(t *testing.T) { val = types.NewMockPV(types.PrivKeyComposite) // TODO 🏺 need to test by all key types height = int64(30) stateStore = initializeValidatorState(val, height) - evidenceDB = dbm.NewMemDB() + evidenceDB = memdb.NewDB() blockStore = &mocks.BlockStore{} expiredEvidenceTime = time.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC) expiredHeight = int64(2) @@ -316,7 +317,7 @@ func TestCheckEvidenceWithLightClientAttack(t *testing.T) { blockStore.On("LoadBlockMeta", height).Return(&types.BlockMeta{Header: *trustedHeader}) blockStore.On("LoadBlockCommit", height).Return(trustedCommit) - pool, err := evidence.NewPool(dbm.NewMemDB(), stateStore, blockStore) + pool, err := evidence.NewPool(memdb.NewDB(), stateStore, blockStore) require.NoError(t, err) pool.SetLogger(log.TestingLogger()) @@ -339,11 +340,11 @@ func TestRecoverPendingEvidence(t *testing.T) { height := int64(10) val := types.NewMockPV(types.PrivKeyComposite) // TODO 🏺 need to test by all key types valAddress := val.PrivKey.PubKey().Address() - evidenceDB := dbm.NewMemDB() + evidenceDB := memdb.NewDB() stateStore := initializeValidatorState(val, height) state, err := stateStore.Load() require.NoError(t, err) - blockStore := initializeBlockStore(dbm.NewMemDB(), state, valAddress) + blockStore := initializeBlockStore(memdb.NewDB(), state, valAddress) // create previous pool and populate it pool, err := evidence.NewPool(evidenceDB, stateStore, blockStore) require.NoError(t, err) @@ -384,7 +385,7 @@ func TestRecoverPendingEvidence(t *testing.T) { } func initializeStateFromValidatorSet(valSet *types.ValidatorSet, height int64) sm.Store { - stateDB := dbm.NewMemDB() + stateDB := memdb.NewDB() stateStore := sm.NewStore(stateDB) state := sm.State{ ChainID: evidenceChainID, @@ -471,10 +472,10 @@ func makeCommit(height int64, valAddr []byte) *types.Commit { func defaultTestPool(height int64) (*evidence.Pool, types.MockPV) { val := types.NewMockPV(types.PrivKeyComposite) // TODO 🏺 need to test by all key types valAddress := val.PrivKey.PubKey().Address() - evidenceDB := dbm.NewMemDB() + evidenceDB := memdb.NewDB() stateStore := initializeValidatorState(val, height) state, _ := stateStore.Load() - blockStore := initializeBlockStore(dbm.NewMemDB(), state, valAddress) + blockStore := initializeBlockStore(memdb.NewDB(), state, valAddress) pool, err := evidence.NewPool(evidenceDB, stateStore, blockStore) if err != nil { panic("test evidence pool could not be created") diff --git a/evidence/reactor_test.go b/evidence/reactor_test.go index b15925cd1..97430e7fb 100644 --- a/evidence/reactor_test.go +++ b/evidence/reactor_test.go @@ -9,12 +9,11 @@ import ( "github.com/fortytw2/leaktest" "github.com/go-kit/kit/log/term" + "github.com/line/tm-db/v2/memdb" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - dbm "github.com/tendermint/tm-db" - cfg "github.com/line/ostracon/config" "github.com/line/ostracon/crypto" "github.com/line/ostracon/crypto/tmhash" @@ -190,7 +189,7 @@ func TestReactorsGossipNoCommittedEvidence(t *testing.T) { func TestReactorBroadcastEvidenceMemoryLeak(t *testing.T) { config := cfg.TestConfig() evidenceTime := time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC) - evidenceDB := dbm.NewMemDB() + evidenceDB := memdb.NewDB() blockStore := &mocks.BlockStore{} blockStore.On("LoadBlockMeta", mock.AnythingOfType("int64")).Return( &types.BlockMeta{Header: types.Header{Time: evidenceTime}}, @@ -247,7 +246,7 @@ func makeAndConnectReactorsAndPools(config *cfg.Config, stateStores []sm.Store) evidenceTime := time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC) for i := 0; i < N; i++ { - evidenceDB := dbm.NewMemDB() + evidenceDB := memdb.NewDB() blockStore := &mocks.BlockStore{} blockStore.On("LoadBlockMeta", mock.AnythingOfType("int64")).Return( &types.BlockMeta{Header: types.Header{Time: evidenceTime}}, diff --git a/evidence/verify_test.go b/evidence/verify_test.go index 919520360..e61e443dc 100644 --- a/evidence/verify_test.go +++ b/evidence/verify_test.go @@ -5,14 +5,13 @@ import ( "time" "github.com/coniks-sys/coniks-go/crypto/vrf" + "github.com/line/tm-db/v2/memdb" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - dbm "github.com/tendermint/tm-db" - "github.com/line/ostracon/crypto" "github.com/line/ostracon/crypto/tmhash" "github.com/line/ostracon/evidence" @@ -137,7 +136,7 @@ func TestVerifyLightClientAttack_Lunatic(t *testing.T) { blockStore.On("LoadBlockCommit", int64(4)).Return(commit) blockStore.On("LoadBlockCommit", int64(10)).Return(trustedCommit) - pool, err := evidence.NewPool(dbm.NewMemDB(), stateStore, blockStore) + pool, err := evidence.NewPool(memdb.NewDB(), stateStore, blockStore) require.NoError(t, err) pool.SetLogger(log.TestingLogger()) @@ -253,7 +252,7 @@ func TestVerifyLightClientAttack_Equivocation(t *testing.T) { blockStore.On("LoadBlockMeta", int64(10)).Return(&types.BlockMeta{Header: *trustedHeader}) blockStore.On("LoadBlockCommit", int64(10)).Return(trustedCommit) - pool, err := evidence.NewPool(dbm.NewMemDB(), stateStore, blockStore) + pool, err := evidence.NewPool(memdb.NewDB(), stateStore, blockStore) require.NoError(t, err) pool.SetLogger(log.TestingLogger()) @@ -346,7 +345,7 @@ func TestVerifyLightClientAttack_Amnesia(t *testing.T) { blockStore.On("LoadBlockMeta", int64(10)).Return(&types.BlockMeta{Header: *trustedHeader}) blockStore.On("LoadBlockCommit", int64(10)).Return(trustedCommit) - pool, err := evidence.NewPool(dbm.NewMemDB(), stateStore, blockStore) + pool, err := evidence.NewPool(memdb.NewDB(), stateStore, blockStore) require.NoError(t, err) pool.SetLogger(log.TestingLogger()) @@ -440,7 +439,7 @@ func TestVerifyDuplicateVoteEvidence(t *testing.T) { blockStore := &mocks.BlockStore{} blockStore.On("LoadBlockMeta", int64(10)).Return(&types.BlockMeta{Header: types.Header{Time: defaultEvidenceTime}}) - pool, err := evidence.NewPool(dbm.NewMemDB(), stateStore, blockStore) + pool, err := evidence.NewPool(memdb.NewDB(), stateStore, blockStore) require.NoError(t, err) evList := types.EvidenceList{goodEv} diff --git a/go.mod b/go.mod index 6cbd988e5..f9b435ca6 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,6 @@ require ( github.com/btcsuite/btcutil v1.0.2 github.com/confio/ics23/go v0.6.3 github.com/coniks-sys/coniks-go v0.0.0-20180722014011-11acf4819b71 - github.com/cosmos/iavl v0.15.3 github.com/fortytw2/leaktest v1.3.0 github.com/go-kit/kit v0.10.0 github.com/go-logfmt/logfmt v0.5.0 @@ -20,6 +19,7 @@ require ( github.com/gtank/merlin v0.1.1 github.com/herumi/bls-eth-go-binary v0.0.0-20200923072303-32b29e5d8cbf github.com/libp2p/go-buffer-pool v0.0.2 + github.com/line/tm-db/v2 v2.0.0-init.1.0.20210824011847-fcfa67dd3c70 github.com/minio/highwayhash v1.0.1 github.com/pelletier/go-toml v1.6.0 // indirect github.com/pkg/errors v0.9.1 @@ -36,7 +36,6 @@ require ( github.com/stretchr/objx v0.2.0 // indirect github.com/stretchr/testify v1.7.0 github.com/tendermint/go-amino v0.16.0 - github.com/tendermint/tm-db v0.6.4 github.com/yahoo/coname v0.0.0-20170609175141-84592ddf8673 // indirect golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9 golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 diff --git a/go.sum b/go.sum index 5dd3abfb0..c328bd876 100644 --- a/go.sum +++ b/go.sum @@ -34,7 +34,6 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -74,11 +73,9 @@ github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/confio/ics23/go v0.0.0-20200817220745-f173e6211efb/go.mod h1:E45NqnlpxGnpfTWL/xauN7MRwEE28T4Dd4uraToOaKg= github.com/confio/ics23/go v0.6.3 h1:PuGK2V1NJWZ8sSkNDq91jgT/cahFEW9RGp4Y5jxulf0= github.com/confio/ics23/go v0.6.3/go.mod h1:E45NqnlpxGnpfTWL/xauN7MRwEE28T4Dd4uraToOaKg= github.com/coniks-sys/coniks-go v0.0.0-20180722014011-11acf4819b71 h1:MFLTqgfJclmtaQ1SRUrWwmDX/1UBok3XWUethkJ2swQ= @@ -95,10 +92,6 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d h1:49RLWk1j44Xu4fjHb6JFYmeUnDORVwHNkDxaQ0ctCVU= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= -github.com/cosmos/iavl v0.15.0-rc3.0.20201009144442-230e9bdf52cd/go.mod h1:3xOIaNNX19p0QrX0VqWa6voPRoJRGGYtny+DH8NEPvE= -github.com/cosmos/iavl v0.15.0-rc5/go.mod h1:WqoPL9yPTQ85QBMT45OOUzPxG/U/JcJoN7uMjgxke/I= -github.com/cosmos/iavl v0.15.3 h1:xE9r6HW8GeKeoYJN4zefpljZ1oukVScP/7M8oj6SUts= -github.com/cosmos/iavl v0.15.3/go.mod h1:OLjQiAQ4fGD2KDZooyJG9yz+p2ao2IAYSbke8mVvSA4= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -108,7 +101,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= -github.com/dgraph-io/badger/v2 v2.2007.1/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE= github.com/dgraph-io/badger/v2 v2.2007.2 h1:EjjK0KqwaFMlPin1ajhP943VPENHJdEz1KLIegjaI3k= github.com/dgraph-io/badger/v2 v2.2007.2/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de h1:t0UHb5vdojIDUqktM6+xJAfScFBsVpXZmqC9dsgJmeA= @@ -127,15 +119,14 @@ github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaB github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 h1:0JZ+dUmQeA8IIVUMzysrX4/AKuQwWhV2dYQuPZdvdSQ= -github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= +github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= +github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= -github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 h1:E2s37DuLxFhQDg5gKsWoLBOB0n+ZW8s599zru8FJ2/Y= -github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= +github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= +github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= @@ -146,7 +137,6 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= @@ -158,7 +148,6 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gogo/gateway v1.1.0/go.mod h1:S7rR8FRQyG3QFESeSv4l2WnsyzlCLG0CzBbUUo/mbic= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -177,7 +166,6 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -216,20 +204,13 @@ github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51 github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.2.1/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= -github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.14.7/go.mod h1:oYZKL012gGh6LMyg/xA7Q2yq6j8bu0wa+9w14EEthWU= -github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= @@ -291,6 +272,7 @@ github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= @@ -299,6 +281,10 @@ github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOS github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/line/gorocksdb v0.0.0-20210406043732-d4bea34b6d55 h1:cXVtMiJkvQ4kn0pxM2svH1ncJbFgQsLHtnFC9qJj2VM= +github.com/line/gorocksdb v0.0.0-20210406043732-d4bea34b6d55/go.mod h1:DHRJroSL7NaRkpvocRx3OtRsleXVsYSxBI9SfHFlTQ0= +github.com/line/tm-db/v2 v2.0.0-init.1.0.20210824011847-fcfa67dd3c70 h1:Izv/u19P8salnSZGAgNHFugNlzWLgREiL+AmWK8C/lE= +github.com/line/tm-db/v2 v2.0.0-init.1.0.20210824011847-fcfa67dd3c70/go.mod h1:wmkyPabXjtVZ1dvRofmurjaceghywtCSYGqFuFS+TbI= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= @@ -336,8 +322,6 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= @@ -420,7 +404,6 @@ github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqn github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ= github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= @@ -428,7 +411,6 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/sasha-s/go-deadlock v0.2.0/go.mod h1:StQn567HiB1fF2yJ44N9au7wOhrPS3iZqiDbRupzT10= github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa h1:0U2s5loxrTy6/VgfVoLuVLFJcURKLH49ie0zSch7gh4= github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= @@ -454,7 +436,6 @@ github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= @@ -465,7 +446,6 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= @@ -480,28 +460,16 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk= github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= -github.com/tendermint/tendermint v0.34.0-rc4/go.mod h1:yotsojf2C1QBOw4dZrTcxbyxmPUrT4hNuOQWX9XUwB4= -github.com/tendermint/tendermint v0.34.0-rc6/go.mod h1:ugzyZO5foutZImv0Iyx/gOFCX6mjJTgbLHTwi17VDVg= -github.com/tendermint/tendermint v0.34.0 h1:eXCfMgoqVSzrjzOj6clI9GAejcHH0LvOlRjpCmMJksU= -github.com/tendermint/tendermint v0.34.0/go.mod h1:Aj3PIipBFSNO21r+Lq3TtzQ+uKESxkbA3yo/INM4QwQ= -github.com/tendermint/tm-db v0.6.2/go.mod h1:GYtQ67SUvATOcoY8/+x6ylk8Qo02BQyLrAs+yAcLvGI= -github.com/tendermint/tm-db v0.6.3/go.mod h1:lfA1dL9/Y/Y8wwyPp2NMLyn5P5Ptr/gvDFNWtrCWSf8= -github.com/tendermint/tm-db v0.6.4 h1:3N2jlnYQkXNQclQwd/eKV/NzlqPlfK21cpRRIx80XXQ= -github.com/tendermint/tm-db v0.6.4/go.mod h1:dptYhIpJ2M5kUuenLr+Yyf3zQOv1SgBZcl8/BmWlMBw= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= @@ -542,8 +510,6 @@ golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9 h1:phUcVbl53swtrUN8kQEXFhUxPlIlWyBfKmidCu7P95o= golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -551,7 +517,6 @@ golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -566,9 +531,7 @@ golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCc golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -585,26 +548,20 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -634,7 +591,6 @@ golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -642,13 +598,11 @@ golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211 h1:9UQO31fZ+0aKQOFldThf7BKPMJTiBfWycGh/u3UoO88= golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -689,9 +643,7 @@ golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a h1:CB3a9Nez8M13wwlr/E2YtwoU+qYHKfC+JrDa45RXXoQ= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -720,16 +672,10 @@ google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201111145450-ac7456db90a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201119123407-9b1e624d6bc4 h1:Rt0FRalMgdSlXAVJvX4pr65KfqaxHXSLkSJRD9pw6g0= -google.golang.org/genproto v0.0.0-20201119123407-9b1e624d6bc4/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -740,12 +686,6 @@ google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.35.0 h1:TwIQcH3es+MojMVojxxfQ3l3OF2KzlRxML2xZq0kRo8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -756,16 +696,13 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U= -gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -779,7 +716,6 @@ gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRN gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/libs/cli/flags/log_level.go b/libs/cli/flags/log_level.go index 2a2df8005..6deb77fdf 100644 --- a/libs/cli/flags/log_level.go +++ b/libs/cli/flags/log_level.go @@ -17,7 +17,7 @@ const ( // all other modules). // // Example: -// ParseLogLevel("consensus:debug,mempool:debug,*:error", log.NewTMLogger(os.Stdout), "info") +// ParseLogLevel("consensus:debug,mempool:debug,*:error", log.NewOCLogger(os.Stdout), "info") func ParseLogLevel(lvl string, logger log.Logger, defaultLogLevelValue string) (log.Logger, error) { if lvl == "" { return nil, errors.New("empty log level") diff --git a/libs/cli/flags/log_level_test.go b/libs/cli/flags/log_level_test.go index 88f0d6568..25a34d3b1 100644 --- a/libs/cli/flags/log_level_test.go +++ b/libs/cli/flags/log_level_test.go @@ -15,7 +15,7 @@ const ( func TestParseLogLevel(t *testing.T) { var buf bytes.Buffer - jsonLogger := log.NewTMJSONLoggerNoTS(&buf) + jsonLogger := log.NewOCJSONLoggerNoTS(&buf) correctLogLevels := []struct { lvl string diff --git a/libs/cli/setup.go b/libs/cli/setup.go index c28d759b2..ba3a73f65 100644 --- a/libs/cli/setup.go +++ b/libs/cli/setup.go @@ -48,13 +48,13 @@ func PrepareMainCmd(cmd *cobra.Command, envPrefix, defaultHome string) Executor func initEnv(prefix string) { copyEnvVars(prefix) - // env variables with TM prefix (eg. TM_ROOT) + // env variables with OC prefix (eg. OC_ROOT) viper.SetEnvPrefix(prefix) viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_")) viper.AutomaticEnv() } -// This copies all variables like TMROOT to TM_ROOT, +// This copies all variables like OCROOT to OC_ROOT, // so we can support both formats for the user func copyEnvVars(prefix string) { prefix = strings.ToUpper(prefix) diff --git a/libs/log/filter_test.go b/libs/log/filter_test.go index f40bdfdb5..ba4543d7d 100644 --- a/libs/log/filter_test.go +++ b/libs/log/filter_test.go @@ -58,7 +58,7 @@ func TestVariousLevels(t *testing.T) { tc := tc t.Run(tc.name, func(t *testing.T) { var buf bytes.Buffer - logger := log.NewFilter(log.NewTMJSONLoggerNoTS(&buf), tc.allowed) + logger := log.NewFilter(log.NewOCJSONLoggerNoTS(&buf), tc.allowed) logger.Debug("here", "this is", "debug log") logger.Info("here", "this is", "info log") @@ -74,7 +74,7 @@ func TestVariousLevels(t *testing.T) { func TestLevelContext(t *testing.T) { var buf bytes.Buffer - logger := log.NewTMJSONLoggerNoTS(&buf) + logger := log.NewOCJSONLoggerNoTS(&buf) logger = log.NewFilter(logger, log.AllowError()) logger = logger.With("context", "value") @@ -96,7 +96,7 @@ func TestLevelContext(t *testing.T) { func TestVariousAllowWith(t *testing.T) { var buf bytes.Buffer - logger := log.NewTMJSONLoggerNoTS(&buf) + logger := log.NewOCJSONLoggerNoTS(&buf) logger1 := log.NewFilter(logger, log.AllowError(), log.AllowInfoWith("context", "value")) logger1.With("context", "value").Info("foo", "bar", "baz") diff --git a/libs/log/logger.go b/libs/log/logger.go index ddb187bc7..f4b84c466 100644 --- a/libs/log/logger.go +++ b/libs/log/logger.go @@ -6,7 +6,7 @@ import ( kitlog "github.com/go-kit/kit/log" ) -// Logger is what any Tendermint library should take. +// Logger is what any Ostracon library should take. type Logger interface { Debug(msg string, keyvals ...interface{}) Info(msg string, keyvals ...interface{}) diff --git a/libs/log/tm_json_logger.go b/libs/log/oc_json_logger.go similarity index 62% rename from libs/log/tm_json_logger.go rename to libs/log/oc_json_logger.go index 3ebeddaa3..209845ea1 100644 --- a/libs/log/tm_json_logger.go +++ b/libs/log/oc_json_logger.go @@ -6,19 +6,19 @@ import ( kitlog "github.com/go-kit/kit/log" ) -// NewTMJSONLogger returns a Logger that encodes keyvals to the Writer as a +// NewOCJSONLogger returns a Logger that encodes keyvals to the Writer as a // single JSON object. Each log event produces no more than one call to // w.Write. The passed Writer must be safe for concurrent use by multiple // goroutines if the returned Logger will be used concurrently. -func NewTMJSONLogger(w io.Writer) Logger { +func NewOCJSONLogger(w io.Writer) Logger { logger := kitlog.NewJSONLogger(w) logger = kitlog.With(logger, "ts", kitlog.DefaultTimestampUTC) - return &tmLogger{logger} + return &ocLogger{logger} } -// NewTMJSONLoggerNoTS is the same as NewTMJSONLogger, but without the +// NewOCJSONLoggerNoTS is the same as NewOCJSONLogger, but without the // timestamp. -func NewTMJSONLoggerNoTS(w io.Writer) Logger { +func NewOCJSONLoggerNoTS(w io.Writer) Logger { logger := kitlog.NewJSONLogger(w) - return &tmLogger{logger} + return &ocLogger{logger} } diff --git a/libs/log/tm_logger.go b/libs/log/oc_logger.go similarity index 72% rename from libs/log/tm_logger.go rename to libs/log/oc_logger.go index 7c106336c..cbb790955 100644 --- a/libs/log/tm_logger.go +++ b/libs/log/oc_logger.go @@ -14,17 +14,17 @@ const ( moduleKey = "module" ) -type tmLogger struct { +type ocLogger struct { srcLogger kitlog.Logger } // Interface assertions -var _ Logger = (*tmLogger)(nil) +var _ Logger = (*ocLogger)(nil) -// NewTMLogger returns a logger that encodes msg and keyvals to the Writer +// NewOCLogger returns a logger that encodes msg and keyvals to the Writer // using go-kit's log as an underlying logger and our custom formatter. Note // that underlying logger could be swapped with something else. -func NewTMLogger(w io.Writer) Logger { +func NewOCLogger(w io.Writer) Logger { // Color by level value colorFn := func(keyvals ...interface{}) term.FgBgColor { if keyvals[0] != kitlevel.Key() { @@ -40,17 +40,17 @@ func NewTMLogger(w io.Writer) Logger { } } - return &tmLogger{term.NewLogger(w, NewTMFmtLogger, colorFn)} + return &ocLogger{term.NewLogger(w, NewOCFmtLogger, colorFn)} } -// NewTMLoggerWithColorFn allows you to provide your own color function. See -// NewTMLogger for documentation. -func NewTMLoggerWithColorFn(w io.Writer, colorFn func(keyvals ...interface{}) term.FgBgColor) Logger { - return &tmLogger{term.NewLogger(w, NewTMFmtLogger, colorFn)} +// NewOCLoggerWithColorFn allows you to provide your own color function. See +// NewOCLogger for documentation. +func NewOCLoggerWithColorFn(w io.Writer, colorFn func(keyvals ...interface{}) term.FgBgColor) Logger { + return &ocLogger{term.NewLogger(w, NewOCFmtLogger, colorFn)} } // Info logs a message at level Info. -func (l *tmLogger) Info(msg string, keyvals ...interface{}) { +func (l *ocLogger) Info(msg string, keyvals ...interface{}) { lWithLevel := kitlevel.Info(l.srcLogger) if err := kitlog.With(lWithLevel, msgKey, msg).Log(keyvals...); err != nil { @@ -60,7 +60,7 @@ func (l *tmLogger) Info(msg string, keyvals ...interface{}) { } // Debug logs a message at level Debug. -func (l *tmLogger) Debug(msg string, keyvals ...interface{}) { +func (l *ocLogger) Debug(msg string, keyvals ...interface{}) { lWithLevel := kitlevel.Debug(l.srcLogger) if err := kitlog.With(lWithLevel, msgKey, msg).Log(keyvals...); err != nil { @@ -70,7 +70,7 @@ func (l *tmLogger) Debug(msg string, keyvals ...interface{}) { } // Error logs a message at level Error. -func (l *tmLogger) Error(msg string, keyvals ...interface{}) { +func (l *ocLogger) Error(msg string, keyvals ...interface{}) { lWithLevel := kitlevel.Error(l.srcLogger) lWithMsg := kitlog.With(lWithLevel, msgKey, msg) @@ -81,6 +81,6 @@ func (l *tmLogger) Error(msg string, keyvals ...interface{}) { // With returns a new contextual logger with keyvals prepended to those passed // to calls to Info, Debug or Error. -func (l *tmLogger) With(keyvals ...interface{}) Logger { - return &tmLogger{kitlog.With(l.srcLogger, keyvals...)} +func (l *ocLogger) With(keyvals ...interface{}) Logger { + return &ocLogger{kitlog.With(l.srcLogger, keyvals...)} } diff --git a/libs/log/tm_logger_test.go b/libs/log/oc_logger_test.go similarity index 91% rename from libs/log/tm_logger_test.go rename to libs/log/oc_logger_test.go index a4a215807..0498b9bd5 100644 --- a/libs/log/tm_logger_test.go +++ b/libs/log/oc_logger_test.go @@ -12,7 +12,7 @@ import ( func TestLoggerLogsItsErrors(t *testing.T) { var buf bytes.Buffer - logger := log.NewTMLogger(&buf) + logger := log.NewOCLogger(&buf) logger.Info("foo", "baz baz", "bar") msg := strings.TrimSpace(buf.String()) if !strings.Contains(msg, "foo") { @@ -23,7 +23,7 @@ func TestLoggerLogsItsErrors(t *testing.T) { func TestInfo(t *testing.T) { var bufInfo bytes.Buffer - l := log.NewTMLogger(&bufInfo) + l := log.NewOCLogger(&bufInfo) l.Info("Client initialized with old header (trusted is more recent)", "old", 42, "trustedHeight", "forty two", @@ -46,7 +46,7 @@ func TestInfo(t *testing.T) { func TestDebug(t *testing.T) { var bufDebug bytes.Buffer - ld := log.NewTMLogger(&bufDebug) + ld := log.NewOCLogger(&bufDebug) ld.Debug("Client initialized with old header (trusted is more recent)", "old", 42, "trustedHeight", "forty two", @@ -69,7 +69,7 @@ func TestDebug(t *testing.T) { func TestError(t *testing.T) { var bufErr bytes.Buffer - le := log.NewTMLogger(&bufErr) + le := log.NewOCLogger(&bufErr) le.Error("Client initialized with old header (trusted is more recent)", "old", 42, "trustedHeight", "forty two", @@ -90,11 +90,11 @@ func TestError(t *testing.T) { } func BenchmarkTMLoggerSimple(b *testing.B) { - benchmarkRunner(b, log.NewTMLogger(ioutil.Discard), baseInfoMessage) + benchmarkRunner(b, log.NewOCLogger(ioutil.Discard), baseInfoMessage) } func BenchmarkTMLoggerContextual(b *testing.B) { - benchmarkRunner(b, log.NewTMLogger(ioutil.Discard), withInfoMessage) + benchmarkRunner(b, log.NewOCLogger(ioutil.Discard), withInfoMessage) } func benchmarkRunner(b *testing.B, logger log.Logger, f func(log.Logger)) { diff --git a/libs/log/tmfmt_logger.go b/libs/log/ocfmt_logger.go similarity index 85% rename from libs/log/tmfmt_logger.go rename to libs/log/ocfmt_logger.go index c6004cc62..d29689fe5 100644 --- a/libs/log/tmfmt_logger.go +++ b/libs/log/ocfmt_logger.go @@ -14,43 +14,43 @@ import ( "github.com/go-logfmt/logfmt" ) -type tmfmtEncoder struct { +type ocfmtEncoder struct { *logfmt.Encoder buf bytes.Buffer } -func (l *tmfmtEncoder) Reset() { +func (l *ocfmtEncoder) Reset() { l.Encoder.Reset() l.buf.Reset() } -var tmfmtEncoderPool = sync.Pool{ +var ocfmtEncoderPool = sync.Pool{ New: func() interface{} { - var enc tmfmtEncoder + var enc ocfmtEncoder enc.Encoder = logfmt.NewEncoder(&enc.buf) return &enc }, } -type tmfmtLogger struct { +type ocfmtLogger struct { w io.Writer } -// NewTMFmtLogger returns a logger that encodes keyvals to the Writer in -// Tendermint custom format. Note complex types (structs, maps, slices) +// NewOCFmtLogger returns a logger that encodes keyvals to the Writer in +// Ostracon custom format. Note complex types (structs, maps, slices) // formatted as "%+v". // // Each log event produces no more than one call to w.Write. // The passed Writer must be safe for concurrent use by multiple goroutines if // the returned Logger will be used concurrently. -func NewTMFmtLogger(w io.Writer) kitlog.Logger { - return &tmfmtLogger{w} +func NewOCFmtLogger(w io.Writer) kitlog.Logger { + return &ocfmtLogger{w} } -func (l tmfmtLogger) Log(keyvals ...interface{}) error { - enc := tmfmtEncoderPool.Get().(*tmfmtEncoder) +func (l ocfmtLogger) Log(keyvals ...interface{}) error { + enc := ocfmtEncoderPool.Get().(*ocfmtEncoder) enc.Reset() - defer tmfmtEncoderPool.Put(enc) + defer ocfmtEncoderPool.Put(enc) const unknown = "unknown" lvl := "none" @@ -89,7 +89,7 @@ func (l tmfmtLogger) Log(keyvals ...interface{}) error { } } - // Form a custom Tendermint line + // Form a custom Ostracon line // // Example: // D[2016-05-02|11:06:44.322] Stopping AddrBook (ignoring: already stopped) diff --git a/libs/log/tmfmt_logger_test.go b/libs/log/ocfmt_logger_test.go similarity index 92% rename from libs/log/tmfmt_logger_test.go rename to libs/log/ocfmt_logger_test.go index 8bd7e2357..28b0e0a00 100644 --- a/libs/log/tmfmt_logger_test.go +++ b/libs/log/ocfmt_logger_test.go @@ -17,7 +17,7 @@ import ( func TestTMFmtLogger(t *testing.T) { t.Parallel() buf := &bytes.Buffer{} - logger := log.NewTMFmtLogger(buf) + logger := log.NewOCFmtLogger(buf) if err := logger.Log("hello", "world"); err != nil { t.Fatal(err) @@ -62,16 +62,16 @@ func TestTMFmtLogger(t *testing.T) { } func BenchmarkTMFmtLoggerSimple(b *testing.B) { - benchmarkRunnerKitlog(b, log.NewTMFmtLogger(ioutil.Discard), baseMessage) + benchmarkRunnerKitlog(b, log.NewOCFmtLogger(ioutil.Discard), baseMessage) } func BenchmarkTMFmtLoggerContextual(b *testing.B) { - benchmarkRunnerKitlog(b, log.NewTMFmtLogger(ioutil.Discard), withMessage) + benchmarkRunnerKitlog(b, log.NewOCFmtLogger(ioutil.Discard), withMessage) } func TestTMFmtLoggerConcurrency(t *testing.T) { t.Parallel() - testConcurrency(t, log.NewTMFmtLogger(ioutil.Discard), 10000) + testConcurrency(t, log.NewOCFmtLogger(ioutil.Discard), 10000) } func benchmarkRunnerKitlog(b *testing.B, logger kitlog.Logger, f func(kitlog.Logger)) { diff --git a/libs/log/testing_logger.go b/libs/log/testing_logger.go index 8914bd81f..ff97934bd 100644 --- a/libs/log/testing_logger.go +++ b/libs/log/testing_logger.go @@ -35,7 +35,7 @@ func TestingLoggerWithOutput(w io.Writer) Logger { } if testing.Verbose() { - _testingLogger = NewTMLogger(NewSyncWriter(w)) + _testingLogger = NewOCLogger(NewSyncWriter(w)) } else { _testingLogger = NewNopLogger() } @@ -51,7 +51,7 @@ func TestingLoggerWithColorFn(colorFn func(keyvals ...interface{}) term.FgBgColo } if testing.Verbose() { - _testingLogger = NewTMLoggerWithColorFn(NewSyncWriter(os.Stdout), colorFn) + _testingLogger = NewOCLoggerWithColorFn(NewSyncWriter(os.Stdout), colorFn) } else { _testingLogger = NewNopLogger() } diff --git a/libs/log/tracing_logger_test.go b/libs/log/tracing_logger_test.go index e95c5f2de..e41684782 100644 --- a/libs/log/tracing_logger_test.go +++ b/libs/log/tracing_logger_test.go @@ -15,7 +15,7 @@ import ( func TestTracingLogger(t *testing.T) { var buf bytes.Buffer - logger := log.NewTMJSONLoggerNoTS(&buf) + logger := log.NewOCJSONLoggerNoTS(&buf) logger1 := log.NewTracingLogger(logger) err1 := errors.New("courage is grace under pressure") diff --git a/light/client_benchmark_test.go b/light/client_benchmark_test.go index c4de860d8..89fbb44a6 100644 --- a/light/client_benchmark_test.go +++ b/light/client_benchmark_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - dbm "github.com/tendermint/tm-db" + "github.com/line/tm-db/v2/memdb" "github.com/line/ostracon/libs/log" "github.com/line/ostracon/light" @@ -38,7 +38,7 @@ func BenchmarkSequence(b *testing.B) { }, benchmarkFullNode, []provider.Provider{benchmarkFullNode}, - dbs.New(dbm.NewMemDB(), chainID), + dbs.New(memdb.NewDB(), chainID), types.DefaultVoterParams(), light.Logger(log.TestingLogger()), light.SequentialVerification(), @@ -67,7 +67,7 @@ func BenchmarkBisection(b *testing.B) { }, benchmarkFullNode, []provider.Provider{benchmarkFullNode}, - dbs.New(dbm.NewMemDB(), chainID), + dbs.New(memdb.NewDB(), chainID), types.DefaultVoterParams(), light.Logger(log.TestingLogger()), ) @@ -96,7 +96,7 @@ func BenchmarkBackwards(b *testing.B) { }, benchmarkFullNode, []provider.Provider{benchmarkFullNode}, - dbs.New(dbm.NewMemDB(), chainID), + dbs.New(memdb.NewDB(), chainID), types.DefaultVoterParams(), light.Logger(log.TestingLogger()), ) diff --git a/light/client_test.go b/light/client_test.go index f942253df..b4f2eb9f4 100644 --- a/light/client_test.go +++ b/light/client_test.go @@ -7,10 +7,7 @@ import ( "time" tmrand "github.com/line/ostracon/libs/rand" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - dbm "github.com/tendermint/tm-db" + "github.com/line/tm-db/v2/memdb" "github.com/line/ostracon/crypto/ed25519" "github.com/line/ostracon/crypto/vrf" @@ -21,6 +18,8 @@ import ( mockp "github.com/line/ostracon/light/provider/mock" dbs "github.com/line/ostracon/light/store/db" "github.com/line/ostracon/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) const ( @@ -298,7 +297,7 @@ func TestClient_SequentialVerification(t *testing.T) { tc.vals, tc.voters, )}, - dbs.New(dbm.NewMemDB(), chainID), + dbs.New(memdb.NewDB(), chainID), voterParam, light.SequentialVerification(), light.Logger(log.TestingLogger()), @@ -474,7 +473,7 @@ func TestClient_SkippingVerification(t *testing.T) { tc.vals, tc.voters, )}, - dbs.New(dbm.NewMemDB(), chainID), + dbs.New(memdb.NewDB(), chainID), voterParam, light.SkippingVerification(light.DefaultTrustLevel), light.Logger(log.TestingLogger()), @@ -513,7 +512,7 @@ func TestClientLargeBisectionVerification(t *testing.T) { }, veryLargeFullNode, []provider.Provider{veryLargeFullNode}, - dbs.New(dbm.NewMemDB(), chainID), + dbs.New(memdb.NewDB(), chainID), voterParam, light.SequentialVerification(), ) @@ -536,7 +535,7 @@ func TestClientBisectionBetweenTrustedHeaders(t *testing.T) { }, fullNode, []provider.Provider{fullNode}, - dbs.New(dbm.NewMemDB(), chainID), + dbs.New(memdb.NewDB(), chainID), voterParam, light.SequentialVerification(), ) @@ -561,7 +560,7 @@ func TestClient_Cleanup(t *testing.T) { trustOptions, fullNode, []provider.Provider{fullNode}, - dbs.New(dbm.NewMemDB(), chainID), + dbs.New(memdb.NewDB(), chainID), voterParam, light.Logger(log.TestingLogger()), ) @@ -582,7 +581,7 @@ func TestClient_Cleanup(t *testing.T) { func TestClientRestoresTrustedHeaderAfterStartup1(t *testing.T) { // 1. options.Hash == trustedHeader.Hash { - trustedStore := dbs.New(dbm.NewMemDB(), chainID) + trustedStore := dbs.New(memdb.NewDB(), chainID) err := trustedStore.SaveLightBlock(l1) require.NoError(t, err) @@ -607,7 +606,7 @@ func TestClientRestoresTrustedHeaderAfterStartup1(t *testing.T) { // 2. options.Hash != trustedHeader.Hash { - trustedStore := dbs.New(dbm.NewMemDB(), chainID) + trustedStore := dbs.New(memdb.NewDB(), chainID) err := trustedStore.SaveLightBlock(l1) require.NoError(t, err) @@ -657,7 +656,7 @@ func TestClientRestoresTrustedHeaderAfterStartup1(t *testing.T) { func TestClientRestoresTrustedHeaderAfterStartup2(t *testing.T) { // 1. options.Hash == trustedHeader.Hash { - trustedStore := dbs.New(dbm.NewMemDB(), chainID) + trustedStore := dbs.New(memdb.NewDB(), chainID) err := trustedStore.SaveLightBlock(l1) require.NoError(t, err) @@ -688,7 +687,7 @@ func TestClientRestoresTrustedHeaderAfterStartup2(t *testing.T) { // 2. options.Hash != trustedHeader.Hash // This could happen if previous provider was lying to us. { - trustedStore := dbs.New(dbm.NewMemDB(), chainID) + trustedStore := dbs.New(memdb.NewDB(), chainID) err := trustedStore.SaveLightBlock(l1) require.NoError(t, err) @@ -742,7 +741,7 @@ func TestClientRestoresTrustedHeaderAfterStartup3(t *testing.T) { // 1. options.Hash == trustedHeader.Hash { // load the first three headers into the trusted store - trustedStore := dbs.New(dbm.NewMemDB(), chainID) + trustedStore := dbs.New(memdb.NewDB(), chainID) err := trustedStore.SaveLightBlock(l1) require.NoError(t, err) @@ -781,7 +780,7 @@ func TestClientRestoresTrustedHeaderAfterStartup3(t *testing.T) { // 2. options.Hash != trustedHeader.Hash // This could happen if previous provider was lying to us. { - trustedStore := dbs.New(dbm.NewMemDB(), chainID) + trustedStore := dbs.New(memdb.NewDB(), chainID) err := trustedStore.SaveLightBlock(l1) require.NoError(t, err) @@ -845,7 +844,7 @@ func TestClient_Update(t *testing.T) { trustOptions, fullNode, []provider.Provider{fullNode}, - dbs.New(dbm.NewMemDB(), chainID), + dbs.New(memdb.NewDB(), chainID), voterParam, light.Logger(log.TestingLogger()), ) @@ -867,7 +866,7 @@ func TestClient_Concurrency(t *testing.T) { trustOptions, fullNode, []provider.Provider{fullNode}, - dbs.New(dbm.NewMemDB(), chainID), + dbs.New(memdb.NewDB(), chainID), voterParam, light.Logger(log.TestingLogger()), ) @@ -909,7 +908,7 @@ func TestClientReplacesPrimaryWithWitnessIfPrimaryIsUnavailable(t *testing.T) { trustOptions, deadNode, []provider.Provider{fullNode, fullNode}, - dbs.New(dbm.NewMemDB(), chainID), + dbs.New(memdb.NewDB(), chainID), voterParam, light.Logger(log.TestingLogger()), light.MaxRetryAttempts(1), @@ -936,7 +935,7 @@ func TestClient_BackwardsVerification(t *testing.T) { }, largeFullNode, []provider.Provider{largeFullNode}, - dbs.New(dbm.NewMemDB(), chainID), + dbs.New(memdb.NewDB(), chainID), voterParam, light.Logger(log.TestingLogger()), ) @@ -1023,7 +1022,7 @@ func TestClient_BackwardsVerification(t *testing.T) { }, tc.provider, []provider.Provider{tc.provider}, - dbs.New(dbm.NewMemDB(), chainID), + dbs.New(memdb.NewDB(), chainID), voterParam, light.Logger(log.TestingLogger()), ) @@ -1037,7 +1036,7 @@ func TestClient_BackwardsVerification(t *testing.T) { func TestClient_NewClientFromTrustedStore(t *testing.T) { // 1) Initiate DB and fill with a "trusted" header - db := dbs.New(dbm.NewMemDB(), chainID) + db := dbs.New(memdb.NewDB(), chainID) err := db.SaveLightBlock(l1) require.NoError(t, err) @@ -1105,7 +1104,7 @@ func TestClientRemovesWitnessIfItSendsUsIncorrectHeader(t *testing.T) { trustOptions, fullNode, []provider.Provider{badProvider1, badProvider2}, - dbs.New(dbm.NewMemDB(), chainID), + dbs.New(memdb.NewDB(), chainID), voterParam, light.Logger(log.TestingLogger()), light.MaxRetryAttempts(1), @@ -1161,7 +1160,7 @@ func TestClient_TrustedValidatorSet(t *testing.T) { trustOptions, fullNode, []provider.Provider{badVoterSetNode, fullNode}, - dbs.New(dbm.NewMemDB(), chainID), + dbs.New(memdb.NewDB(), chainID), voterParam, light.Logger(log.TestingLogger()), ) @@ -1180,7 +1179,7 @@ func TestClientPrunesHeadersAndValidatorSets(t *testing.T) { trustOptions, fullNode, []provider.Provider{fullNode}, - dbs.New(dbm.NewMemDB(), chainID), + dbs.New(memdb.NewDB(), chainID), voterParam, light.Logger(log.TestingLogger()), light.PruningSize(1), @@ -1270,7 +1269,7 @@ func TestClientEnsureValidHeadersAndValSets(t *testing.T) { trustOptions, badNode, []provider.Provider{badNode, badNode}, - dbs.New(dbm.NewMemDB(), chainID), + dbs.New(memdb.NewDB(), chainID), voterParam, light.MaxRetryAttempts(1), ) diff --git a/light/detector_test.go b/light/detector_test.go index 975863bcb..aaba17985 100644 --- a/light/detector_test.go +++ b/light/detector_test.go @@ -4,11 +4,10 @@ import ( "testing" "time" + "github.com/line/tm-db/v2/memdb" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - dbm "github.com/tendermint/tm-db" - "github.com/line/ostracon/libs/log" "github.com/line/ostracon/light" "github.com/line/ostracon/light/provider" @@ -19,7 +18,7 @@ import ( func TestLightClientAttackEvidence_Lunatic(t *testing.T) { t.Skip("Voter selection in Ostracon only supports sequential verification mode, " + - "but Tendermint has a few test case for skipping mode.") + "but Ostracon has a few test case for skipping mode.") // primary performs a lunatic attack var ( latestHeight = int64(10) @@ -66,7 +65,7 @@ func TestLightClientAttackEvidence_Lunatic(t *testing.T) { }, primary, []provider.Provider{witness}, - dbs.New(dbm.NewMemDB(), chainID), + dbs.New(memdb.NewDB(), chainID), types.DefaultVoterParams(), light.Logger(log.TestingLogger()), light.MaxRetryAttempts(1), @@ -106,7 +105,7 @@ func TestLightClientAttackEvidence_Lunatic(t *testing.T) { func TestLightClientAttackEvidence_Equivocation(t *testing.T) { t.Skip("Voter selection in Ostracon only supports sequential verification mode, " + - "but Tendermint has a few test case for skipping mode.") + "but Ostracon has a few test case for skipping mode.") verificationOptions := map[string]light.Option{ "sequential": light.SequentialVerification(), "skipping": light.SkippingVerification(light.DefaultTrustLevel), @@ -158,7 +157,7 @@ func TestLightClientAttackEvidence_Equivocation(t *testing.T) { }, primary, []provider.Provider{witness}, - dbs.New(dbm.NewMemDB(), chainID), + dbs.New(memdb.NewDB(), chainID), types.DefaultVoterParams(), light.Logger(log.TestingLogger()), light.MaxRetryAttempts(1), @@ -216,7 +215,7 @@ func TestClientDivergentTraces1(t *testing.T) { }, primary, []provider.Provider{witness}, - dbs.New(dbm.NewMemDB(), chainID), + dbs.New(memdb.NewDB(), chainID), types.DefaultVoterParams(), light.Logger(log.TestingLogger()), light.MaxRetryAttempts(1), @@ -241,7 +240,7 @@ func TestClientDivergentTraces2(t *testing.T) { }, primary, []provider.Provider{deadNode, deadNode, primary}, - dbs.New(dbm.NewMemDB(), chainID), + dbs.New(memdb.NewDB(), chainID), types.DefaultVoterParams(), light.Logger(log.TestingLogger()), light.MaxRetryAttempts(1), @@ -278,7 +277,7 @@ func TestClientDivergentTraces3(t *testing.T) { }, primary, []provider.Provider{witness}, - dbs.New(dbm.NewMemDB(), chainID), + dbs.New(memdb.NewDB(), chainID), types.DefaultVoterParams(), light.Logger(log.TestingLogger()), light.MaxRetryAttempts(1), diff --git a/light/doc.go b/light/doc.go index 700bbeb6c..68ae50625 100644 --- a/light/doc.go +++ b/light/doc.go @@ -5,11 +5,11 @@ The concept of light clients was introduced in the Bitcoin white paper. It describes a watcher of distributed consensus process that only validates the consensus algorithm and not the state machine transactions within. -Tendermint light clients allow bandwidth & compute-constrained devices, such as +Ostracon light clients allow bandwidth & compute-constrained devices, such as smartphones, low-power embedded chips, or other blockchains to efficiently -verify the consensus of a Tendermint blockchain. This forms the basis of safe +verify the consensus of an Ostracon blockchain. This forms the basis of safe and efficient state synchronization for new network nodes and inter-blockchain -communication (where a light client of one Tendermint instance runs in another +communication (where a light client of one Ostracon instance runs in another chain's state machine). In a network that is expected to reliably punish validators for misbehavior by @@ -28,7 +28,7 @@ fork the network at some point in its prior history. See Vitalik's post at [Proof of Stake: How I Learned to Love Weak Subjectivity](https://blog.ethereum.org/2014/11/25/proof-stake-learned-love-weak-subjectivity/). -NOTE: Tendermint provides a somewhat different (stronger) light client model +NOTE: Ostracon provides a somewhat different (stronger) light client model than Bitcoin under eclipse, since the eclipsing node(s) can only fool the light client if they have two-thirds of the private keys from the last root-of-trust. @@ -111,7 +111,7 @@ refer to docs/imgs/light_client_bisection_alg.png ## 3. Secure RPC proxy -Tendermint RPC exposes a lot of info, but a malicious node could return any +Ostracon RPC exposes a lot of info, but a malicious node could return any data it wants to queries, or even to block headers, even making up fake signatures from non-existent validators to justify it. Secure RPC proxy serves as a wrapper, which verifies all the headers, using a light client connected to diff --git a/light/example_test.go b/light/example_test.go index 65bdda01f..eee1d4d8a 100644 --- a/light/example_test.go +++ b/light/example_test.go @@ -10,8 +10,7 @@ import ( "time" "github.com/line/ostracon/types" - - dbm "github.com/tendermint/tm-db" + "github.com/line/tm-db/v2/goleveldb" "github.com/line/ostracon/abci/example/kvstore" "github.com/line/ostracon/libs/log" @@ -24,7 +23,7 @@ import ( // Automatically getting new headers and verifying them. func ExampleClient_Update() { - // give Tendermint time to generate some blocks + // give Ostracon time to generate some blocks time.Sleep(5 * time.Second) dbDir, err := ioutil.TempDir("", "light-client-example") @@ -48,7 +47,7 @@ func ExampleClient_Update() { stdlog.Fatal(err) } - db, err := dbm.NewGoLevelDB("light-client-db", dbDir) + db, err := goleveldb.NewDB("light-client-db", dbDir) if err != nil { stdlog.Fatal(err) } @@ -93,7 +92,7 @@ func ExampleClient_Update() { // Manually getting light blocks and verifying them. func ExampleClient_VerifyLightBlockAtHeight() { - // give Tendermint time to generate some blocks + // give Ostracon time to generate some blocks time.Sleep(5 * time.Second) dbDir, err := ioutil.TempDir("", "light-client-example") @@ -117,7 +116,7 @@ func ExampleClient_VerifyLightBlockAtHeight() { stdlog.Fatal(err) } - db, err := dbm.NewGoLevelDB("light-client-db", dbDir) + db, err := goleveldb.NewDB("light-client-db", dbDir) if err != nil { stdlog.Fatal(err) } @@ -162,11 +161,11 @@ func ExampleClient_VerifyLightBlockAtHeight() { func TestMain(m *testing.M) { // start an ostracon node (and kvstore) in the background to test against app := kvstore.NewApplication() - node := rpctest.StartTendermint(app, rpctest.SuppressStdout) + node := rpctest.StartOstracon(app, rpctest.SuppressStdout) code := m.Run() // and shut down proper at the end - rpctest.StopTendermint(node) + rpctest.StopOstracon(node) os.Exit(code) } diff --git a/light/provider/http/http_test.go b/light/provider/http/http_test.go index 8dd9a0134..21cf177a3 100644 --- a/light/provider/http/http_test.go +++ b/light/provider/http/http_test.go @@ -35,11 +35,11 @@ func TestNewProvider(t *testing.T) { func TestMain(m *testing.M) { app := kvstore.NewApplication() app.RetainBlocks = 9 - node := rpctest.StartTendermint(app) + node := rpctest.StartOstracon(app) code := m.Run() - rpctest.StopTendermint(node) + rpctest.StopOstracon(node) os.Exit(code) } diff --git a/light/rpc/client_test.go b/light/rpc/client_test.go index 9a0213e47..2505fc7bd 100644 --- a/light/rpc/client_test.go +++ b/light/rpc/client_test.go @@ -7,11 +7,6 @@ import ( "testing" ics23 "github.com/confio/ics23/go" - "github.com/cosmos/iavl" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - dbm "github.com/tendermint/tm-db" abci "github.com/line/ostracon/abci/types" "github.com/line/ostracon/crypto/merkle" @@ -21,26 +16,41 @@ import ( rpcmock "github.com/line/ostracon/rpc/client/mocks" ctypes "github.com/line/ostracon/rpc/core/types" "github.com/line/ostracon/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" ) // TestABCIQuery tests ABCIQuery requests and verifies proofs. HAPPY PATH 😀 func TestABCIQuery(t *testing.T) { - tree, err := iavl.NewMutableTree(dbm.NewMemDB(), 100) - require.NoError(t, err) - var ( key = []byte("foo") value = []byte("bar") ) - tree.Set(key, value) - commitmentProof, err := tree.GetMembershipProof(key) + // You can get this proof binary with following code. + proof := []byte{10, 23, 10, 3, 102, 111, 111, 18, 3, 98, 97, 114, 26, 11, 8, 1, 24, 1, 32, 1, 42, 3, 0, 2, 2} + var commitmentProof ics23.CommitmentProof + err := commitmentProof.Unmarshal(proof) require.NoError(t, err) + // We comment out this code to remove the dependency of iavl + /* + tree, err := iavl.NewMutableTree(memdb.NewDB(), 100) + require.NoError(t, err) + + tree.Set(key, value) + + commitmentProof, err := tree.GetMembershipProof(key) + require.NoError(t, err) + data, _ := commitmentProof.Marshal() + fmt.Printf("%v\n", data) + */ + op := &testOp{ Spec: ics23.IavlSpec, Key: key, - Proof: commitmentProof, + Proof: &commitmentProof, } next := &rpcmock.Client{} diff --git a/light/store/db/db.go b/light/store/db/db.go index 8746986af..d427580fd 100644 --- a/light/store/db/db.go +++ b/light/store/db/db.go @@ -6,7 +6,7 @@ import ( "regexp" "strconv" - dbm "github.com/tendermint/tm-db" + dbm "github.com/line/tm-db/v2" tmsync "github.com/line/ostracon/libs/sync" "github.com/line/ostracon/light/store" diff --git a/light/store/db/db_test.go b/light/store/db/db_test.go index 33dc3c086..89b8b5cf4 100644 --- a/light/store/db/db_test.go +++ b/light/store/db/db_test.go @@ -5,11 +5,10 @@ import ( "testing" "time" + "github.com/line/tm-db/v2/memdb" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - dbm "github.com/tendermint/tm-db" - "github.com/line/ostracon/crypto" "github.com/line/ostracon/crypto/tmhash" tmrand "github.com/line/ostracon/libs/rand" @@ -19,7 +18,7 @@ import ( ) func TestLast_FirstLightBlockHeight(t *testing.T) { - dbStore := New(dbm.NewMemDB(), "TestLast_FirstLightBlockHeight") + dbStore := New(memdb.NewDB(), "TestLast_FirstLightBlockHeight") // Empty store height, err := dbStore.LastLightBlockHeight() @@ -44,7 +43,7 @@ func TestLast_FirstLightBlockHeight(t *testing.T) { } func Test_SaveLightBlock(t *testing.T) { - dbStore := New(dbm.NewMemDB(), "Test_SaveLightBlockAndValidatorSet") + dbStore := New(memdb.NewDB(), "Test_SaveLightBlockAndValidatorSet") // Empty store h, err := dbStore.LightBlock(1) @@ -74,7 +73,7 @@ func Test_SaveLightBlock(t *testing.T) { } func Test_LightBlockBefore(t *testing.T) { - dbStore := New(dbm.NewMemDB(), "Test_LightBlockBefore") + dbStore := New(memdb.NewDB(), "Test_LightBlockBefore") assert.Panics(t, func() { _, _ = dbStore.LightBlockBefore(0) @@ -92,7 +91,7 @@ func Test_LightBlockBefore(t *testing.T) { } func Test_Prune(t *testing.T) { - dbStore := New(dbm.NewMemDB(), "Test_Prune") + dbStore := New(memdb.NewDB(), "Test_Prune") // Empty store assert.EqualValues(t, 0, dbStore.Size()) @@ -129,7 +128,7 @@ func Test_Prune(t *testing.T) { } func Test_Concurrency(t *testing.T) { - dbStore := New(dbm.NewMemDB(), "Test_Prune") + dbStore := New(memdb.NewDB(), "Test_Prune") var wg sync.WaitGroup for i := 1; i <= 100; i++ { diff --git a/mempool/bench_test.go b/mempool/bench_test.go index 18767408a..5242d6523 100644 --- a/mempool/bench_test.go +++ b/mempool/bench_test.go @@ -18,9 +18,7 @@ func BenchmarkReap(b *testing.B) { for i := 0; i < size; i++ { tx := make([]byte, 8) binary.BigEndian.PutUint64(tx, uint64(i)) - if err := mempool.CheckTx(tx, nil, TxInfo{}); err != nil { - b.Error(err) - } + mempool.CheckTxSync(tx, TxInfo{}) // nolint: errcheck } b.ResetTimer() for i := 0; i < b.N; i++ { @@ -28,7 +26,38 @@ func BenchmarkReap(b *testing.B) { } } -func BenchmarkCheckTx(b *testing.B) { +func BenchmarkReapWithCheckTxAsync(b *testing.B) { + app := kvstore.NewApplication() + cc := proxy.NewLocalClientCreator(app) + mempool, cleanup := newMempoolWithApp(cc) + defer cleanup() + + size := 10000 + for i := 0; i < size; i++ { + tx := make([]byte, 8) + binary.BigEndian.PutUint64(tx, uint64(i)) + mempool.CheckTxAsync(tx, TxInfo{}, nil, nil) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + mempool.ReapMaxBytesMaxGas(100000000, 10000000) + } +} + +func BenchmarkCheckTxSync(b *testing.B) { + app := kvstore.NewApplication() + cc := proxy.NewLocalClientCreator(app) + mempool, cleanup := newMempoolWithApp(cc) + defer cleanup() + + for i := 0; i < b.N; i++ { + tx := make([]byte, 8) + binary.BigEndian.PutUint64(tx, uint64(i)) + mempool.CheckTxSync(tx, TxInfo{}) // nolint: errcheck + } +} + +func BenchmarkCheckTxAsync(b *testing.B) { app := kvstore.NewApplication() cc := proxy.NewLocalClientCreator(app) mempool, cleanup := newMempoolWithApp(cc) @@ -37,9 +66,7 @@ func BenchmarkCheckTx(b *testing.B) { for i := 0; i < b.N; i++ { tx := make([]byte, 8) binary.BigEndian.PutUint64(tx, uint64(i)) - if err := mempool.CheckTx(tx, nil, TxInfo{}); err != nil { - b.Error(err) - } + mempool.CheckTxAsync(tx, TxInfo{}, nil, nil) } } diff --git a/mempool/cache_test.go b/mempool/cache_test.go index 2187fed45..072c3f03a 100644 --- a/mempool/cache_test.go +++ b/mempool/cache_test.go @@ -59,7 +59,7 @@ func TestCacheAfterUpdate(t *testing.T) { for tcIndex, tc := range tests { for i := 0; i < tc.numTxsToCreate; i++ { tx := types.Tx{byte(i)} - err := mempool.CheckTx(tx, nil, TxInfo{}) + _, err := mempool.CheckTxSync(tx, TxInfo{}) require.NoError(t, err) } @@ -68,12 +68,13 @@ func TestCacheAfterUpdate(t *testing.T) { tx := types.Tx{byte(v)} updateTxs = append(updateTxs, tx) } - err := mempool.Update(int64(tcIndex), updateTxs, abciResponses(len(updateTxs), abci.CodeTypeOK), nil, nil) + err := mempool.Update(newTestBlock(int64(tcIndex), updateTxs), + abciResponses(len(updateTxs), abci.CodeTypeOK), nil) require.NoError(t, err) for _, v := range tc.reAddIndices { tx := types.Tx{byte(v)} - _ = mempool.CheckTx(tx, nil, TxInfo{}) + _, _ = mempool.CheckTxSync(tx, TxInfo{}) } cache := mempool.cache.(*mapTxCache) diff --git a/mempool/clist_mempool.go b/mempool/clist_mempool.go index 592755215..0274df8f5 100644 --- a/mempool/clist_mempool.go +++ b/mempool/clist_mempool.go @@ -1,12 +1,12 @@ package mempool import ( - "bytes" "container/list" "crypto/sha256" "fmt" "sync" "sync/atomic" + "time" abci "github.com/line/ostracon/abci/types" cfg "github.com/line/ostracon/config" @@ -17,6 +17,7 @@ import ( tmos "github.com/line/ostracon/libs/os" tmsync "github.com/line/ostracon/libs/sync" "github.com/line/ostracon/p2p" + tmproto "github.com/line/ostracon/proto/ostracon/types" "github.com/line/ostracon/proxy" "github.com/line/ostracon/types" ) @@ -38,6 +39,10 @@ type CListMempool struct { height int64 // the last block Update()'d to txsBytes int64 // total size of mempool, in bytes + reserved int // the number of checking tx and it should be considered when checking mempool full + reservedBytes int64 // size of checking tx and it should be considered when checking mempool full + reservedMtx sync.Mutex + // notify listeners (ie. consensus) when txs are available notifiedTxsAvailable bool txsAvailable chan struct{} // fires once for each height, when the mempool is not empty @@ -48,18 +53,13 @@ type CListMempool struct { // CheckTx or ReapMaxBytesMaxGas(ReapMaxTxs) methods. updateMtx tmsync.RWMutex preCheck PreCheckFunc - postCheck PostCheckFunc + + chReqCheckTx chan *requestCheckTxAsync wal *auto.AutoFile // a log of mempool txs txs *clist.CList // concurrent linked-list of good txs proxyAppConn proxy.AppConnMempool - // Track whether we're rechecking txs. - // These are not protected by a mutex and are expected to be mutated in - // serial (ie. by abci responses which are called in serial). - recheckCursor *clist.CElement // next expected response - recheckEnd *clist.CElement // re-checking stops here - // Map for quick access to txs to record sender in CheckTx. // txsMap: txKey -> CElement txsMap sync.Map @@ -73,6 +73,13 @@ type CListMempool struct { metrics *Metrics } +type requestCheckTxAsync struct { + tx types.Tx + txInfo TxInfo + prepareCb func(error) + checkTxCb func(*abci.Response) +} + var _ Mempool = &CListMempool{} // CListMempoolOption sets an optional parameter on the mempool. @@ -86,24 +93,24 @@ func NewCListMempool( options ...CListMempoolOption, ) *CListMempool { mempool := &CListMempool{ - config: config, - proxyAppConn: proxyAppConn, - txs: clist.New(), - height: height, - recheckCursor: nil, - recheckEnd: nil, - logger: log.NewNopLogger(), - metrics: NopMetrics(), + config: config, + proxyAppConn: proxyAppConn, + txs: clist.New(), + height: height, + chReqCheckTx: make(chan *requestCheckTxAsync, config.Size), + logger: log.NewNopLogger(), + metrics: NopMetrics(), } if config.CacheSize > 0 { mempool.cache = newMapTxCache(config.CacheSize) } else { mempool.cache = nopTxCache{} } - proxyAppConn.SetResponseCallback(mempool.globalCb) + proxyAppConn.SetGlobalCallback(mempool.globalCb) for _, option := range options { option(mempool) } + go mempool.checkTxAsyncReactor() return mempool } @@ -124,13 +131,6 @@ func WithPreCheck(f PreCheckFunc) CListMempoolOption { return func(mem *CListMempool) { mem.preCheck = f } } -// WithPostCheck sets a filter for the mempool to reject a tx if f(tx) returns -// false. This is ran after CheckTx. Only applies to the first created block. -// After that, Update overwrites the existing value. -func WithPostCheck(f PostCheckFunc) CListMempoolOption { - return func(mem *CListMempool) { mem.postCheck = f } -} - // WithMetrics sets the metrics. func WithMetrics(metrics *Metrics) CListMempoolOption { return func(mem *CListMempool) { mem.metrics = metrics } @@ -185,13 +185,14 @@ func (mem *CListMempool) TxsBytes() int64 { // Lock() must be help by the caller during execution. func (mem *CListMempool) FlushAppConn() error { - return mem.proxyAppConn.FlushSync() + _, err := mem.proxyAppConn.FlushSync() + return err } // XXX: Unsafe! Calling Flush may leave mempool in inconsistent state. func (mem *CListMempool) Flush() { - mem.updateMtx.RLock() - defer mem.updateMtx.RUnlock() + mem.updateMtx.Lock() + defer mem.updateMtx.Unlock() _ = atomic.SwapInt64(&mem.txsBytes, 0) mem.cache.Reset() @@ -226,16 +227,76 @@ func (mem *CListMempool) TxsWaitChan() <-chan struct{} { } // It blocks if we're waiting on Update() or Reap(). +// Safe for concurrent use by multiple goroutines. +func (mem *CListMempool) CheckTxSync(tx types.Tx, txInfo TxInfo) (res *abci.Response, err error) { + mem.updateMtx.RLock() + // use defer to unlock mutex because application (*local client*) might panic + defer mem.updateMtx.RUnlock() + + if err = mem.prepareCheckTx(tx, txInfo); err != nil { + return res, err + } + + // CONTRACT: `app.CheckTxSync()` should check whether `GasWanted` is valid (0 <= GasWanted <= block.masGas) + var r *abci.ResponseCheckTx + r, err = mem.proxyAppConn.CheckTxSync(abci.RequestCheckTx{Tx: tx}) + if err != nil { + return res, err + } + + res = abci.ToResponseCheckTx(*r) + mem.reqResCb(tx, txInfo.SenderID, txInfo.SenderP2PID, res, nil) + return res, err +} + // cb: A callback from the CheckTx command. // It gets called from another goroutine. -// CONTRACT: Either cb will get called, or err returned. // // Safe for concurrent use by multiple goroutines. -func (mem *CListMempool) CheckTx(tx types.Tx, cb func(*abci.Response), txInfo TxInfo) error { +func (mem *CListMempool) CheckTxAsync(tx types.Tx, txInfo TxInfo, prepareCb func(error), + checkTxCb func(*abci.Response)) { + mem.chReqCheckTx <- &requestCheckTxAsync{tx: tx, txInfo: txInfo, prepareCb: prepareCb, checkTxCb: checkTxCb} +} + +func (mem *CListMempool) checkTxAsyncReactor() { + for req := range mem.chReqCheckTx { + mem.checkTxAsync(req.tx, req.txInfo, req.prepareCb, req.checkTxCb) + } +} + +// It blocks if we're waiting on Update() or Reap(). +func (mem *CListMempool) checkTxAsync(tx types.Tx, txInfo TxInfo, prepareCb func(error), + checkTxCb func(*abci.Response)) { mem.updateMtx.RLock() - // use defer to unlock mutex because application (*local client*) might panic - defer mem.updateMtx.RUnlock() + defer func() { + if r := recover(); r != nil { + mem.updateMtx.RUnlock() + panic(r) + } + }() + + err := mem.prepareCheckTx(tx, txInfo) + if prepareCb != nil { + prepareCb(err) + } + if err != nil { + mem.updateMtx.RUnlock() + return + } + // CONTRACT: `app.CheckTxAsync()` should check whether `GasWanted` is valid (0 <= GasWanted <= block.masGas) + mem.proxyAppConn.CheckTxAsync(abci.RequestCheckTx{Tx: tx}, func(res *abci.Response) { + mem.reqResCb(tx, txInfo.SenderID, txInfo.SenderP2PID, res, func(response *abci.Response) { + if checkTxCb != nil { + checkTxCb(response) + } + mem.updateMtx.RUnlock() + }) + }) +} + +// CONTRACT: `caller` should held `mem.updateMtx.RLock()` +func (mem *CListMempool) prepareCheckTx(tx types.Tx, txInfo TxInfo) error { txSize := len(tx) if err := mem.isFull(txSize); err != nil { @@ -285,8 +346,12 @@ func (mem *CListMempool) CheckTx(tx types.Tx, cb func(*abci.Response), txInfo Tx return ErrTxInCache } - reqRes := mem.proxyAppConn.CheckTxAsync(abci.RequestCheckTx{Tx: tx}) - reqRes.SetCallback(mem.reqResCb(tx, txInfo.SenderID, txInfo.SenderP2PID, cb)) + // reserve mempool that should be called just before calling `mem.proxyAppConn.CheckTxAsync()` + if err := mem.reserve(int64(txSize)); err != nil { + // remove from cache + mem.cache.Remove(tx) + return err + } return nil } @@ -301,15 +366,18 @@ func (mem *CListMempool) CheckTx(tx types.Tx, cb func(*abci.Response), txInfo Tx // When rechecking, we don't need the peerID, so the recheck callback happens // here. func (mem *CListMempool) globalCb(req *abci.Request, res *abci.Response) { - if mem.recheckCursor == nil { + checkTxReq := req.GetCheckTx() + if checkTxReq == nil { return } - mem.metrics.RecheckTimes.Add(1) - mem.resCbRecheck(req, res) + if checkTxReq.Type == abci.CheckTxType_Recheck { + mem.metrics.RecheckCount.Add(1) + mem.resCbRecheck(req, res) - // update metrics - mem.metrics.Size.Set(float64(mem.Size())) + // update metrics + mem.metrics.Size.Set(float64(mem.Size())) + } } // Request specific callback that should be set on individual reqRes objects @@ -325,23 +393,17 @@ func (mem *CListMempool) reqResCb( tx []byte, peerID uint16, peerP2PID p2p.ID, + res *abci.Response, externalCb func(*abci.Response), -) func(res *abci.Response) { - return func(res *abci.Response) { - if mem.recheckCursor != nil { - // this should never happen - panic("recheck cursor is not nil in reqResCb") - } - - mem.resCbFirstTime(tx, peerID, peerP2PID, res) +) { + mem.resCbFirstTime(tx, peerID, peerP2PID, res) - // update metrics - mem.metrics.Size.Set(float64(mem.Size())) + // update metrics + mem.metrics.Size.Set(float64(mem.Size())) - // passed in by the caller of CheckTx, eg. the RPC - if externalCb != nil { - externalCb(res) - } + // passed in by the caller of CheckTx, eg. the RPC + if externalCb != nil { + externalCb(res) } } @@ -394,6 +456,35 @@ func (mem *CListMempool) isFull(txSize int) error { return nil } +func (mem *CListMempool) reserve(txSize int64) error { + mem.reservedMtx.Lock() + defer mem.reservedMtx.Unlock() + + var ( + memSize = mem.Size() + txsBytes = mem.TxsBytes() + ) + + if memSize+mem.reserved >= mem.config.Size || txSize+mem.reservedBytes+txsBytes > mem.config.MaxTxsBytes { + return ErrMempoolIsFull{ + memSize + mem.reserved, mem.config.Size, + txsBytes + mem.reservedBytes, mem.config.MaxTxsBytes, + } + } + + mem.reserved++ + mem.reservedBytes += txSize + return nil +} + +func (mem *CListMempool) releaseReserve(txSize int64) { + mem.reservedMtx.Lock() + defer mem.reservedMtx.Unlock() + + mem.reserved-- + mem.reservedBytes -= txSize +} + // callback, which is called after the app checked the tx for the first time. // // The case where the app checks the tx for the second and subsequent times is @@ -406,20 +497,7 @@ func (mem *CListMempool) resCbFirstTime( ) { switch r := res.Value.(type) { case *abci.Response_CheckTx: - var postCheckErr error - if mem.postCheck != nil { - postCheckErr = mem.postCheck(tx, r.CheckTx) - } - if (r.CheckTx.Code == abci.CodeTypeOK) && postCheckErr == nil { - // Check mempool isn't full again to reduce the chance of exceeding the - // limits. - if err := mem.isFull(len(tx)); err != nil { - // remove from cache (mempool might have a space later) - mem.cache.Remove(tx) - mem.logger.Error(err.Error()) - return - } - + if r.CheckTx.Code == abci.CodeTypeOK { memTx := &mempoolTx{ height: mem.height, gasWanted: r.CheckTx.GasWanted, @@ -436,14 +514,17 @@ func (mem *CListMempool) resCbFirstTime( mem.notifyTxsAvailable() } else { // ignore bad transaction - mem.logger.Info("Rejected bad transaction", - "tx", txID(tx), "peerID", peerP2PID, "res", r, "err", postCheckErr) + mem.logger.Debug("rejected bad transaction", + "tx", txID(tx), "peerID", peerP2PID, "res", r) mem.metrics.FailedTxs.Add(1) if !mem.config.KeepInvalidTxsInCache { // remove from cache (it might be good later) mem.cache.Remove(tx) } } + + // release `reserve` regardless it's OK or not (it might be good later) + mem.releaseReserve(int64(len(tx))) default: // ignore other messages } @@ -457,38 +538,19 @@ func (mem *CListMempool) resCbRecheck(req *abci.Request, res *abci.Response) { switch r := res.Value.(type) { case *abci.Response_CheckTx: tx := req.GetCheckTx().Tx - memTx := mem.recheckCursor.Value.(*mempoolTx) - if !bytes.Equal(tx, memTx.tx) { - panic(fmt.Sprintf( - "Unexpected tx response from proxy during recheck\nExpected %X, got %X", - memTx.tx, - tx)) - } - var postCheckErr error - if mem.postCheck != nil { - postCheckErr = mem.postCheck(tx, r.CheckTx) - } - if (r.CheckTx.Code == abci.CodeTypeOK) && postCheckErr == nil { - // Good, nothing to do. - } else { - // Tx became invalidated due to newly committed block. - mem.logger.Info("Tx is no longer valid", "tx", txID(tx), "res", r, "err", postCheckErr) - // NOTE: we remove tx from the cache because it might be good later - mem.removeTx(tx, mem.recheckCursor, !mem.config.KeepInvalidTxsInCache) - } - if mem.recheckCursor == mem.recheckEnd { - mem.recheckCursor = nil - } else { - mem.recheckCursor = mem.recheckCursor.Next() - } - if mem.recheckCursor == nil { - // Done! - mem.logger.Info("Done rechecking txs") - - // incase the recheck removed all txs - if mem.Size() > 0 { - mem.notifyTxsAvailable() + txHash := TxKey(tx) + if e, ok := mem.txsMap.Load(txHash); ok { + celem := e.(*clist.CElement) + if r.CheckTx.Code == abci.CodeTypeOK { + // Good, nothing to do. + } else { + // Tx became invalidated due to newly committed block. + mem.logger.Info("tx is no longer valid", "tx", txID(tx), "res", r) + // NOTE: we remove tx from the cache because it might be good later + mem.removeTx(tx, celem, true) } + } else { + panic(fmt.Sprintf("unexpected tx response from proxy during recheck\ntxHash=%X, tx=%X", txHash, tx)) } default: // ignore other messages @@ -525,13 +587,13 @@ func (mem *CListMempool) ReapMaxBytesMaxGas(maxBytes, maxGas int64) types.Txs { // size per tx, and set the initial capacity based off of that. // txs := make([]types.Tx, 0, tmmath.MinInt(mem.txs.Len(), max/mem.avgTxSize)) txs := make([]types.Tx, 0, mem.txs.Len()) + protoTxs := tmproto.Data{} for e := mem.txs.Front(); e != nil; e = e.Next() { memTx := e.Value.(*mempoolTx) - dataSize := types.ComputeProtoSizeForTxs(append(txs, memTx.tx)) - + protoTxs.Txs = append(protoTxs.Txs, memTx.tx) // Check total size requirement - if maxBytes > -1 && dataSize > maxBytes { + if maxBytes > -1 && int64(protoTxs.Size()) > maxBytes { return txs } // Check total gas requirement. @@ -565,26 +627,21 @@ func (mem *CListMempool) ReapMaxTxs(max int) types.Txs { return txs } -// Lock() must be help by the caller during execution. +// Lock() must be held by the caller during execution. func (mem *CListMempool) Update( - height int64, - txs types.Txs, + block *types.Block, deliverTxResponses []*abci.ResponseDeliverTx, preCheck PreCheckFunc, - postCheck PostCheckFunc, -) error { +) (err error) { // Set height - mem.height = height + mem.height = block.Height mem.notifiedTxsAvailable = false if preCheck != nil { mem.preCheck = preCheck } - if postCheck != nil { - mem.postCheck = postCheck - } - for i, tx := range txs { + for i, tx := range block.Txs { if deliverTxResponses[i].Code == abci.CodeTypeOK { // Add valid committed tx to the cache (if missing). _ = mem.cache.Push(tx) @@ -608,45 +665,71 @@ func (mem *CListMempool) Update( } } - // Either recheck non-committed txs to see if they became invalid - // or just notify there're some txs left. - if mem.Size() > 0 { - if mem.config.Recheck { - mem.logger.Info("Recheck txs", "numtxs", mem.Size(), "height", height) - mem.recheckTxs() - // At this point, mem.txs are being rechecked. - // mem.recheckCursor re-scans mem.txs and possibly removes some txs. - // Before mem.Reap(), we should wait for mem.recheckCursor to be nil. - } else { - mem.notifyTxsAvailable() + if mem.config.Recheck { + // recheck non-committed txs to see if they became invalid + recheckStartTime := time.Now().UnixNano() + + _, err = mem.proxyAppConn.BeginRecheckTxSync(abci.RequestBeginRecheckTx{ + Header: types.OC2PB.Header(&block.Header), + }) + if err != nil { + mem.logger.Error("error in proxyAppConn.BeginRecheckTxSync", "err", err) + } + + mem.logger.Info("recheck txs", "numtxs", mem.Size(), "height", block.Height) + mem.recheckTxs() + + _, err = mem.proxyAppConn.EndRecheckTxSync(abci.RequestEndRecheckTx{Height: block.Height}) + if err != nil { + mem.logger.Error("error in proxyAppConn.EndRecheckTxSync", "err", err) } + + recheckEndTime := time.Now().UnixNano() + + recheckTimeMs := float64(recheckEndTime-recheckStartTime) / 1000000 + mem.metrics.RecheckTime.Set(recheckTimeMs) + + // At this point, mem.txs are being rechecked. + // mem.recheckCursor re-scans mem.txs and possibly removes some txs. + // Before mem.Reap(), we should wait for mem.recheckCursor to be nil. + } + + // notify there're some txs left. + if mem.Size() > 0 { + mem.notifyTxsAvailable() } // Update metrics mem.metrics.Size.Set(float64(mem.Size())) - return nil + return err } func (mem *CListMempool) recheckTxs() { if mem.Size() == 0 { - panic("recheckTxs is called, but the mempool is empty") + return } - mem.recheckCursor = mem.txs.Front() - mem.recheckEnd = mem.txs.Back() + wg := sync.WaitGroup{} // Push txs to proxyAppConn // NOTE: globalCb may be called concurrently. for e := mem.txs.Front(); e != nil; e = e.Next() { + wg.Add(1) + memTx := e.Value.(*mempoolTx) - mem.proxyAppConn.CheckTxAsync(abci.RequestCheckTx{ + req := abci.RequestCheckTx{ Tx: memTx.tx, Type: abci.CheckTxType_Recheck, + } + + mem.proxyAppConn.CheckTxAsync(req, func(res *abci.Response) { + wg.Done() }) } - mem.proxyAppConn.FlushAsync() + mem.proxyAppConn.FlushAsync(func(res *abci.Response) {}) + wg.Wait() } //-------------------------------------------------------------------------------- diff --git a/mempool/clist_mempool_test.go b/mempool/clist_mempool_test.go index 776064cc1..1f0b7c5c1 100644 --- a/mempool/clist_mempool_test.go +++ b/mempool/clist_mempool_test.go @@ -77,7 +77,7 @@ func checkTxs(t *testing.T, mempool Mempool, count int, peerID uint16) types.Txs if err != nil { t.Error(err) } - if err := mempool.CheckTx(txBytes, nil, txInfo); err != nil { + if _, err := mempool.CheckTxSync(txBytes, txInfo); err != nil { // Skip invalid txs. // TestMempoolFilters will fail otherwise. It asserts a number of txs // returned. @@ -100,7 +100,8 @@ func TestReapMaxBytesMaxGas(t *testing.T) { checkTxs(t, mempool, 1, UnknownPeerID) tx0 := mempool.TxsFront().Value.(*mempoolTx) // assert that kv store has gas wanted = 1. - require.Equal(t, app.CheckTx(abci.RequestCheckTx{Tx: tx0.tx}).GasWanted, int64(1), "KVStore had a gas value neq to 1") + require.Equal(t, + app.CheckTxSync(abci.RequestCheckTx{Tx: tx0.tx}).GasWanted, int64(1), "KVStore had a gas value neq to 1") require.Equal(t, tx0.gasWanted, int64(1), "transactions gas was set incorrectly") // ensure each tx is 20 bytes long require.Equal(t, len(tx0.tx), 20, "Tx is longer than 20 bytes") @@ -147,30 +148,23 @@ func TestMempoolFilters(t *testing.T) { emptyTxArr := []types.Tx{[]byte{}} nopPreFilter := func(tx types.Tx) error { return nil } - nopPostFilter := func(tx types.Tx, res *abci.ResponseCheckTx) error { return nil } // each table driven test creates numTxsToCreate txs with checkTx, and at the end clears all remaining txs. // each tx has 20 bytes tests := []struct { numTxsToCreate int preFilter PreCheckFunc - postFilter PostCheckFunc expectedNumTxs int }{ - {10, nopPreFilter, nopPostFilter, 10}, - {10, PreCheckMaxBytes(10), nopPostFilter, 0}, - {10, PreCheckMaxBytes(22), nopPostFilter, 10}, - {10, nopPreFilter, PostCheckMaxGas(-1), 10}, - {10, nopPreFilter, PostCheckMaxGas(0), 0}, - {10, nopPreFilter, PostCheckMaxGas(1), 10}, - {10, nopPreFilter, PostCheckMaxGas(3000), 10}, - {10, PreCheckMaxBytes(10), PostCheckMaxGas(20), 0}, - {10, PreCheckMaxBytes(30), PostCheckMaxGas(20), 10}, - {10, PreCheckMaxBytes(22), PostCheckMaxGas(1), 10}, - {10, PreCheckMaxBytes(22), PostCheckMaxGas(0), 0}, + {10, nopPreFilter, 10}, + {10, PreCheckMaxBytes(10), 0}, + {10, PreCheckMaxBytes(20), 0}, + {10, PreCheckMaxBytes(22), 10}, + {10, PreCheckMaxBytes(30), 10}, } for tcIndex, tt := range tests { - err := mempool.Update(1, emptyTxArr, abciResponses(len(emptyTxArr), abci.CodeTypeOK), tt.preFilter, tt.postFilter) + err := mempool.Update(newTestBlock(1, emptyTxArr), + abciResponses(len(emptyTxArr), abci.CodeTypeOK), tt.preFilter) require.NoError(t, err) checkTxs(t, mempool, tt.numTxsToCreate, UnknownPeerID) require.Equal(t, tt.expectedNumTxs, mempool.Size(), "mempool had the incorrect size, on test case %d", tcIndex) @@ -186,9 +180,10 @@ func TestMempoolUpdate(t *testing.T) { // 1. Adds valid txs to the cache { - err := mempool.Update(1, []types.Tx{[]byte{0x01}}, abciResponses(1, abci.CodeTypeOK), nil, nil) + err := mempool.Update(newTestBlock(1, []types.Tx{[]byte{0x01}}), + abciResponses(1, abci.CodeTypeOK), nil) require.NoError(t, err) - err = mempool.CheckTx([]byte{0x01}, nil, TxInfo{}) + _, err = mempool.CheckTxSync([]byte{0x01}, TxInfo{}) if assert.Error(t, err) { assert.Equal(t, ErrTxInCache, err) } @@ -196,22 +191,22 @@ func TestMempoolUpdate(t *testing.T) { // 2. Removes valid txs from the mempool { - err := mempool.CheckTx([]byte{0x02}, nil, TxInfo{}) + _, err := mempool.CheckTxSync([]byte{0x02}, TxInfo{}) require.NoError(t, err) - err = mempool.Update(1, []types.Tx{[]byte{0x02}}, abciResponses(1, abci.CodeTypeOK), nil, nil) + err = mempool.Update(newTestBlock(1, []types.Tx{[]byte{0x02}}), abciResponses(1, abci.CodeTypeOK), nil) require.NoError(t, err) assert.Zero(t, mempool.Size()) } // 3. Removes invalid transactions from the cache and the mempool (if present) { - err := mempool.CheckTx([]byte{0x03}, nil, TxInfo{}) + _, err := mempool.CheckTxSync([]byte{0x03}, TxInfo{}) require.NoError(t, err) - err = mempool.Update(1, []types.Tx{[]byte{0x03}}, abciResponses(1, 1), nil, nil) + err = mempool.Update(newTestBlock(1, []types.Tx{[]byte{0x03}}), abciResponses(1, 1), nil) require.NoError(t, err) assert.Zero(t, mempool.Size()) - err = mempool.CheckTx([]byte{0x03}, nil, TxInfo{}) + _, err = mempool.CheckTxSync([]byte{0x03}, TxInfo{}) require.NoError(t, err) } } @@ -232,24 +227,24 @@ func TestMempool_KeepInvalidTxsInCache(t *testing.T) { b := make([]byte, 8) binary.BigEndian.PutUint64(b, 1) - err := mempool.CheckTx(b, nil, TxInfo{}) + _, err := mempool.CheckTxSync(b, TxInfo{}) require.NoError(t, err) // simulate new block _ = app.DeliverTx(abci.RequestDeliverTx{Tx: a}) _ = app.DeliverTx(abci.RequestDeliverTx{Tx: b}) - err = mempool.Update(1, []types.Tx{a, b}, - []*abci.ResponseDeliverTx{{Code: abci.CodeTypeOK}, {Code: 2}}, nil, nil) + err = mempool.Update(newTestBlock(1, []types.Tx{a, b}), + []*abci.ResponseDeliverTx{{Code: abci.CodeTypeOK}, {Code: 2}}, nil) require.NoError(t, err) // a must be added to the cache - err = mempool.CheckTx(a, nil, TxInfo{}) + _, err = mempool.CheckTxSync(a, TxInfo{}) if assert.Error(t, err) { assert.Equal(t, ErrTxInCache, err) } // b must remain in the cache - err = mempool.CheckTx(b, nil, TxInfo{}) + _, err = mempool.CheckTxSync(b, TxInfo{}) if assert.Error(t, err) { assert.Equal(t, ErrTxInCache, err) } @@ -263,10 +258,10 @@ func TestMempool_KeepInvalidTxsInCache(t *testing.T) { // remove a from the cache to test (2) mempool.cache.Remove(a) - err := mempool.CheckTx(a, nil, TxInfo{}) + _, err := mempool.CheckTxSync(a, TxInfo{}) require.NoError(t, err) - err = mempool.CheckTx(a, nil, TxInfo{}) + _, err = mempool.CheckTxSync(a, TxInfo{}) if assert.Error(t, err) { assert.Equal(t, ErrTxInCache, err) } @@ -294,7 +289,8 @@ func TestTxsAvailable(t *testing.T) { // it should fire once now for the new height // since there are still txs left committedTxs, txs := txs[:50], txs[50:] - if err := mempool.Update(1, committedTxs, abciResponses(len(committedTxs), abci.CodeTypeOK), nil, nil); err != nil { + if err := mempool.Update(newTestBlock(1, committedTxs), + abciResponses(len(committedTxs), abci.CodeTypeOK), nil); err != nil { t.Error(err) } ensureFire(t, mempool.TxsAvailable(), timeoutMS) @@ -305,8 +301,9 @@ func TestTxsAvailable(t *testing.T) { ensureNoFire(t, mempool.TxsAvailable(), timeoutMS) // now call update with all the txs. it should not fire as there are no txs left - committedTxs = append(txs, moreTxs...) //nolint: gocritic - if err := mempool.Update(2, committedTxs, abciResponses(len(committedTxs), abci.CodeTypeOK), nil, nil); err != nil { + committedTxs = append(txs, moreTxs...) // nolint: gocritic + if err := mempool.Update(newTestBlock(2, committedTxs), + abciResponses(len(committedTxs), abci.CodeTypeOK), nil); err != nil { t.Error(err) } ensureNoFire(t, mempool.TxsAvailable(), timeoutMS) @@ -338,7 +335,7 @@ func TestSerialReap(t *testing.T) { // This will succeed txBytes := make([]byte, 8) binary.BigEndian.PutUint64(txBytes, uint64(i)) - err := mempool.CheckTx(txBytes, nil, TxInfo{}) + _, err := mempool.CheckTxSync(txBytes, TxInfo{}) _, cached := cacheMap[string(txBytes)] if cached { require.NotNil(t, err, "expected error for cached tx") @@ -348,7 +345,7 @@ func TestSerialReap(t *testing.T) { cacheMap[string(txBytes)] = struct{}{} // Duplicates are cached and should return error - err = mempool.CheckTx(txBytes, nil, TxInfo{}) + _, err = mempool.CheckTxSync(txBytes, TxInfo{}) require.NotNil(t, err, "Expected error after CheckTx on duplicated tx") } } @@ -365,7 +362,8 @@ func TestSerialReap(t *testing.T) { binary.BigEndian.PutUint64(txBytes, uint64(i)) txs = append(txs, txBytes) } - if err := mempool.Update(0, txs, abciResponses(len(txs), abci.CodeTypeOK), nil, nil); err != nil { + if err := mempool.Update(newTestBlock(0, txs), + abciResponses(len(txs), abci.CodeTypeOK), nil); err != nil { t.Error(err) } } @@ -393,7 +391,7 @@ func TestSerialReap(t *testing.T) { } } - //---------------------------------------- + // ---------------------------------------- // Deliver some txs. deliverTxsRange(0, 100) @@ -455,7 +453,7 @@ func TestMempoolCloseWAL(t *testing.T) { require.Equal(t, 1, len(m2), "expecting the wal match in") // 5. Write some contents to the WAL - err = mempool.CheckTx(types.Tx([]byte("foo")), nil, TxInfo{}) + _, err = mempool.CheckTxSync(types.Tx([]byte("foo")), TxInfo{}) require.NoError(t, err) walFilepath := mempool.wal.Path sum1 := checksumFile(walFilepath, t) @@ -466,7 +464,7 @@ func TestMempoolCloseWAL(t *testing.T) { // 7. Invoke CloseWAL() and ensure it discards the // WAL thus any other write won't go through. mempool.CloseWAL() - err = mempool.CheckTx(types.Tx([]byte("bar")), nil, TxInfo{}) + _, err = mempool.CheckTxSync(types.Tx([]byte("bar")), TxInfo{}) require.NoError(t, err) sum2 := checksumFile(walFilepath, t) require.Equal(t, sum1, sum2, "expected no change to the WAL after invoking CloseWAL() since it was discarded") @@ -505,7 +503,7 @@ func TestMempool_CheckTxChecksTxSize(t *testing.T) { tx := tmrand.Bytes(testCase.len) - err := mempl.CheckTx(tx, nil, TxInfo{}) + _, err := mempl.CheckTxSync(tx, TxInfo{}) bv := gogotypes.BytesValue{Value: tx} bz, err2 := bv.Marshal() require.NoError(t, err2) @@ -531,17 +529,18 @@ func TestMempoolTxsBytes(t *testing.T) { assert.EqualValues(t, 0, mempool.TxsBytes()) // 2. len(tx) after CheckTx - err := mempool.CheckTx([]byte{0x01}, nil, TxInfo{}) + _, err := mempool.CheckTxSync([]byte{0x01}, TxInfo{}) require.NoError(t, err) assert.EqualValues(t, 1, mempool.TxsBytes()) // 3. zero again after tx is removed by Update - err = mempool.Update(1, []types.Tx{[]byte{0x01}}, abciResponses(1, abci.CodeTypeOK), nil, nil) + err = mempool.Update(newTestBlock(1, []types.Tx{[]byte{0x01}}), + abciResponses(1, abci.CodeTypeOK), nil) require.NoError(t, err) assert.EqualValues(t, 0, mempool.TxsBytes()) // 4. zero after Flush - err = mempool.CheckTx([]byte{0x02, 0x03}, nil, TxInfo{}) + _, err = mempool.CheckTxSync([]byte{0x02, 0x03}, TxInfo{}) require.NoError(t, err) assert.EqualValues(t, 2, mempool.TxsBytes()) @@ -549,9 +548,9 @@ func TestMempoolTxsBytes(t *testing.T) { assert.EqualValues(t, 0, mempool.TxsBytes()) // 5. ErrMempoolIsFull is returned when/if MaxTxsBytes limit is reached. - err = mempool.CheckTx([]byte{0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04}, nil, TxInfo{}) + _, err = mempool.CheckTxSync([]byte{0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04}, TxInfo{}) require.NoError(t, err) - err = mempool.CheckTx([]byte{0x05}, nil, TxInfo{}) + _, err = mempool.CheckTxSync([]byte{0x05}, TxInfo{}) if assert.Error(t, err) { assert.IsType(t, ErrMempoolIsFull{}, err) } @@ -565,7 +564,7 @@ func TestMempoolTxsBytes(t *testing.T) { txBytes := make([]byte, 8) binary.BigEndian.PutUint64(txBytes, uint64(0)) - err = mempool.CheckTx(txBytes, nil, TxInfo{}) + _, err = mempool.CheckTxSync(txBytes, TxInfo{}) require.NoError(t, err) assert.EqualValues(t, 8, mempool.TxsBytes()) @@ -586,12 +585,12 @@ func TestMempoolTxsBytes(t *testing.T) { require.NotEmpty(t, res2.Data) // Pretend like we committed nothing so txBytes gets rechecked and removed. - err = mempool.Update(1, []types.Tx{}, abciResponses(0, abci.CodeTypeOK), nil, nil) + err = mempool.Update(newTestBlock(1, []types.Tx{}), abciResponses(0, abci.CodeTypeOK), nil) require.NoError(t, err) assert.EqualValues(t, 0, mempool.TxsBytes()) // 7. Test RemoveTxByKey function - err = mempool.CheckTx([]byte{0x06}, nil, TxInfo{}) + _, err = mempool.CheckTxSync([]byte{0x06}, TxInfo{}) require.NoError(t, err) assert.EqualValues(t, 1, mempool.TxsBytes()) mempool.RemoveTxByKey(TxKey([]byte{0x07}), true) @@ -635,12 +634,23 @@ func TestMempoolRemoteAppConcurrency(t *testing.T) { tx := txs[txNum] // this will err with ErrTxInCache many times ... - mempool.CheckTx(tx, nil, TxInfo{SenderID: uint16(peerID)}) //nolint: errcheck // will error + mempool.CheckTxSync(tx, TxInfo{SenderID: uint16(peerID)}) // nolint: errcheck } err := mempool.FlushAppConn() require.NoError(t, err) } +func newTestBlock(height int64, txs types.Txs) *types.Block { + return &types.Block{ + Header: types.Header{ + Height: height, + }, + Data: types.Data{ + Txs: txs, + }, + } +} + // caller must close server func newRemoteApp( t *testing.T, @@ -660,9 +670,10 @@ func newRemoteApp( } return clientCreator, server } + func checksumIt(data []byte) string { h := sha256.New() - h.Write(data) //nolint: errcheck // ignore errcheck + h.Write(data) // nolint: errcheck // ignore errcheck return fmt.Sprintf("%x", h.Sum(nil)) } diff --git a/mempool/errors.go b/mempool/errors.go index e33e14ca3..00f288ac8 100644 --- a/mempool/errors.go +++ b/mempool/errors.go @@ -20,7 +20,7 @@ func (e ErrTxTooLarge) Error() string { return fmt.Sprintf("Tx too large. Max size is %d, but got %d", e.max, e.actual) } -// ErrMempoolIsFull means Tendermint & an application can't handle that much load +// ErrMempoolIsFull means Ostracon & an application can't handle that much load type ErrMempoolIsFull struct { numTxs int maxTxs int diff --git a/mempool/mempool.go b/mempool/mempool.go index cef9c64bf..882e6893d 100644 --- a/mempool/mempool.go +++ b/mempool/mempool.go @@ -15,7 +15,8 @@ import ( 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 + CheckTxSync(tx types.Tx, txInfo TxInfo) (*abci.Response, error) + CheckTxAsync(tx types.Tx, txInfo TxInfo, prepareCb func(error), checkTxCb func(*abci.Response)) // ReapMaxBytesMaxGas reaps transactions from the mempool up to maxBytes // bytes total with the condition that the total gasWanted must be less than @@ -39,11 +40,9 @@ type Mempool interface { // NOTE: this should be called *after* block is committed by consensus. // NOTE: Lock/Unlock must be managed by caller Update( - blockHeight int64, - blockTxs types.Txs, + block *types.Block, deliverTxResponses []*abci.ResponseDeliverTx, newPreFn PreCheckFunc, - newPostFn PostCheckFunc, ) error // FlushAppConn flushes the mempool connection to ensure async reqResCb calls are @@ -85,11 +84,6 @@ type Mempool interface { // transaction doesn't exceeded the block size. type PreCheckFunc func(types.Tx) error -// PostCheckFunc is an optional filter executed after CheckTx and rejects -// transaction if false is returned. An example would be to ensure a -// transaction doesn't require more gas than available for the block. -type PostCheckFunc func(types.Tx, *abci.ResponseCheckTx) error - // TxInfo are parameters that get passed when attempting to add a tx to the // mempool. type TxInfo struct { @@ -114,22 +108,3 @@ func PreCheckMaxBytes(maxBytes int64) PreCheckFunc { return nil } } - -// PostCheckMaxGas checks that the wanted gas is smaller or equal to the passed -// maxGas. Returns nil if maxGas is -1. -func PostCheckMaxGas(maxGas int64) PostCheckFunc { - return func(tx types.Tx, res *abci.ResponseCheckTx) error { - if maxGas == -1 { - return nil - } - if res.GasWanted < 0 { - return fmt.Errorf("gas wanted %d is negative", - res.GasWanted) - } - if res.GasWanted > maxGas { - return fmt.Errorf("gas wanted %d is greater than max gas %d", - res.GasWanted, maxGas) - } - return nil - } -} diff --git a/mempool/metrics.go b/mempool/metrics.go index 5e4eaf5ed..39459de69 100644 --- a/mempool/metrics.go +++ b/mempool/metrics.go @@ -23,7 +23,9 @@ type Metrics struct { // Number of failed transactions. FailedTxs metrics.Counter // Number of times transactions are rechecked in the mempool. - RecheckTimes metrics.Counter + RecheckCount metrics.Counter + // Time of recheck transactions in the mempool. + RecheckTime metrics.Gauge } // PrometheusMetrics returns Metrics build using Prometheus client library. @@ -54,12 +56,18 @@ func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics { Name: "failed_txs", Help: "Number of failed transactions.", }, labels).With(labelsAndValues...), - RecheckTimes: prometheus.NewCounterFrom(stdprometheus.CounterOpts{ + RecheckCount: prometheus.NewCounterFrom(stdprometheus.CounterOpts{ Namespace: namespace, Subsystem: MetricsSubsystem, - Name: "recheck_times", + Name: "recheck_count", Help: "Number of times transactions are rechecked in the mempool.", }, labels).With(labelsAndValues...), + RecheckTime: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: MetricsSubsystem, + Name: "recheck_time", + Help: "Time of recheck transactions in the mempool in ms.", + }, labels).With(labelsAndValues...), } } @@ -69,6 +77,7 @@ func NopMetrics() *Metrics { Size: discard.NewGauge(), TxSizeBytes: discard.NewHistogram(), FailedTxs: discard.NewCounter(), - RecheckTimes: discard.NewCounter(), + RecheckCount: discard.NewCounter(), + RecheckTime: discard.NewGauge(), } } diff --git a/mempool/mock/mempool.go b/mempool/mock/mempool.go index c8b328194..b0a69f85c 100644 --- a/mempool/mock/mempool.go +++ b/mempool/mock/mempool.go @@ -15,17 +15,17 @@ var _ mempl.Mempool = Mempool{} func (Mempool) Lock() {} func (Mempool) Unlock() {} func (Mempool) Size() int { return 0 } -func (Mempool) CheckTx(_ types.Tx, _ func(*abci.Response), _ mempl.TxInfo) error { - return nil +func (Mempool) CheckTxSync(_ types.Tx, _ mempl.TxInfo) (*abci.Response, error) { + return nil, nil +} +func (Mempool) CheckTxAsync(_ types.Tx, _ mempl.TxInfo, _ func(error), _ func(*abci.Response)) { } func (Mempool) ReapMaxBytesMaxGas(_, _ int64) types.Txs { return types.Txs{} } func (Mempool) ReapMaxTxs(n int) types.Txs { return types.Txs{} } func (Mempool) Update( - _ int64, - _ types.Txs, + _ *types.Block, _ []*abci.ResponseDeliverTx, _ mempl.PreCheckFunc, - _ mempl.PostCheckFunc, ) error { return nil } diff --git a/mempool/reactor.go b/mempool/reactor.go index 57f482cd2..8a255eb95 100644 --- a/mempool/reactor.go +++ b/mempool/reactor.go @@ -186,10 +186,12 @@ func (memR *Reactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) { txInfo.SenderP2PID = src.ID() } for _, tx := range msg.Txs { - err = memR.mempool.CheckTx(tx, nil, txInfo) - if err != nil { - memR.Logger.Info("Could not check tx", "tx", txID(tx), "err", err) - } + tx := tx // pin! workaround for `scopelint` error + memR.mempool.CheckTxAsync(tx, txInfo, func(err error) { + if err != nil { + memR.Logger.Info("Could not check tx", "tx", txID(tx), "err", err) + } + }, nil) } // broadcasting happens from go routines per peer } diff --git a/mempool/reactor_test.go b/mempool/reactor_test.go index 03a7801c6..866a17114 100644 --- a/mempool/reactor_test.go +++ b/mempool/reactor_test.go @@ -107,7 +107,7 @@ func TestReactorConcurrency(t *testing.T) { for i := range txs { deliverTxResponses[i] = &abci.ResponseDeliverTx{Code: 0} } - err := reactors[0].mempool.Update(1, txs, deliverTxResponses, nil, nil) + err := reactors[0].mempool.Update(newTestBlock(1, txs), deliverTxResponses, nil) assert.NoError(t, err) }() @@ -119,7 +119,8 @@ func TestReactorConcurrency(t *testing.T) { reactors[1].mempool.Lock() defer reactors[1].mempool.Unlock() - err := reactors[1].mempool.Update(1, []types.Tx{}, make([]*abci.ResponseDeliverTx, 0), nil, nil) + err := reactors[1].mempool.Update(newTestBlock(1, []types.Tx{}), + make([]*abci.ResponseDeliverTx, 0), nil) assert.NoError(t, err) }() @@ -175,7 +176,7 @@ func TestReactor_MaxTxBytes(t *testing.T) { // Broadcast a tx, which has the max size // => ensure it's received by the second reactor. tx1 := tmrand.Bytes(config.Mempool.MaxTxBytes) - err := reactors[0].mempool.CheckTx(tx1, nil, TxInfo{SenderID: UnknownPeerID}) + _, err := reactors[0].mempool.CheckTxSync(tx1, TxInfo{SenderID: UnknownPeerID}) require.NoError(t, err) waitForTxsOnReactors(t, []types.Tx{tx1}, reactors) @@ -185,7 +186,7 @@ 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, TxInfo{SenderID: UnknownPeerID}) + _, err = reactors[0].mempool.CheckTxSync(tx2, TxInfo{SenderID: UnknownPeerID}) require.Error(t, err) } diff --git a/networks/local/localnode/wrapper.sh b/networks/local/localnode/wrapper.sh index f6d56e126..010170760 100755 --- a/networks/local/localnode/wrapper.sh +++ b/networks/local/localnode/wrapper.sh @@ -26,10 +26,10 @@ fi ## ## Run binary with all parameters ## -export TMHOME="/ostracon/node${ID}" +export OCHOME="/ostracon/node${ID}" -if [ -d "`dirname ${TMHOME}/${LOG}`" ]; then - "$BINARY" "$@" | tee "${TMHOME}/${LOG}" +if [ -d "`dirname ${OCHOME}/${LOG}`" ]; then + "$BINARY" "$@" | tee "${OCHOME}/${LOG}" else "$BINARY" "$@" fi diff --git a/node/node.go b/node/node.go index fef21b9fa..d1dd3bfdd 100644 --- a/node/node.go +++ b/node/node.go @@ -11,11 +11,12 @@ import ( "strings" "time" + "github.com/line/tm-db/v2/metadb" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/rs/cors" - dbm "github.com/tendermint/tm-db" + dbm "github.com/line/tm-db/v2" abci "github.com/line/ostracon/abci/types" bcv0 "github.com/line/ostracon/blockchain/v0" @@ -63,8 +64,8 @@ type DBProvider func(*DBContext) (dbm.DB, error) // DefaultDBProvider returns a database using the DBBackend and DBDir // specified in the ctx.Config. func DefaultDBProvider(ctx *DBContext) (dbm.DB, error) { - dbType := dbm.BackendType(ctx.Config.DBBackend) - return dbm.NewDB(ctx.ID, dbType, ctx.Config.DBDir()) + dbType := metadb.BackendType(ctx.Config.DBBackend) + return metadb.NewDB(ctx.ID, dbType, ctx.Config.DBDir()) } // GenesisDocProvider returns a GenesisDoc. @@ -83,7 +84,7 @@ func DefaultGenesisDocProviderFunc(config *cfg.Config) GenesisDocProvider { // Provider takes a config and a logger and returns a ready to go Node. type Provider func(*cfg.Config, log.Logger) (*Node, error) -// DefaultNewNode returns a Tendermint node with default settings for the +// DefaultNewNode returns an Ostracon node with default settings for the // PrivValidator, ClientCreator, GenesisDoc, and DBProvider. // It implements NodeProvider. func DefaultNewNode(config *cfg.Config, logger log.Logger) (*Node, error) { @@ -173,7 +174,7 @@ func StateProvider(stateProvider statesync.StateProvider) Option { //------------------------------------------------------------------------------ -// Node is the highest level interface to a full Tendermint node. +// Node is the highest level interface to a full Ostracon node. // It includes all configuration information and running services. type Node struct { service.BaseService @@ -291,7 +292,7 @@ func doHandshake( func logNodeStartupInfo(state sm.State, pubKey crypto.PubKey, logger, consensusLogger log.Logger) { // Log the version info. logger.Info("Version info", - "software", version.TMCoreSemVer, + "software", version.OCCoreSemVer, "block", version.BlockProtocol, "p2p", version.P2PProtocol, ) @@ -330,7 +331,6 @@ func createMempoolAndMempoolReactor(config *cfg.Config, proxyApp proxy.AppConns, state.LastBlockHeight, mempl.WithMetrics(memplMetrics), mempl.WithPreCheck(sm.TxPreCheck(state)), - mempl.WithPostCheck(sm.TxPostCheck(state)), ) mempoolLogger := logger.With("module", "mempool") mempoolReactor := mempl.NewReactor(config.Mempool, config.P2P.RecvAsync, config.P2P.MempoolRecvBufSize, mempool) @@ -632,7 +632,7 @@ func startStateSync(ssR *statesync.Reactor, bcR fastSyncReactor, conR *cs.Reacto return nil } -// NewNode returns a new, ready to go, Tendermint Node. +// NewNode returns a new, ready to go, Ostracon Node. func NewNode(config *cfg.Config, privValidator types.PrivValidator, nodeKey *p2p.NodeKey, @@ -1031,6 +1031,9 @@ func (n *Node) startRPC() ([]net.Listener, error) { config.MaxBodyBytes = n.config.RPC.MaxBodyBytes config.MaxHeaderBytes = n.config.RPC.MaxHeaderBytes config.MaxOpenConnections = n.config.RPC.MaxOpenConnections + config.ReadTimeout = n.config.RPC.ReadTimeout + config.WriteTimeout = n.config.RPC.WriteTimeout + config.IdleTimeout = n.config.RPC.IdleTimeout // If necessary adjust global WriteTimeout to ensure it's greater than // TimeoutBroadcastTxCommit. // See https://github.com/tendermint/tendermint/issues/3435 @@ -1269,7 +1272,7 @@ func makeNodeInfo( ), DefaultNodeID: nodeKey.ID(), Network: genDoc.ChainID, - Version: version.TMCoreSemVer, + Version: version.OCCoreSemVer, Channels: []byte{ bcChannel, cs.StateChannel, cs.DataChannel, cs.VoteChannel, cs.VoteSetBitsChannel, diff --git a/node/node_test.go b/node/node_test.go index 24a8f1ed5..2e6967adc 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -9,10 +9,11 @@ import ( "testing" "time" + "github.com/line/tm-db/v2/memdb" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - dbm "github.com/tendermint/tm-db" + dbm "github.com/line/tm-db/v2" "github.com/line/ostracon/abci/example/kvstore" cfg "github.com/line/ostracon/config" @@ -248,13 +249,12 @@ func TestCreateProposalBlock(t *testing.T) { state.LastBlockHeight, mempl.WithMetrics(memplMetrics), mempl.WithPreCheck(sm.TxPreCheck(state)), - mempl.WithPostCheck(sm.TxPostCheck(state)), ) mempool.SetLogger(logger) // Make EvidencePool - evidenceDB := dbm.NewMemDB() - blockStore := store.NewBlockStore(dbm.NewMemDB()) + evidenceDB := memdb.NewDB() + blockStore := store.NewBlockStore(memdb.NewDB()) evidencePool, err := evidence.NewPool(evidenceDB, stateStore, blockStore) require.NoError(t, err) evidencePool.SetLogger(logger) @@ -278,7 +278,7 @@ func TestCreateProposalBlock(t *testing.T) { txLength := 100 for i := 0; i <= maxBytes/txLength; i++ { tx := tmrand.Bytes(txLength) - err := mempool.CheckTx(tx, nil, mempl.TxInfo{}) + _, err := mempool.CheckTxSync(tx, mempl.TxInfo{}) assert.NoError(t, err) } @@ -344,14 +344,13 @@ func TestMaxProposalBlockSize(t *testing.T) { state.LastBlockHeight, mempl.WithMetrics(memplMetrics), mempl.WithPreCheck(sm.TxPreCheck(state)), - mempl.WithPostCheck(sm.TxPostCheck(state)), ) mempool.SetLogger(logger) // fill the mempool with one txs just below the maximum size txLength := int(types.MaxDataBytesNoEvidence(maxBytes, 1)) tx := tmrand.Bytes(txLength - 4) // to account for the varint - err = mempool.CheckTx(tx, nil, mempl.TxInfo{}) + _, err = mempool.CheckTxSync(tx, mempl.TxInfo{}) assert.NoError(t, err) blockExec := sm.NewBlockExecutor( @@ -439,7 +438,7 @@ func state(nVals int, height int64) (sm.State, dbm.DB, []types.PrivValidator) { }) // save validators to db for 2 heights - stateDB := dbm.NewMemDB() + stateDB := memdb.NewDB() stateStore := sm.NewStore(stateDB) if err := stateStore.Save(s); err != nil { panic(err) diff --git a/p2p/netaddress.go b/p2p/netaddress.go index 2261a7012..cbb67eb9d 100644 --- a/p2p/netaddress.go +++ b/p2p/netaddress.go @@ -1,4 +1,4 @@ -// Modified for Tendermint +// Modified for Tendermint, Ostracon // Originally Copyright (c) 2013-2014 Conformal Systems LLC. // https://github.com/conformal/btcd/blob/master/LICENSE diff --git a/p2p/node_info.go b/p2p/node_info.go index d356784ca..3ea41fcaf 100644 --- a/p2p/node_info.go +++ b/p2p/node_info.go @@ -74,7 +74,7 @@ func NewProtocolVersion(p2p, block, app uint64) ProtocolVersion { var _ NodeInfo = DefaultNodeInfo{} // DefaultNodeInfo is the basic node information exchanged -// between two peers during the Tendermint P2P handshake. +// between two peers during the Ostracon P2P handshake. type DefaultNodeInfo struct { ProtocolVersion ProtocolVersion `json:"protocol_version"` diff --git a/p2p/trust/store.go b/p2p/trust/store.go index e5ca49d94..779b49a30 100644 --- a/p2p/trust/store.go +++ b/p2p/trust/store.go @@ -8,7 +8,7 @@ import ( "fmt" "time" - dbm "github.com/tendermint/tm-db" + dbm "github.com/line/tm-db/v2" "github.com/line/ostracon/libs/service" tmsync "github.com/line/ostracon/libs/sync" diff --git a/p2p/trust/store_test.go b/p2p/trust/store_test.go index cf655b882..ea07f6a36 100644 --- a/p2p/trust/store_test.go +++ b/p2p/trust/store_test.go @@ -9,11 +9,10 @@ import ( "os" "testing" + "github.com/line/ostracon/libs/log" + "github.com/line/tm-db/v2/metadb" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - dbm "github.com/tendermint/tm-db" - - "github.com/line/ostracon/libs/log" ) func TestTrustMetricStoreSaveLoad(t *testing.T) { @@ -21,7 +20,7 @@ func TestTrustMetricStoreSaveLoad(t *testing.T) { require.NoError(t, err) defer os.Remove(dir) - historyDB, err := dbm.NewDB("trusthistory", "goleveldb", dir) + historyDB, err := metadb.NewDB("trusthistory", "goleveldb", dir) require.NoError(t, err) // 0 peers saved @@ -84,7 +83,7 @@ func TestTrustMetricStoreSaveLoad(t *testing.T) { } func TestTrustMetricStoreConfig(t *testing.T) { - historyDB, err := dbm.NewDB("", "memdb", "") + historyDB, err := metadb.NewDB("", "memdb", "") require.NoError(t, err) config := MetricConfig{ @@ -109,7 +108,7 @@ func TestTrustMetricStoreConfig(t *testing.T) { } func TestTrustMetricStoreLookup(t *testing.T) { - historyDB, err := dbm.NewDB("", "memdb", "") + historyDB, err := metadb.NewDB("", "memdb", "") require.NoError(t, err) store := NewTrustMetricStore(historyDB, DefaultConfig()) @@ -132,7 +131,7 @@ func TestTrustMetricStoreLookup(t *testing.T) { } func TestTrustMetricStorePeerScore(t *testing.T) { - historyDB, err := dbm.NewDB("", "memdb", "") + historyDB, err := metadb.NewDB("", "memdb", "") require.NoError(t, err) store := NewTrustMetricStore(historyDB, DefaultConfig()) diff --git a/p2p/upnp/probe.go b/p2p/upnp/probe.go index f1448972c..78fbb09f7 100644 --- a/p2p/upnp/probe.go +++ b/p2p/upnp/probe.go @@ -26,7 +26,7 @@ func makeUPNPListener(intPort int, extPort int, logger log.Logger) (NAT, net.Lis } logger.Info(fmt.Sprintf("External address: %v", ext)) - port, err := nat.AddPortMapping("tcp", extPort, intPort, "Tendermint UPnP Probe", 0) + port, err := nat.AddPortMapping("tcp", extPort, intPort, "Ostracon UPnP Probe", 0) if err != nil { return nat, nil, ext, fmt.Errorf("port mapping error: %v", err) } diff --git a/privval/file_test.go b/privval/file_test.go index a2d8d332d..f7d39edfa 100644 --- a/privval/file_test.go +++ b/privval/file_test.go @@ -162,11 +162,11 @@ func TestUnmarshalValidatorKey(t *testing.T) { serialized := fmt.Sprintf(`{ "address": "%s", "pub_key": { - "type": "tendermint/PubKeyEd25519", + "type": "ostracon/PubKeyEd25519", "value": "%s" }, "priv_key": { - "type": "tendermint/PrivKeyEd25519", + "type": "ostracon/PrivKeyEd25519", "value": "%s" } }`, addr, pubB64, privB64) diff --git a/proto/ostracon/abci/types.proto b/proto/ostracon/abci/types.proto index cedff0a9c..1f6ed0a41 100644 --- a/proto/ostracon/abci/types.proto +++ b/proto/ostracon/abci/types.proto @@ -36,6 +36,8 @@ message Request { RequestOfferSnapshot offer_snapshot = 13; RequestLoadSnapshotChunk load_snapshot_chunk = 14; RequestApplySnapshotChunk apply_snapshot_chunk = 15; + RequestBeginRecheckTx begin_recheck_tx = 1000; // 16~99 are reserved for merging original tendermint + RequestEndRecheckTx end_recheck_tx = 1001; } } @@ -125,6 +127,14 @@ message RequestApplySnapshotChunk { string sender = 3; } +message RequestBeginRecheckTx { + ostracon.types.Header header = 1 [(gogoproto.nullable) = false]; +} + +message RequestEndRecheckTx { + int64 height = 1; +} + //---------------------------------------- // Response types @@ -146,6 +156,8 @@ message Response { ResponseOfferSnapshot offer_snapshot = 14; ResponseLoadSnapshotChunk load_snapshot_chunk = 15; ResponseApplySnapshotChunk apply_snapshot_chunk = 16; + ResponseBeginRecheckTx begin_recheck_tx = 1000; // 17~99 are reserved for merging original tendermint + ResponseEndRecheckTx end_recheck_tx = 1001; } } @@ -276,6 +288,14 @@ message ResponseApplySnapshotChunk { } } +message ResponseBeginRecheckTx { + uint32 code = 1; +} + +message ResponseEndRecheckTx { + uint32 code = 1; +} + //---------------------------------------- // Misc. @@ -407,4 +427,6 @@ service ABCIApplication { rpc OfferSnapshot(RequestOfferSnapshot) returns (ResponseOfferSnapshot); rpc LoadSnapshotChunk(RequestLoadSnapshotChunk) returns (ResponseLoadSnapshotChunk); rpc ApplySnapshotChunk(RequestApplySnapshotChunk) returns (ResponseApplySnapshotChunk); + rpc BeginRecheckTx(RequestBeginRecheckTx) returns (ResponseBeginRecheckTx); + rpc EndRecheckTx(RequestEndRecheckTx) returns (ResponseEndRecheckTx); } diff --git a/proto/ostracon/crypto/keys.pb.go b/proto/ostracon/crypto/keys.pb.go index 2ebc0b007..3d42cc643 100644 --- a/proto/ostracon/crypto/keys.pb.go +++ b/proto/ostracon/crypto/keys.pb.go @@ -77,7 +77,7 @@ func (m *CompositePublicKey) GetVrfKey() *PublicKey { return nil } -// PublicKey defines the keys available for use with Tendermint Validators +// PublicKey defines the keys available for use with Ostracon Validators type PublicKey struct { // Types that are valid to be assigned to Sum: // *PublicKey_Ed25519 diff --git a/proto/ostracon/crypto/keys.proto b/proto/ostracon/crypto/keys.proto index eabeb0679..c32cfcbec 100644 --- a/proto/ostracon/crypto/keys.proto +++ b/proto/ostracon/crypto/keys.proto @@ -14,7 +14,7 @@ message CompositePublicKey { PublicKey vrf_key = 2; } -// PublicKey defines the keys available for use with Tendermint Validators +// PublicKey defines the keys available for use with Ostracon Validators message PublicKey { option (gogoproto.compare) = true; option (gogoproto.equal) = true; diff --git a/proto/ostracon/types/types.pb.go b/proto/ostracon/types/types.pb.go index e35b7e29f..5cd235025 100644 --- a/proto/ostracon/types/types.pb.go +++ b/proto/ostracon/types/types.pb.go @@ -261,7 +261,7 @@ func (m *BlockID) GetPartSetHeader() PartSetHeader { return PartSetHeader{} } -// Header defines the structure of a Tendermint block header. +// Header defines the structure of an Ostracon block header. type Header struct { // basic block info Version version.Consensus `protobuf:"bytes,1,opt,name=version,proto3" json:"version"` diff --git a/proto/ostracon/types/types.proto b/proto/ostracon/types/types.proto index dd4cffb89..9aedd448a 100644 --- a/proto/ostracon/types/types.proto +++ b/proto/ostracon/types/types.proto @@ -55,7 +55,7 @@ message BlockID { // -------------------------------- -// Header defines the structure of a Tendermint block header. +// Header defines the structure of an Ostracon block header. message Header { // basic block info ostracon.version.Consensus version = 1 [(gogoproto.nullable) = false]; diff --git a/proxy/app_conn.go b/proxy/app_conn.go index 931662433..9be854cf3 100644 --- a/proxy/app_conn.go +++ b/proxy/app_conn.go @@ -5,32 +5,36 @@ import ( "github.com/line/ostracon/abci/types" ) -//go:generate mockery --case underscore --name AppConnConsensus|AppConnMempool|AppConnQuery|AppConnSnapshot +//nolint +//go:generate mockery --case underscore --name AppConnConsensus|AppConnMempool|AppConnQuery|AppConnSnapshot|ClientCreator //---------------------------------------------------------------------------------------- // Enforce which abci msgs can be sent on a connection at the type level type AppConnConsensus interface { - SetResponseCallback(abcicli.Callback) + SetGlobalCallback(abcicli.GlobalCallback) Error() error InitChainSync(types.RequestInitChain) (*types.ResponseInitChain, error) BeginBlockSync(types.RequestBeginBlock) (*types.ResponseBeginBlock, error) - DeliverTxAsync(types.RequestDeliverTx) *abcicli.ReqRes + DeliverTxAsync(types.RequestDeliverTx, abcicli.ResponseCallback) *abcicli.ReqRes EndBlockSync(types.RequestEndBlock) (*types.ResponseEndBlock, error) CommitSync() (*types.ResponseCommit, error) } type AppConnMempool interface { - SetResponseCallback(abcicli.Callback) + SetGlobalCallback(abcicli.GlobalCallback) Error() error - CheckTxAsync(types.RequestCheckTx) *abcicli.ReqRes + CheckTxAsync(types.RequestCheckTx, abcicli.ResponseCallback) *abcicli.ReqRes CheckTxSync(types.RequestCheckTx) (*types.ResponseCheckTx, error) - FlushAsync() *abcicli.ReqRes - FlushSync() error + BeginRecheckTxSync(types.RequestBeginRecheckTx) (*types.ResponseBeginRecheckTx, error) + EndRecheckTxSync(types.RequestEndRecheckTx) (*types.ResponseEndRecheckTx, error) + + FlushAsync(abcicli.ResponseCallback) *abcicli.ReqRes + FlushSync() (*types.ResponseFlush, error) } type AppConnQuery interface { @@ -65,8 +69,8 @@ func NewAppConnConsensus(appConn abcicli.Client) AppConnConsensus { } } -func (app *appConnConsensus) SetResponseCallback(cb abcicli.Callback) { - app.appConn.SetResponseCallback(cb) +func (app *appConnConsensus) SetGlobalCallback(globalCb abcicli.GlobalCallback) { + app.appConn.SetGlobalCallback(globalCb) } func (app *appConnConsensus) Error() error { @@ -81,8 +85,8 @@ func (app *appConnConsensus) BeginBlockSync(req types.RequestBeginBlock) (*types return app.appConn.BeginBlockSync(req) } -func (app *appConnConsensus) DeliverTxAsync(req types.RequestDeliverTx) *abcicli.ReqRes { - return app.appConn.DeliverTxAsync(req) +func (app *appConnConsensus) DeliverTxAsync(req types.RequestDeliverTx, cb abcicli.ResponseCallback) *abcicli.ReqRes { + return app.appConn.DeliverTxAsync(req, cb) } func (app *appConnConsensus) EndBlockSync(req types.RequestEndBlock) (*types.ResponseEndBlock, error) { @@ -106,30 +110,38 @@ func NewAppConnMempool(appConn abcicli.Client) AppConnMempool { } } -func (app *appConnMempool) SetResponseCallback(cb abcicli.Callback) { - app.appConn.SetResponseCallback(cb) +func (app *appConnMempool) SetGlobalCallback(globalCb abcicli.GlobalCallback) { + app.appConn.SetGlobalCallback(globalCb) } func (app *appConnMempool) Error() error { return app.appConn.Error() } -func (app *appConnMempool) FlushAsync() *abcicli.ReqRes { - return app.appConn.FlushAsync() +func (app *appConnMempool) FlushAsync(cb abcicli.ResponseCallback) *abcicli.ReqRes { + return app.appConn.FlushAsync(cb) } -func (app *appConnMempool) FlushSync() error { +func (app *appConnMempool) FlushSync() (*types.ResponseFlush, error) { return app.appConn.FlushSync() } -func (app *appConnMempool) CheckTxAsync(req types.RequestCheckTx) *abcicli.ReqRes { - return app.appConn.CheckTxAsync(req) +func (app *appConnMempool) CheckTxAsync(req types.RequestCheckTx, cb abcicli.ResponseCallback) *abcicli.ReqRes { + return app.appConn.CheckTxAsync(req, cb) } func (app *appConnMempool) CheckTxSync(req types.RequestCheckTx) (*types.ResponseCheckTx, error) { return app.appConn.CheckTxSync(req) } +func (app *appConnMempool) BeginRecheckTxSync(req types.RequestBeginRecheckTx) (*types.ResponseBeginRecheckTx, error) { + return app.appConn.BeginRecheckTxSync(req) +} + +func (app *appConnMempool) EndRecheckTxSync(req types.RequestEndRecheckTx) (*types.ResponseEndRecheckTx, error) { + return app.appConn.EndRecheckTxSync(req) +} + //------------------------------------------------ // Implements AppConnQuery (subset of abcicli.Client) diff --git a/proxy/app_conn_test.go b/proxy/app_conn_test.go index a9d69f635..f802567e1 100644 --- a/proxy/app_conn_test.go +++ b/proxy/app_conn_test.go @@ -16,8 +16,8 @@ import ( //---------------------------------------- type AppConnTest interface { - EchoAsync(string) *abcicli.ReqRes - FlushSync() error + FlushSync() (*types.ResponseFlush, error) + EchoAsync(string, abcicli.ResponseCallback) *abcicli.ReqRes InfoSync(types.RequestInfo) (*types.ResponseInfo, error) } @@ -29,11 +29,11 @@ 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) EchoAsync(msg string, cb abcicli.ResponseCallback) *abcicli.ReqRes { + return app.appConn.EchoAsync(msg, cb) } -func (app *appConnTest) FlushSync() error { +func (app *appConnTest) FlushSync() (*types.ResponseFlush, error) { return app.appConn.FlushSync() } @@ -75,10 +75,11 @@ func TestEcho(t *testing.T) { t.Log("Connected") for i := 0; i < 1000; i++ { - proxy.EchoAsync(fmt.Sprintf("echo-%v", i)) + proxy.EchoAsync(fmt.Sprintf("echo-%v", i), nil) } - if err := proxy.FlushSync(); err != nil { - t.Error(err) + _, err2 := proxy.FlushSync() + if err2 != nil { + t.Error(err2) } } @@ -115,10 +116,11 @@ func BenchmarkEcho(b *testing.B) { b.StartTimer() // Start benchmarking tests for i := 0; i < b.N; i++ { - proxy.EchoAsync(echoString) + proxy.EchoAsync(echoString, nil) } - if err := proxy.FlushSync(); err != nil { - b.Error(err) + _, err2 := proxy.FlushSync() + if err2 != nil { + b.Error(err2) } b.StopTimer() diff --git a/proxy/mocks/app_conn_consensus.go b/proxy/mocks/app_conn_consensus.go index 601e71ec9..a21beed72 100644 --- a/proxy/mocks/app_conn_consensus.go +++ b/proxy/mocks/app_conn_consensus.go @@ -1,10 +1,10 @@ -// Code generated by mockery 2.9.0. DO NOT EDIT. +// Code generated by mockery 2.7.4. DO NOT EDIT. package mocks import ( - mock "github.com/stretchr/testify/mock" abcicli "github.com/line/ostracon/abci/client" + mock "github.com/stretchr/testify/mock" types "github.com/line/ostracon/abci/types" ) @@ -60,13 +60,13 @@ func (_m *AppConnConsensus) CommitSync() (*types.ResponseCommit, error) { return r0, r1 } -// DeliverTxAsync provides a mock function with given fields: _a0 -func (_m *AppConnConsensus) DeliverTxAsync(_a0 types.RequestDeliverTx) *abcicli.ReqRes { - ret := _m.Called(_a0) +// DeliverTxAsync provides a mock function with given fields: _a0, _a1 +func (_m *AppConnConsensus) DeliverTxAsync(_a0 types.RequestDeliverTx, _a1 abcicli.ResponseCallback) *abcicli.ReqRes { + ret := _m.Called(_a0, _a1) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestDeliverTx) *abcicli.ReqRes); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(types.RequestDeliverTx, abcicli.ResponseCallback) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) @@ -136,7 +136,7 @@ func (_m *AppConnConsensus) InitChainSync(_a0 types.RequestInitChain) (*types.Re return r0, r1 } -// SetResponseCallback provides a mock function with given fields: _a0 -func (_m *AppConnConsensus) SetResponseCallback(_a0 abcicli.Callback) { +// SetGlobalCallback provides a mock function with given fields: _a0 +func (_m *AppConnConsensus) SetGlobalCallback(_a0 abcicli.GlobalCallback) { _m.Called(_a0) } diff --git a/proxy/mocks/app_conn_mempool.go b/proxy/mocks/app_conn_mempool.go index 38a87cf79..24f19bcef 100644 --- a/proxy/mocks/app_conn_mempool.go +++ b/proxy/mocks/app_conn_mempool.go @@ -1,10 +1,10 @@ -// Code generated by mockery 2.9.0. DO NOT EDIT. +// Code generated by mockery 2.7.4. DO NOT EDIT. package mocks import ( - mock "github.com/stretchr/testify/mock" abcicli "github.com/line/ostracon/abci/client" + mock "github.com/stretchr/testify/mock" types "github.com/line/ostracon/abci/types" ) @@ -14,13 +14,36 @@ type AppConnMempool struct { mock.Mock } -// CheckTxAsync provides a mock function with given fields: _a0 -func (_m *AppConnMempool) CheckTxAsync(_a0 types.RequestCheckTx) *abcicli.ReqRes { +// BeginRecheckTxSync provides a mock function with given fields: _a0 +func (_m *AppConnMempool) BeginRecheckTxSync(_a0 types.RequestBeginRecheckTx) (*types.ResponseBeginRecheckTx, error) { ret := _m.Called(_a0) - var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func(types.RequestCheckTx) *abcicli.ReqRes); ok { + var r0 *types.ResponseBeginRecheckTx + if rf, ok := ret.Get(0).(func(types.RequestBeginRecheckTx) *types.ResponseBeginRecheckTx); ok { r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseBeginRecheckTx) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(types.RequestBeginRecheckTx) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CheckTxAsync provides a mock function with given fields: _a0, _a1 +func (_m *AppConnMempool) CheckTxAsync(_a0 types.RequestCheckTx, _a1 abcicli.ResponseCallback) *abcicli.ReqRes { + ret := _m.Called(_a0, _a1) + + var r0 *abcicli.ReqRes + if rf, ok := ret.Get(0).(func(types.RequestCheckTx, abcicli.ResponseCallback) *abcicli.ReqRes); ok { + r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) @@ -53,6 +76,29 @@ func (_m *AppConnMempool) CheckTxSync(_a0 types.RequestCheckTx) (*types.Response return r0, r1 } +// EndRecheckTxSync provides a mock function with given fields: _a0 +func (_m *AppConnMempool) EndRecheckTxSync(_a0 types.RequestEndRecheckTx) (*types.ResponseEndRecheckTx, error) { + ret := _m.Called(_a0) + + var r0 *types.ResponseEndRecheckTx + if rf, ok := ret.Get(0).(func(types.RequestEndRecheckTx) *types.ResponseEndRecheckTx); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseEndRecheckTx) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(types.RequestEndRecheckTx) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // Error provides a mock function with given fields: func (_m *AppConnMempool) Error() error { ret := _m.Called() @@ -67,13 +113,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() +// FlushAsync provides a mock function with given fields: _a0 +func (_m *AppConnMempool) FlushAsync(_a0 abcicli.ResponseCallback) *abcicli.ReqRes { + ret := _m.Called(_a0) var r0 *abcicli.ReqRes - if rf, ok := ret.Get(0).(func() *abcicli.ReqRes); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(abcicli.ResponseCallback) *abcicli.ReqRes); ok { + r0 = rf(_a0) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*abcicli.ReqRes) @@ -84,20 +130,29 @@ func (_m *AppConnMempool) FlushAsync() *abcicli.ReqRes { } // FlushSync provides a mock function with given fields: -func (_m *AppConnMempool) FlushSync() error { +func (_m *AppConnMempool) FlushSync() (*types.ResponseFlush, error) { ret := _m.Called() - var r0 error - if rf, ok := ret.Get(0).(func() error); ok { + var r0 *types.ResponseFlush + if rf, ok := ret.Get(0).(func() *types.ResponseFlush); ok { r0 = rf() } else { - r0 = ret.Error(0) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseFlush) + } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// SetResponseCallback provides a mock function with given fields: _a0 -func (_m *AppConnMempool) SetResponseCallback(_a0 abcicli.Callback) { +// SetGlobalCallback provides a mock function with given fields: _a0 +func (_m *AppConnMempool) SetGlobalCallback(_a0 abcicli.GlobalCallback) { _m.Called(_a0) } diff --git a/proxy/mocks/app_conn_query.go b/proxy/mocks/app_conn_query.go index 1c93936e4..eec6053ed 100644 --- a/proxy/mocks/app_conn_query.go +++ b/proxy/mocks/app_conn_query.go @@ -1,4 +1,4 @@ -// Code generated by mockery 2.9.0. DO NOT EDIT. +// Code generated by mockery 2.7.4. DO NOT EDIT. package mocks diff --git a/proxy/mocks/app_conn_snapshot.go b/proxy/mocks/app_conn_snapshot.go index 85189ffad..0c37135a9 100644 --- a/proxy/mocks/app_conn_snapshot.go +++ b/proxy/mocks/app_conn_snapshot.go @@ -1,4 +1,4 @@ -// Code generated by mockery 2.9.0. DO NOT EDIT. +// Code generated by mockery 2.7.4. DO NOT EDIT. package mocks diff --git a/proxy/mocks/client_creator.go b/proxy/mocks/client_creator.go index f6aa04c06..69f80af56 100644 --- a/proxy/mocks/client_creator.go +++ b/proxy/mocks/client_creator.go @@ -1,11 +1,10 @@ -// Code generated by mockery v1.1.1. DO NOT EDIT. +// Code generated by mockery 2.7.4. DO NOT EDIT. package mocks import ( - mock "github.com/stretchr/testify/mock" - abcicli "github.com/line/ostracon/abci/client" + mock "github.com/stretchr/testify/mock" ) // ClientCreator is an autogenerated mock type for the ClientCreator type diff --git a/proxy/multi_app_conn.go b/proxy/multi_app_conn.go index 653fac3e4..33f095d6d 100644 --- a/proxy/multi_app_conn.go +++ b/proxy/multi_app_conn.go @@ -16,7 +16,7 @@ const ( connSnapshot = "snapshot" ) -// AppConns is the Tendermint's interface to the application that consists of +// AppConns is the Ostracon's interface to the application that consists of // multiple connections. type AppConns interface { service.Service @@ -114,8 +114,8 @@ func (app *multiAppConn) OnStart() error { app.consensusConnClient = c app.consensusConn = NewAppConnConsensus(c) - // Kill Tendermint if the ABCI application crashes. - go app.killTMOnClientError() + // Kill Ostracon if the ABCI application crashes. + go app.killOCOnClientError() return nil } @@ -124,10 +124,10 @@ func (app *multiAppConn) OnStop() { app.stopAllClients() } -func (app *multiAppConn) killTMOnClientError() { +func (app *multiAppConn) killOCOnClientError() { killFn := func(conn string, err error, logger tmlog.Logger) { logger.Error( - fmt.Sprintf("%s connection terminated. Did the application crash? Please restart tendermint", conn), + fmt.Sprintf("%s connection terminated. Did the application crash? Please restart ostracon", conn), "err", err) killErr := tmos.Kill() if killErr != nil { diff --git a/proxy/version.go b/proxy/version.go index 96b75bd9d..c2b65d3fc 100644 --- a/proxy/version.go +++ b/proxy/version.go @@ -9,7 +9,7 @@ import ( // the abci.RequestInfo message during handshake with the app. // It contains only compile-time version information. var RequestInfo = abci.RequestInfo{ - Version: version.TMCoreSemVer, + Version: version.OCCoreSemVer, BlockVersion: version.BlockProtocol, P2PVersion: version.P2PProtocol, } diff --git a/rpc/client/examples_test.go b/rpc/client/examples_test.go index 2c109b4fb..76b61d2fa 100644 --- a/rpc/client/examples_test.go +++ b/rpc/client/examples_test.go @@ -15,8 +15,8 @@ import ( func ExampleHTTP_simple() { // Start an ostracon node (and kvstore) in the background to test against app := kvstore.NewApplication() - node := rpctest.StartTendermint(app, rpctest.SuppressStdout, rpctest.RecreateConfig) - defer rpctest.StopTendermint(node) + node := rpctest.StartOstracon(app, rpctest.SuppressStdout, rpctest.RecreateConfig) + defer rpctest.StopOstracon(node) // Create our RPC client rpcAddr := rpctest.GetConfig().RPC.ListenAddress @@ -68,7 +68,7 @@ func ExampleHTTP_simple() { func ExampleHTTP_batching() { // Start an ostracon node (and kvstore) in the background to test against app := kvstore.NewApplication() - node := rpctest.StartTendermint(app, rpctest.SuppressStdout, rpctest.RecreateConfig) + node := rpctest.StartOstracon(app, rpctest.SuppressStdout, rpctest.RecreateConfig) // Create our RPC client rpcAddr := rpctest.GetConfig().RPC.ListenAddress @@ -77,7 +77,7 @@ func ExampleHTTP_batching() { log.Fatal(err) } - defer rpctest.StopTendermint(node) + defer rpctest.StopOstracon(node) // Create our two transactions k1 := []byte("firstName") diff --git a/rpc/client/helpers.go b/rpc/client/helpers.go index a1d218342..4eec8e279 100644 --- a/rpc/client/helpers.go +++ b/rpc/client/helpers.go @@ -57,7 +57,7 @@ func WaitForHeight(c StatusClient, h int64, waiter Waiter) error { // when the timeout duration has expired. // // This handles subscribing and unsubscribing under the hood -func WaitForOneEvent(c EventsClient, evtTyp string, timeout time.Duration) (types.TMEventData, error) { +func WaitForOneEvent(c EventsClient, evtTyp string, timeout time.Duration) (types.OCEventData, error) { const subscriber = "helpers" ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() @@ -76,7 +76,7 @@ func WaitForOneEvent(c EventsClient, evtTyp string, timeout time.Duration) (type select { case event := <-eventCh: - return event.Data.(types.TMEventData), nil + return event.Data.(types.OCEventData), nil case <-ctx.Done(): return nil, errors.New("timed out waiting for event") } diff --git a/rpc/client/http/http.go b/rpc/client/http/http.go index d8e2c36a4..d83a2b000 100644 --- a/rpc/client/http/http.go +++ b/rpc/client/http/http.go @@ -20,16 +20,16 @@ import ( ) /* -HTTP is a Client implementation that communicates with a Tendermint node over +HTTP is a Client implementation that communicates with an Ostracon node over JSON RPC and WebSockets. This is the main implementation you probably want to use in production code. -There are other implementations when calling the Tendermint node in-process +There are other implementations when calling the Ostracon node in-process (Local), or when you want to mock out the server for test code (mock). -You can subscribe for any event published by Tendermint using Subscribe method. +You can subscribe for any event published by Ostracon using Subscribe method. Note delivery is best-effort. If you don't read events fast enough or network is -slow, Tendermint might cancel the subscription. The client will attempt to +slow, Ostracon might cancel the subscription. The client will attempt to resubscribe (you don't need to do anything). It will keep trying every second indefinitely until successful. @@ -629,7 +629,7 @@ func (w *WSEvents) Subscribe(ctx context.Context, subscriber, query string, outc := make(chan ctypes.ResultEvent, outCap) w.mtx.Lock() - // subscriber param is ignored because Tendermint will override it with + // subscriber param is ignored because Ostracon will override it with // remote IP anyway. w.subscriptions[query] = outc w.mtx.Unlock() @@ -710,11 +710,11 @@ func (w *WSEvents) eventListener() { if resp.Error != nil { w.Logger.Error("WS error", "err", resp.Error.Error()) // Error can be ErrAlreadySubscribed or max client (subscriptions per - // client) reached or Tendermint exited. + // client) reached or Ostracon exited. // We can ignore ErrAlreadySubscribed, but need to retry in other // cases. if !isErrAlreadySubscribed(resp.Error) { - // Resubscribe after 1 second to give Tendermint time to restart (if + // Resubscribe after 1 second to give Ostracon time to restart (if // crashed). w.redoSubscriptionsAfter(1 * time.Second) } diff --git a/rpc/client/interface.go b/rpc/client/interface.go index eb5958e92..de4a56173 100644 --- a/rpc/client/interface.go +++ b/rpc/client/interface.go @@ -98,7 +98,7 @@ type NetworkClient interface { } // EventsClient is reactive, you can subscribe to any message, given the proper -// string. see tendermint/types/events.go +// string. see ostracon/types/events.go type EventsClient interface { // Subscribe subscribes given subscriber to query. Returns a channel with // cap=1 onto which events are published. An error is returned if it fails to diff --git a/rpc/client/local/local.go b/rpc/client/local/local.go index b51f72de8..6e2b66ac5 100644 --- a/rpc/client/local/local.go +++ b/rpc/client/local/local.go @@ -25,14 +25,14 @@ This implementation is useful for: * Running tests against a node in-process without the overhead of going through an http server -* Communication between an ABCI app and Tendermint core when they +* Communication between an ABCI app and Ostracon core when they are compiled in process. For real clients, you probably want to use client.HTTP. For more powerful control during testing, you probably want the "client/mock" package. -You can subscribe for any event published by Tendermint using Subscribe method. -Note delivery is best-effort. If you don't read events fast enough, Tendermint +You can subscribe for any event published by Ostracon using Subscribe method. +Note delivery is best-effort. If you don't read events fast enough, Ostracon might cancel the subscription. The client will attempt to resubscribe (you don't need to do anything). It will keep trying indefinitely with exponential backoff (10ms -> 20ms -> 40ms) until successful. diff --git a/rpc/client/main_test.go b/rpc/client/main_test.go index a445e66da..79734afcd 100644 --- a/rpc/client/main_test.go +++ b/rpc/client/main_test.go @@ -20,12 +20,12 @@ func TestMain(m *testing.M) { } app := kvstore.NewPersistentKVStoreApplication(dir) - node = rpctest.StartTendermint(app) + node = rpctest.StartOstracon(app) code := m.Run() // and shut down proper at the end - rpctest.StopTendermint(node) + rpctest.StopOstracon(node) _ = os.RemoveAll(dir) os.Exit(code) } diff --git a/rpc/client/mock/abci.go b/rpc/client/mock/abci.go index 52bd4bccd..dbeafbfc2 100644 --- a/rpc/client/mock/abci.go +++ b/rpc/client/mock/abci.go @@ -51,7 +51,7 @@ func (a ABCIApp) ABCIQueryWithOptions( // 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}) + res.CheckTx = a.App.CheckTxSync(abci.RequestCheckTx{Tx: tx}) if res.CheckTx.IsErr() { return &res, nil } @@ -61,11 +61,13 @@ func (a ABCIApp) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*ctypes.Re } func (a ABCIApp) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) { - c := a.App.CheckTx(abci.RequestCheckTx{Tx: tx}) + chRes := make(chan abci.ResponseCheckTx, 1) + a.App.CheckTxAsync(abci.RequestCheckTx{Tx: tx}, func(res abci.ResponseCheckTx) { + chRes <- res + }) + c := <-chRes // and this gets written in a background thread... - if !c.IsErr() { - go func() { a.App.DeliverTx(abci.RequestDeliverTx{Tx: tx}) }() - } + go func() { a.App.DeliverTx(abci.RequestDeliverTx{Tx: tx}) }() return &ctypes.ResultBroadcastTx{ Code: c.Code, Data: c.Data, @@ -76,7 +78,7 @@ func (a ABCIApp) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*ctypes.Res } func (a ABCIApp) BroadcastTxSync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) { - c := a.App.CheckTx(abci.RequestCheckTx{Tx: tx}) + c := a.App.CheckTxSync(abci.RequestCheckTx{Tx: tx}) // and this gets written in a background thread... if !c.IsErr() { go func() { a.App.DeliverTx(abci.RequestDeliverTx{Tx: tx}) }() diff --git a/rpc/client/rpc_test.go b/rpc/client/rpc_test.go index c39bcb0f2..9550571d9 100644 --- a/rpc/client/rpc_test.go +++ b/rpc/client/rpc_test.go @@ -351,8 +351,11 @@ func TestUnconfirmedTxs(t *testing.T) { ch := make(chan *abci.Response, 1) mempool := node.Mempool() - err := mempool.CheckTx(tx, func(resp *abci.Response) { ch <- resp }, mempl.TxInfo{}) - require.NoError(t, err) + mempool.CheckTxAsync(tx, mempl.TxInfo{}, func(err error) { + require.NoError(t, err) + }, func(resp *abci.Response) { + ch <- resp + }) // wait for tx to arrive in mempoool. select { @@ -381,8 +384,11 @@ func TestNumUnconfirmedTxs(t *testing.T) { ch := make(chan *abci.Response, 1) mempool := node.Mempool() - err := mempool.CheckTx(tx, func(resp *abci.Response) { ch <- resp }, mempl.TxInfo{}) - require.NoError(t, err) + mempool.CheckTxAsync(tx, mempl.TxInfo{}, func(err error) { + require.NoError(t, err) + }, func(resp *abci.Response) { + ch <- resp + }) // wait for tx to arrive in mempoool. select { diff --git a/rpc/core/blocks_test.go b/rpc/core/blocks_test.go index bc0a7fd1e..7d22a5d6e 100644 --- a/rpc/core/blocks_test.go +++ b/rpc/core/blocks_test.go @@ -4,11 +4,10 @@ import ( "fmt" "testing" + "github.com/line/tm-db/v2/memdb" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - dbm "github.com/tendermint/tm-db" - abci "github.com/line/ostracon/abci/types" tmstate "github.com/line/ostracon/proto/ostracon/state" ctypes "github.com/line/ostracon/rpc/core/types" @@ -81,7 +80,7 @@ func TestBlockResults(t *testing.T) { } env = &Environment{} - env.StateStore = sm.NewStore(dbm.NewMemDB()) + env.StateStore = sm.NewStore(memdb.NewDB()) err := env.StateStore.SaveABCIResponses(100, results) require.NoError(t, err) env.BlockStore = mockBlockStore{height: 100} diff --git a/rpc/core/env.go b/rpc/core/env.go index 42a6fd65f..6016c4fba 100644 --- a/rpc/core/env.go +++ b/rpc/core/env.go @@ -19,7 +19,10 @@ import ( const ( // see README defaultPerPage = 30 - maxPerPage = 100 + + // Temporarily set it to a sufficient value to reduce the number of tx search queries during the test. + // TODO It will be modified later to be configurable. (Also, add a option to get all tx of block) + maxPerPage = 10000 // SubscribeTimeout is the maximum time we wait to subscribe for an event. // must be less than the server's write timeout (see rpcserver.DefaultConfig) diff --git a/rpc/core/events.go b/rpc/core/events.go index 11457b2ed..07568fd63 100644 --- a/rpc/core/events.go +++ b/rpc/core/events.go @@ -12,7 +12,7 @@ import ( ) const ( - // Buffer on the Tendermint (server) side to allow some slowness in clients. + // Buffer on the Ostracon (server) side to allow some slowness in clients. subBufferSize = 100 ) @@ -62,7 +62,7 @@ func Subscribe(ctx *rpctypes.Context, query string) (*ctypes.ResultSubscribe, er if sub.Err() != tmpubsub.ErrUnsubscribed { var reason string if sub.Err() == nil { - reason = "Tendermint exited" + reason = "Ostracon exited" } else { reason = sub.Err().Error() } diff --git a/rpc/core/mempool.go b/rpc/core/mempool.go index 930a1c347..1c280ccd8 100644 --- a/rpc/core/mempool.go +++ b/rpc/core/mempool.go @@ -14,17 +14,21 @@ import ( ) //----------------------------------------------------------------------------- -// NOTE: tx should be signed, but this is only checked at the app level (not by Tendermint!) +// NOTE: tx should be signed, but this is only checked at the app level (not by Ostracon!) // BroadcastTxAsync returns right away, with no response. Does not wait for // CheckTx nor DeliverTx results. // More: https://docs.tendermint.com/master/rpc/#/Tx/broadcast_tx_async func BroadcastTxAsync(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) { - err := env.Mempool.CheckTx(tx, nil, mempl.TxInfo{}) - + chErr := make(chan error) + env.Mempool.CheckTxAsync(tx, mempl.TxInfo{}, func(err error) { + chErr <- err + }, nil) + err := <-chErr if err != nil { return nil, err } + return &ctypes.ResultBroadcastTx{Hash: tx.Hash()}, nil } @@ -32,14 +36,10 @@ func BroadcastTxAsync(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadca // DeliverTx result. // More: https://docs.tendermint.com/master/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 <- res - }, mempl.TxInfo{}) + res, err := env.Mempool.CheckTxSync(tx, mempl.TxInfo{}) if err != nil { return nil, err } - res := <-resCh r := res.GetCheckTx() return &ctypes.ResultBroadcastTx{ Code: r.Code, @@ -77,16 +77,12 @@ 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 <- res - }, mempl.TxInfo{}) + // Broadcast tx and check tx + checkTxResMsg, err := env.Mempool.CheckTxSync(tx, mempl.TxInfo{}) if err != nil { env.Logger.Error("Error on broadcastTxCommit", "err", err) return nil, fmt.Errorf("error on broadcastTxCommit: %v", err) } - checkTxResMsg := <-checkTxResCh checkTxRes := checkTxResMsg.GetCheckTx() if checkTxRes.Code != abci.CodeTypeOK { return &ctypes.ResultBroadcastTxCommit{ @@ -109,7 +105,7 @@ func BroadcastTxCommit(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadc case <-deliverTxSub.Cancelled(): var reason string if deliverTxSub.Err() == nil { - reason = "Tendermint exited" + reason = "Ostracon exited" } else { reason = deliverTxSub.Err().Error() } diff --git a/rpc/core/status.go b/rpc/core/status.go index e00d34ed5..78e141901 100644 --- a/rpc/core/status.go +++ b/rpc/core/status.go @@ -10,7 +10,7 @@ import ( "github.com/line/ostracon/types" ) -// Status returns Tendermint status including node info, pubkey, latest block +// Status returns Ostracon status including node info, pubkey, latest block // hash, app hash, block height and time. // More: https://docs.tendermint.com/master/rpc/#/Info/status func Status(ctx *rpctypes.Context) (*ctypes.ResultStatus, error) { diff --git a/rpc/core/types/responses.go b/rpc/core/types/responses.go index 7b2c1dc4c..c69a087ec 100644 --- a/rpc/core/types/responses.go +++ b/rpc/core/types/responses.go @@ -241,6 +241,6 @@ type ( // Event data from a subscription type ResultEvent struct { Query string `json:"query"` - Data types.TMEventData `json:"data"` + Data types.OCEventData `json:"data"` Events map[string][]string `json:"events"` } diff --git a/rpc/grpc/grpc_test.go b/rpc/grpc/grpc_test.go index 17e342301..929d22224 100644 --- a/rpc/grpc/grpc_test.go +++ b/rpc/grpc/grpc_test.go @@ -15,12 +15,12 @@ import ( func TestMain(m *testing.M) { // start an ostracon node in the background to test against app := kvstore.NewApplication() - node := rpctest.StartTendermint(app) + node := rpctest.StartOstracon(app) code := m.Run() // and shut down proper at the end - rpctest.StopTendermint(node) + rpctest.StopOstracon(node) os.Exit(code) } diff --git a/rpc/jsonrpc/client/http_json_client.go b/rpc/jsonrpc/client/http_json_client.go index 216aacf9b..ceb8b0722 100644 --- a/rpc/jsonrpc/client/http_json_client.go +++ b/rpc/jsonrpc/client/http_json_client.go @@ -10,6 +10,7 @@ import ( "net/http" "net/url" "strings" + "time" tmsync "github.com/line/ostracon/libs/sync" types "github.com/line/ostracon/rpc/jsonrpc/types" @@ -21,6 +22,10 @@ const ( protoWSS = "wss" protoWS = "ws" protoTCP = "tcp" + + defaultMaxIdleConns = 10000 + defaultIdleConnTimeout = 60 // sec + defaultExpectContinueTimeout = 1 // sec ) //------------------------------------------------------------- @@ -369,8 +374,12 @@ func DefaultHTTPClient(remoteAddr string) (*http.Client, error) { client := &http.Client{ Transport: &http.Transport{ // Set to true to prevent GZIP-bomb DoS attacks - DisableCompression: true, - Dial: dialFn, + DisableCompression: true, + Dial: dialFn, + MaxIdleConns: defaultMaxIdleConns, + MaxIdleConnsPerHost: defaultMaxIdleConns, + IdleConnTimeout: defaultIdleConnTimeout * time.Second, + ExpectContinueTimeout: defaultExpectContinueTimeout * time.Second, }, } diff --git a/rpc/jsonrpc/client/integration_test.go b/rpc/jsonrpc/client/integration_test.go index f828ef4de..df2f02891 100644 --- a/rpc/jsonrpc/client/integration_test.go +++ b/rpc/jsonrpc/client/integration_test.go @@ -27,7 +27,7 @@ func TestWSClientReconnectWithJitter(t *testing.T) { var errNotConnected = errors.New("not connected") clientMap := make(map[int]*WSClient) buf := new(bytes.Buffer) - logger := log.NewTMLogger(buf) + logger := log.NewOCLogger(buf) for i := 0; i < n; i++ { c, err := NewWS("tcp://foo", "/websocket") require.Nil(t, err) diff --git a/rpc/jsonrpc/doc.go b/rpc/jsonrpc/doc.go index 2ceb72098..d71af01ff 100644 --- a/rpc/jsonrpc/doc.go +++ b/rpc/jsonrpc/doc.go @@ -70,7 +70,7 @@ // rpcserver.RegisterRPCFuncs(mux, Routes) // wm := rpcserver.NewWebsocketManager(Routes) // mux.HandleFunc("/websocket", wm.WebsocketHandler) -// logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) +// logger := log.NewOCLogger(log.NewSyncWriter(os.Stdout)) // listener, err := rpc.Listen("0.0.0.0:8080", rpcserver.Config{}) // if err != nil { panic(err) } // go rpcserver.Serve(listener, mux, logger) diff --git a/rpc/jsonrpc/jsonrpc_test.go b/rpc/jsonrpc/jsonrpc_test.go index 79b7aad9c..4d394d8e1 100644 --- a/rpc/jsonrpc/jsonrpc_test.go +++ b/rpc/jsonrpc/jsonrpc_test.go @@ -107,7 +107,7 @@ var colorFn = func(keyvals ...interface{}) term.FgBgColor { // launch unix and tcp servers func setup() { - logger := log.NewTMLoggerWithColorFn(log.NewSyncWriter(os.Stdout), colorFn) + logger := log.NewOCLoggerWithColorFn(log.NewSyncWriter(os.Stdout), colorFn) cmd := exec.Command("rm", "-f", unixSocket) err := cmd.Start() diff --git a/rpc/jsonrpc/server/http_json_handler_test.go b/rpc/jsonrpc/server/http_json_handler_test.go index 450f0959e..8928ee6a7 100644 --- a/rpc/jsonrpc/server/http_json_handler_test.go +++ b/rpc/jsonrpc/server/http_json_handler_test.go @@ -22,7 +22,7 @@ func testMux() *http.ServeMux { } mux := http.NewServeMux() buf := new(bytes.Buffer) - logger := log.NewTMLogger(buf) + logger := log.NewOCLogger(buf) RegisterRPCFuncs(mux, funcMap, logger) return mux diff --git a/rpc/jsonrpc/server/http_server.go b/rpc/jsonrpc/server/http_server.go index e3eb8714a..b1b8fdb22 100644 --- a/rpc/jsonrpc/server/http_server.go +++ b/rpc/jsonrpc/server/http_server.go @@ -27,6 +27,8 @@ type Config struct { ReadTimeout time.Duration // mirrors http.Server#WriteTimeout WriteTimeout time.Duration + // mirrors http.Server#IdleTimeout + IdleTimeout time.Duration // MaxBodyBytes controls the maximum number of bytes the // server will read parsing the request body. MaxBodyBytes int64 @@ -40,6 +42,7 @@ func DefaultConfig() *Config { MaxOpenConnections: 0, // unlimited ReadTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second, + IdleTimeout: 60 * time.Second, MaxBodyBytes: int64(1000000), // 1MB MaxHeaderBytes: 1 << 20, // same as the net/http default } @@ -56,6 +59,7 @@ func Serve(listener net.Listener, handler http.Handler, logger log.Logger, confi Handler: RecoverAndLogHandler(maxBytesHandler{h: handler, n: config.MaxBodyBytes}, logger), ReadTimeout: config.ReadTimeout, WriteTimeout: config.WriteTimeout, + IdleTimeout: config.IdleTimeout, MaxHeaderBytes: config.MaxHeaderBytes, } err := s.Serve(listener) @@ -81,6 +85,7 @@ func ServeTLS( Handler: RecoverAndLogHandler(maxBytesHandler{h: handler, n: config.MaxBodyBytes}, logger), ReadTimeout: config.ReadTimeout, WriteTimeout: config.WriteTimeout, + IdleTimeout: config.IdleTimeout, MaxHeaderBytes: config.MaxHeaderBytes, } err := s.ServeTLS(listener, certFile, keyFile) diff --git a/rpc/jsonrpc/server/ws_handler.go b/rpc/jsonrpc/server/ws_handler.go index 4ff53b9d6..c43dbaa79 100644 --- a/rpc/jsonrpc/server/ws_handler.go +++ b/rpc/jsonrpc/server/ws_handler.go @@ -52,7 +52,7 @@ func NewWebsocketManager( // The default behaviour would be relevant to browser-based clients, // afaik. I suppose having a pass-through is a workaround for allowing // for more complex security schemes, shifting the burden of - // AuthN/AuthZ outside the Tendermint RPC. + // AuthN/AuthZ outside the Ostracon RPC. // I can't think of other uses right now that would warrant a TODO // though. The real backstory of this TODO shall remain shrouded in // mystery diff --git a/rpc/jsonrpc/test/main.go b/rpc/jsonrpc/test/main.go index f3c231a61..cc4d4ee23 100644 --- a/rpc/jsonrpc/test/main.go +++ b/rpc/jsonrpc/test/main.go @@ -26,7 +26,7 @@ type Result struct { func main() { var ( mux = http.NewServeMux() - logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout)) + logger = log.NewOCLogger(log.NewSyncWriter(os.Stdout)) ) // Stop upon receiving SIGTERM or CTRL-C. diff --git a/rpc/openapi/openapi.yaml b/rpc/openapi/openapi.yaml index 6d232d4a7..dbc5d3069 100644 --- a/rpc/openapi/openapi.yaml +++ b/rpc/openapi/openapi.yaml @@ -14,7 +14,7 @@ info: ## Configuration RPC can be configured by tuning parameters under `[rpc]` table in the - `$TMHOME/config/config.toml` file or by using the `--rpc.X` command-line + `$OCHOME/config/config.toml` file or by using the `--rpc.X` command-line flags. Default rpc listen address is `tcp://0.0.0.0:26657`. @@ -1200,7 +1200,7 @@ components: properties: type: type: string - example: "tendermint/PubKeyEd25519" + example: "ostracon/PubKeyEd25519" value: type: string example: "A6DoBUypNtUAyEHWtQ9bFjfNg8Bo9CrnkUGl6k6OHN4=" @@ -1644,7 +1644,7 @@ components: properties: type: type: string - example: "tendermint/PubKeyEd25519" + example: "ostracon/PubKeyEd25519" value: type: string example: "9tK9IT+FPdf2qm+5c2qaxi10sWP+3erWTKgftn2PaQM=" @@ -1803,7 +1803,7 @@ components: properties: type: type: string - example: "tendermint/PubKeyEd25519" + example: "ostracon/PubKeyEd25519" value: type: string example: "cOQZvh/h9ZioSeUMZB/1Vy1Xo5x2sjrVjlE/qHnYifM=" @@ -1974,7 +1974,7 @@ components: - "value" properties: type: - example: "tendermint/PubKeyEd25519" + example: "ostracon/PubKeyEd25519" value: type: "string" example: "VNMNfw7mrQBSpEvCtA9ykOe6BoR00RM9b/a9v3vXZhY=" @@ -2722,7 +2722,7 @@ components: properties: type: type: string - example: "tendermint/PubKeyEd25519" + example: "ostracon/PubKeyEd25519" value: type: string example: "9tK9IT+FPdf2qm+5c2qaxi10sWP+3erWTKgftn2PaQM=" diff --git a/rpc/test/helpers.go b/rpc/test/helpers.go index c8d91ed2d..cebb1a1d0 100644 --- a/rpc/test/helpers.go +++ b/rpc/test/helpers.go @@ -97,7 +97,7 @@ func createConfig() *cfg.Config { tm, rpc, grpc := makeAddrs() c.P2P.ListenAddress = tm c.RPC.ListenAddress = rpc - c.RPC.CORSAllowedOrigins = []string{"https://tendermint.com/"} + c.RPC.CORSAllowedOrigins = []string{"https://ostracon.com/"} c.RPC.GRPCListenAddress = grpc return c } @@ -115,13 +115,13 @@ func GetGRPCClient() core_grpc.BroadcastAPIClient { return core_grpc.StartGRPCClient(grpcAddr) } -// StartTendermint starts a test ostracon server in a go routine and returns when it is initialized -func StartTendermint(app abci.Application, opts ...func(*Options)) *nm.Node { +// StartOstracon starts a test ostracon server in a go routine and returns when it is initialized +func StartOstracon(app abci.Application, opts ...func(*Options)) *nm.Node { nodeOpts := defaultOptions for _, opt := range opts { opt(&nodeOpts) } - node := NewTendermint(app, &nodeOpts) + node := NewOstracon(app, &nodeOpts) err := node.Start() if err != nil { panic(err) @@ -132,15 +132,15 @@ func StartTendermint(app abci.Application, opts ...func(*Options)) *nm.Node { waitForGRPC() if !nodeOpts.suppressStdout { - fmt.Println("Tendermint running!") + fmt.Println("Ostracon running!") } return node } -// StopTendermint stops a test ostracon server, waits until it's stopped and +// StopOstracon stops a test ostracon server, waits until it's stopped and // cleans up test/config files. -func StopTendermint(node *nm.Node) { +func StopOstracon(node *nm.Node) { if err := node.Stop(); err != nil { node.Logger.Error("Error when tryint to stop node", "err", err) } @@ -148,15 +148,15 @@ func StopTendermint(node *nm.Node) { os.RemoveAll(node.Config().RootDir) } -// NewTendermint creates a new ostracon server and sleeps forever -func NewTendermint(app abci.Application, opts *Options) *nm.Node { +// NewOstracon creates a new ostracon server and sleeps forever +func NewOstracon(app abci.Application, opts *Options) *nm.Node { // Create & start node config := GetConfig(opts.recreateConfig) var logger log.Logger if opts.suppressStdout { logger = log.NewNopLogger() } else { - logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout)) + logger = log.NewOCLogger(log.NewSyncWriter(os.Stdout)) logger = log.NewFilter(logger, log.AllowError()) } pvKeyFile := config.PrivValidatorKeyFile() @@ -179,7 +179,7 @@ func NewTendermint(app abci.Application, opts *Options) *nm.Node { return node } -// SuppressStdout is an option that tries to make sure the RPC test Tendermint +// SuppressStdout is an option that tries to make sure the RPC test Ostracon // node doesn't log anything to stdout. func SuppressStdout(o *Options) { o.suppressStdout = true diff --git a/scripts/json2wal/main.go b/scripts/json2wal/main.go index ba594afd2..cb5b8baf8 100644 --- a/scripts/json2wal/main.go +++ b/scripts/json2wal/main.go @@ -37,7 +37,7 @@ func main() { } defer walFile.Close() - // the length of tendermint/wal/MsgInfo in the wal.json may exceed the defaultBufSize(4096) of bufio + // the length of ostracon/wal/MsgInfo in the wal.json may exceed the defaultBufSize(4096) of bufio // because of the byte array in BlockPart // leading to unmarshal error: unexpected end of JSON input br := bufio.NewReaderSize(f, int(2*types.BlockPartSizeBytes)) diff --git a/state/execution.go b/state/execution.go index 2060147ca..744476ddd 100644 --- a/state/execution.go +++ b/state/execution.go @@ -6,6 +6,7 @@ import ( "time" "github.com/line/ostracon/crypto" + canonictime "github.com/line/ostracon/types/time" abci "github.com/line/ostracon/abci/types" cryptoenc "github.com/line/ostracon/crypto/encoding" @@ -45,6 +46,30 @@ type BlockExecutor struct { metrics *Metrics } +type CommitStepTimes struct { + CommitExecuting types.StepDuration + CommitCommitting types.StepDuration + CommitRechecking types.StepDuration + Current *types.StepDuration +} + +func (st *CommitStepTimes) ToNextStep(from, next *types.StepDuration) time.Time { + now := canonictime.Now() + if st.Current == from { + from.End, next.Start = now, now + st.Current = next + } + return now +} + +func (st *CommitStepTimes) ToCommitCommitting() time.Time { + return st.ToNextStep(&st.CommitExecuting, &st.CommitCommitting) +} + +func (st *CommitStepTimes) ToCommitRechecking() time.Time { + return st.ToNextStep(&st.CommitCommitting, &st.CommitRechecking) +} + type BlockExecutorOption func(executor *BlockExecutor) func BlockExecutorWithMetrics(metrics *Metrics) BlockExecutorOption { @@ -130,24 +155,25 @@ func (blockExec *BlockExecutor) ValidateBlock(state State, round int32, block *t // from outside this package to process and commit an entire block. // It takes a blockID to avoid recomputing the parts hash. func (blockExec *BlockExecutor) ApplyBlock( - state State, blockID types.BlockID, block *types.Block, + state State, blockID types.BlockID, block *types.Block, stepTimes *CommitStepTimes, ) (State, int64, error) { - startTime := time.Now().UnixNano() // When doing ApplyBlock, we don't need to check whether the block.Round is same to current round, // so we just put block.Round for the current round parameter if err := blockExec.ValidateBlock(state, block.Round, block); err != nil { return state, 0, ErrInvalidBlock(err) } - endTime := time.Now().UnixNano() - blockExec.metrics.BlockVerifyingTime.Observe(float64(endTime-startTime) / 1000000) - startTime = endTime + execStartTime := time.Now().UnixNano() abciResponses, err := execBlockOnProxyApp( blockExec.logger, blockExec.proxyApp, block, blockExec.store, state.InitialHeight, state.VoterParams, ) - endTime = time.Now().UnixNano() - blockExec.metrics.BlockProcessingTime.Observe(float64(endTime-startTime) / 1000000) + execEndTime := time.Now().UnixNano() + + execTimeMs := float64(execEndTime-execStartTime) / 1000000 + blockExec.metrics.BlockProcessingTime.Observe(execTimeMs) + blockExec.metrics.BlockExecutionTime.Set(execTimeMs) + if err != nil { return state, 0, ErrProxyAppConn(err) } @@ -168,7 +194,7 @@ func (blockExec *BlockExecutor) ApplyBlock( return state, 0, fmt.Errorf("error in validator updates: %v", err) } - validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciValUpdates) + validatorUpdates, err := types.PB2OC.ValidatorUpdates(abciValUpdates) if err != nil { return state, 0, err } @@ -182,14 +208,21 @@ func (blockExec *BlockExecutor) ApplyBlock( return state, 0, fmt.Errorf("commit failed for application: %v", err) } - startTime = time.Now().UnixNano() + if stepTimes != nil { + stepTimes.ToCommitCommitting() + } + // Lock mempool, commit app state, update mempoool. - appHash, retainHeight, err := blockExec.Commit(state, block, abciResponses.DeliverTxs) + commitStartTime := time.Now().UnixNano() + appHash, retainHeight, err := blockExec.Commit(state, block, abciResponses.DeliverTxs, stepTimes) + commitEndTime := time.Now().UnixNano() + + commitTimeMs := float64(commitEndTime-commitStartTime) / 1000000 + blockExec.metrics.BlockCommitTime.Set(commitTimeMs) + if err != nil { return state, 0, fmt.Errorf("commit failed for application: %v", err) } - endTime = time.Now().UnixNano() - blockExec.metrics.BlockCommittingTime.Observe(float64(endTime-startTime) / 1000000) // Update evpool with the latest state. blockExec.evpool.Update(state, block.Evidence.Evidence) @@ -221,6 +254,7 @@ func (blockExec *BlockExecutor) Commit( state State, block *types.Block, deliverTxResponses []*abci.ResponseDeliverTx, + stepTimes *CommitStepTimes, ) ([]byte, int64, error) { blockExec.mempool.Lock() defer blockExec.mempool.Unlock() @@ -234,7 +268,13 @@ func (blockExec *BlockExecutor) Commit( } // Commit block, get hash back + appCommitStartTime := time.Now().UnixNano() res, err := blockExec.proxyApp.CommitSync() + appCommitEndTime := time.Now().UnixNano() + + appCommitTimeMs := float64(appCommitEndTime-appCommitStartTime) / 1000000 + blockExec.metrics.BlockAppCommitTime.Set(appCommitTimeMs) + if err != nil { blockExec.logger.Error("client error during proxyAppConn.CommitSync", "err", err) return nil, 0, err @@ -248,14 +288,21 @@ func (blockExec *BlockExecutor) Commit( "app_hash", fmt.Sprintf("%X", res.Data), ) + if stepTimes != nil { + stepTimes.ToCommitRechecking() + } + // Update mempool. + updateMempoolStartTime := time.Now().UnixNano() err = blockExec.mempool.Update( - block.Height, - block.Txs, + block, deliverTxResponses, TxPreCheck(state), - TxPostCheck(state), ) + updateMempoolEndTime := time.Now().UnixNano() + + updateMempoolTimeMs := float64(updateMempoolEndTime-updateMempoolStartTime) / 1000000 + blockExec.metrics.BlockUpdateMempoolTime.Set(updateMempoolTimeMs) return res.Data, res.RetainHeight, err } @@ -298,7 +345,7 @@ func execBlockOnProxyApp( txIndex++ } } - proxyAppConn.SetResponseCallback(proxyCb) + proxyAppConn.SetGlobalCallback(proxyCb) commitInfo := getBeginBlockValidatorInfo(block, store, initialHeight, voterParams) @@ -328,7 +375,7 @@ func execBlockOnProxyApp( startTime := time.Now() // run txs of block for _, tx := range block.Txs { - proxyAppConn.DeliverTxAsync(abci.RequestDeliverTx{Tx: tx}) + proxyAppConn.DeliverTxAsync(abci.RequestDeliverTx{Tx: tx}, nil) if err := proxyAppConn.Error(); err != nil { return nil, err } @@ -376,7 +423,7 @@ func getBeginBlockValidatorInfo(block *types.Block, store Store, for i, voter := range lastVoterSet.Voters { commitSig := block.LastCommit.Signatures[i] voteInfos[i] = abci.VoteInfo{ - Validator: types.TM2PB.Validator(voter), + Validator: types.OC2PB.Validator(voter), // TODO We need to change distribution of cosmos-sdk in order to reference this power for reward later VotingPower: voter.VotingPower, SignedLastBlock: !commitSig.Absent(), @@ -495,7 +542,7 @@ func updateState( // Fire NewBlock, NewBlockHeader. // Fire TxEvent for every tx. -// NOTE: if Tendermint crashes before commit, some or all of these events may be published again. +// NOTE: if Ostracon crashes before commit, some or all of these events may be published again. func fireEvents( logger log.Logger, eventBus types.BlockEventPublisher, diff --git a/state/execution_test.go b/state/execution_test.go index 6027d5252..4b10dfd03 100644 --- a/state/execution_test.go +++ b/state/execution_test.go @@ -51,7 +51,7 @@ func TestApplyBlock(t *testing.T) { block := makeBlockWithPrivVal(state, privVals[state.Validators.Validators[0].Address.String()], 1) blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: block.MakePartSet(testPartSize).Header()} - state, retainHeight, err := blockExec.ApplyBlock(state, blockID, block) + state, retainHeight, err := blockExec.ApplyBlock(state, blockID, block, nil) require.Nil(t, err) assert.EqualValues(t, retainHeight, 1) @@ -187,14 +187,14 @@ func TestBeginBlockByzantineValidators(t *testing.T) { Type: abci.EvidenceType_DUPLICATE_VOTE, Height: 3, Time: defaultEvidenceTime, - Validator: types.TM2PB.Validator(state.Validators.Validators[0]), + Validator: types.OC2PB.Validator(state.Validators.Validators[0]), TotalVotingPower: 10, }, { Type: abci.EvidenceType_LIGHT_CLIENT_ATTACK, Height: 8, Time: defaultEvidenceTime, - Validator: types.TM2PB.Validator(state.Validators.Validators[0]), + Validator: types.OC2PB.Validator(state.Validators.Validators[0]), TotalVotingPower: 12, }, } @@ -271,7 +271,7 @@ func TestBeginBlockByzantineValidators(t *testing.T) { proof, _ := privVal.GenerateVRFProof(message) block.Proof = bytes.HexBytes(proof) - state, retainHeight, err := blockExec.ApplyBlock(state, blockID, block) + state, retainHeight, err := blockExec.ApplyBlock(state, blockID, block, nil) require.Nil(t, err) assert.EqualValues(t, retainHeight, 1) @@ -389,7 +389,7 @@ func TestUpdateValidators(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.name, func(t *testing.T) { - updates, err := types.PB2TM.ValidatorUpdates(tc.abciUpdates) + updates, err := types.PB2OC.ValidatorUpdates(tc.abciUpdates) assert.NoError(t, err) err = tc.currentSet.UpdateWithChangeSet(updates) if tc.shouldErr { @@ -453,7 +453,7 @@ func TestEndBlockValidatorUpdates(t *testing.T) { {PubKey: pk, Power: 10}, } - state, _, err = blockExec.ApplyBlock(state, blockID, block) + state, _, err = blockExec.ApplyBlock(state, blockID, block, nil) require.Nil(t, err) // test new validator was added to NextValidators if assert.Equal(t, state.Validators.Size()+1, state.NextValidators.Size()) { @@ -509,7 +509,7 @@ func TestEndBlockValidatorUpdatesResultingInEmptySet(t *testing.T) { {PubKey: vp, Power: 0}, } - assert.NotPanics(t, func() { state, _, err = blockExec.ApplyBlock(state, blockID, block) }) + assert.NotPanics(t, func() { state, _, err = blockExec.ApplyBlock(state, blockID, block, nil) }) assert.NotNil(t, err) assert.NotEmpty(t, state.NextValidators.Validators) } diff --git a/state/export_test.go b/state/export_test.go index e492d029a..3e4bb3dab 100644 --- a/state/export_test.go +++ b/state/export_test.go @@ -1,7 +1,7 @@ package state import ( - dbm "github.com/tendermint/tm-db" + dbm "github.com/line/tm-db/v2" abci "github.com/line/ostracon/abci/types" tmstate "github.com/line/ostracon/proto/ostracon/state" diff --git a/state/helpers_test.go b/state/helpers_test.go index c434728dd..0f26bf1ca 100644 --- a/state/helpers_test.go +++ b/state/helpers_test.go @@ -5,7 +5,8 @@ import ( "fmt" "time" - dbm "github.com/tendermint/tm-db" + dbm "github.com/line/tm-db/v2" + "github.com/line/tm-db/v2/memdb" abci "github.com/line/ostracon/abci/types" "github.com/line/ostracon/crypto" @@ -64,7 +65,7 @@ func makeAndApplyGoodBlock(state sm.State, privVal types.PrivValidator, height i } blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: types.PartSetHeader{Total: 3, Hash: tmrand.Bytes(32)}} - state, _, err := blockExec.ApplyBlock(state, blockID, block) + state, _, err := blockExec.ApplyBlock(state, blockID, block, nil) if err != nil { return state, types.BlockID{}, err } @@ -123,7 +124,7 @@ func makeState(nVals, height int) (sm.State, dbm.DB, map[string]types.PrivValida AppHash: nil, }) - stateDB := dbm.NewMemDB() + stateDB := memdb.NewDB() stateStore := sm.NewStore(stateDB) if err := stateStore.Save(s); err != nil { panic(err) @@ -183,8 +184,8 @@ func makeHeaderPartsResponsesValPubKeyChange( 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), + types.OC2PB.NewValidatorUpdate(val.PubKey, 0), + types.OC2PB.NewValidatorUpdate(pubkey, 10), }, } } @@ -208,7 +209,7 @@ func makeHeaderPartsResponsesValPowerChange( if val.StakingPower != power { abciResponses.EndBlock = &abci.ResponseEndBlock{ ValidatorUpdates: []abci.ValidatorUpdate{ - types.TM2PB.NewValidatorUpdate(val.PubKey, power), + types.OC2PB.NewValidatorUpdate(val.PubKey, power), }, } } @@ -224,7 +225,7 @@ func makeHeaderPartsResponsesParams( block := makeBlock(state, state.LastBlockHeight+1) abciResponses := &tmstate.ABCIResponses{ BeginBlock: &abci.ResponseBeginBlock{}, - EndBlock: &abci.ResponseEndBlock{ConsensusParamUpdates: types.TM2PB.ConsensusParams(¶ms)}, + EndBlock: &abci.ResponseEndBlock{ConsensusParamUpdates: types.OC2PB.ConsensusParams(¶ms)}, } return block.Header, types.BlockID{Hash: block.Hash(), PartSetHeader: types.PartSetHeader{}}, abciResponses } @@ -280,10 +281,14 @@ func (app *testApp) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx return abci.ResponseDeliverTx{Events: []abci.Event{}} } -func (app *testApp) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx { +func (app *testApp) CheckTxSync(req abci.RequestCheckTx) abci.ResponseCheckTx { return abci.ResponseCheckTx{} } +func (app *testApp) CheckTxAsync(req abci.RequestCheckTx, callback abci.CheckTxCallback) { + callback(abci.ResponseCheckTx{}) +} + func (app *testApp) Commit() abci.ResponseCommit { return abci.ResponseCommit{RetainHeight: 1} } diff --git a/state/metrics.go b/state/metrics.go index 7461936d9..8033cefa6 100644 --- a/state/metrics.go +++ b/state/metrics.go @@ -15,12 +15,16 @@ const ( // Metrics contains metrics exposed by this package. type Metrics struct { - // Time of ValidBlock - BlockVerifyingTime metrics.Histogram // Time between BeginBlock and EndBlock. BlockProcessingTime metrics.Histogram - // Time of Commit - BlockCommittingTime metrics.Histogram + // Time gauge between BeginBlock and EndBlock. + BlockExecutionTime metrics.Gauge + // Time of commit + BlockCommitTime metrics.Gauge + // Time of app commit + BlockAppCommitTime metrics.Gauge + // Time of update mempool + BlockUpdateMempoolTime metrics.Gauge } // PrometheusMetrics returns Metrics build using Prometheus client library. @@ -36,13 +40,6 @@ func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics { compositeBuckets = append(compositeBuckets, stdprometheus.LinearBuckets(1000, 500, 4)...) return &Metrics{ - BlockVerifyingTime: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{ - Namespace: namespace, - Subsystem: MetricsSubsystem, - Name: "block_verifying_time", - Help: "Time of ValidBlock in ms.", - Buckets: stdprometheus.LinearBuckets(50, 50, 10), - }, labels).With(labelsAndValues...), BlockProcessingTime: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{ Namespace: namespace, Subsystem: MetricsSubsystem, @@ -50,12 +47,29 @@ func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics { Help: "Time between BeginBlock and EndBlock in ms.", Buckets: compositeBuckets, }, labels).With(labelsAndValues...), - BlockCommittingTime: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{ + BlockExecutionTime: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: MetricsSubsystem, + Name: "block_execution_time", + Help: "Time between BeginBlock and EndBlock in ms.", + }, labels).With(labelsAndValues...), + BlockCommitTime: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: MetricsSubsystem, + Name: "block_commit_time", + Help: "Time of commit in ms.", + }, labels).With(labelsAndValues...), + BlockAppCommitTime: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: MetricsSubsystem, + Name: "block_app_commit_time", + Help: "Time of app commit in ms.", + }, labels).With(labelsAndValues...), + BlockUpdateMempoolTime: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ Namespace: namespace, Subsystem: MetricsSubsystem, - Name: "block_committing_time", - Help: "Time of Commit in ms.", - Buckets: stdprometheus.LinearBuckets(20, 20, 10), + Name: "block_update_mempool_time", + Help: "Time of update mempool in ms.", }, labels).With(labelsAndValues...), } } @@ -63,8 +77,10 @@ func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics { // NopMetrics returns no-op Metrics. func NopMetrics() *Metrics { return &Metrics{ - BlockVerifyingTime: discard.NewHistogram(), - BlockProcessingTime: discard.NewHistogram(), - BlockCommittingTime: discard.NewHistogram(), + BlockProcessingTime: discard.NewHistogram(), + BlockExecutionTime: discard.NewGauge(), + BlockCommitTime: discard.NewGauge(), + BlockAppCommitTime: discard.NewGauge(), + BlockUpdateMempoolTime: discard.NewGauge(), } } diff --git a/state/mocks/store.go b/state/mocks/store.go index a44186ff0..d9fba676d 100644 --- a/state/mocks/store.go +++ b/state/mocks/store.go @@ -6,9 +6,9 @@ import ( mock "github.com/stretchr/testify/mock" state "github.com/line/ostracon/state" - tendermintstate "github.com/line/ostracon/proto/ostracon/state" + ostraconstate "github.com/line/ostracon/proto/ostracon/state" - tenderminttypes "github.com/line/ostracon/types" + ostracontypes "github.com/line/ostracon/types" types "github.com/line/ostracon/proto/ostracon/types" ) @@ -54,15 +54,15 @@ func (_m *Store) Load() (state.State, error) { } // LoadABCIResponses provides a mock function with given fields: _a0 -func (_m *Store) LoadABCIResponses(_a0 int64) (*tendermintstate.ABCIResponses, error) { +func (_m *Store) LoadABCIResponses(_a0 int64) (*ostraconstate.ABCIResponses, error) { ret := _m.Called(_a0) - var r0 *tendermintstate.ABCIResponses - if rf, ok := ret.Get(0).(func(int64) *tendermintstate.ABCIResponses); ok { + var r0 *ostraconstate.ABCIResponses + if rf, ok := ret.Get(0).(func(int64) *ostraconstate.ABCIResponses); ok { r0 = rf(_a0) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*tendermintstate.ABCIResponses) + r0 = ret.Get(0).(*ostraconstate.ABCIResponses) } } @@ -98,18 +98,18 @@ func (_m *Store) LoadConsensusParams(_a0 int64) (types.ConsensusParams, error) { } // LoadFromDBOrGenesisDoc provides a mock function with given fields: _a0 -func (_m *Store) LoadFromDBOrGenesisDoc(_a0 *tenderminttypes.GenesisDoc) (state.State, error) { +func (_m *Store) LoadFromDBOrGenesisDoc(_a0 *ostracontypes.GenesisDoc) (state.State, error) { ret := _m.Called(_a0) var r0 state.State - if rf, ok := ret.Get(0).(func(*tenderminttypes.GenesisDoc) state.State); ok { + if rf, ok := ret.Get(0).(func(*ostracontypes.GenesisDoc) state.State); ok { r0 = rf(_a0) } else { r0 = ret.Get(0).(state.State) } var r1 error - if rf, ok := ret.Get(1).(func(*tenderminttypes.GenesisDoc) error); ok { + if rf, ok := ret.Get(1).(func(*ostracontypes.GenesisDoc) error); ok { r1 = rf(_a0) } else { r1 = ret.Error(1) @@ -140,15 +140,15 @@ func (_m *Store) LoadFromDBOrGenesisFile(_a0 string) (state.State, error) { } // LoadValidators provides a mock function with given fields: _a0 -func (_m *Store) LoadValidators(_a0 int64) (*tenderminttypes.ValidatorSet, error) { +func (_m *Store) LoadValidators(_a0 int64) (*ostracontypes.ValidatorSet, error) { ret := _m.Called(_a0) - var r0 *tenderminttypes.ValidatorSet - if rf, ok := ret.Get(0).(func(int64) *tenderminttypes.ValidatorSet); ok { + var r0 *ostracontypes.ValidatorSet + if rf, ok := ret.Get(0).(func(int64) *ostracontypes.ValidatorSet); ok { r0 = rf(_a0) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*tenderminttypes.ValidatorSet) + r0 = ret.Get(0).(*ostracontypes.ValidatorSet) } } @@ -163,20 +163,20 @@ func (_m *Store) LoadValidators(_a0 int64) (*tenderminttypes.ValidatorSet, error } // LoadVoters provides a mock function with given fields: _a0, _a1 -func (_m *Store) LoadVoters(_a0 int64, _a1 *tenderminttypes.VoterParams) (*tenderminttypes.VoterSet, error) { +func (_m *Store) LoadVoters(_a0 int64, _a1 *ostracontypes.VoterParams) (*ostracontypes.VoterSet, error) { ret := _m.Called(_a0, _a1) - var r0 *tenderminttypes.VoterSet - if rf, ok := ret.Get(0).(func(int64, *tenderminttypes.VoterParams) *tenderminttypes.VoterSet); ok { + var r0 *ostracontypes.VoterSet + if rf, ok := ret.Get(0).(func(int64, *ostracontypes.VoterParams) *ostracontypes.VoterSet); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*tenderminttypes.VoterSet) + r0 = ret.Get(0).(*ostracontypes.VoterSet) } } var r1 error - if rf, ok := ret.Get(1).(func(int64, *tenderminttypes.VoterParams) error); ok { + if rf, ok := ret.Get(1).(func(int64, *ostracontypes.VoterParams) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -214,11 +214,11 @@ func (_m *Store) Save(_a0 state.State) error { } // SaveABCIResponses provides a mock function with given fields: _a0, _a1 -func (_m *Store) SaveABCIResponses(_a0 int64, _a1 *tendermintstate.ABCIResponses) error { +func (_m *Store) SaveABCIResponses(_a0 int64, _a1 *ostraconstate.ABCIResponses) 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, *ostraconstate.ABCIResponses) error); ok { r0 = rf(_a0, _a1) } else { r0 = ret.Error(0) diff --git a/state/state.go b/state/state.go index fa4b34df7..93a7c1f65 100644 --- a/state/state.go +++ b/state/state.go @@ -33,12 +33,12 @@ var InitStateVersion = tmstate.Version{ Block: version.BlockProtocol, App: 0, }, - Software: version.TMCoreSemVer, + Software: version.OCCoreSemVer, } //----------------------------------------------------------------------------- -// State is a short description of the latest committed block of the Tendermint consensus. +// State is a short description of the latest committed block of the Ostracon consensus. // It keeps all information necessary to validate new blocks, // including the last validator set and the consensus params. // All fields are exposed so the struct can be easily serialized, diff --git a/state/state_test.go b/state/state_test.go index ae12a0bd6..d1aa80847 100644 --- a/state/state_test.go +++ b/state/state_test.go @@ -9,10 +9,11 @@ import ( "testing" "time" + "github.com/line/tm-db/v2/metadb" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - dbm "github.com/tendermint/tm-db" + dbm "github.com/line/tm-db/v2" abci "github.com/line/ostracon/abci/types" cfg "github.com/line/ostracon/config" @@ -29,8 +30,8 @@ import ( // setupTestCase does setup common to all test cases. func setupTestCase(t *testing.T) (func(t *testing.T), dbm.DB, sm.State) { config := cfg.ResetTestRoot("state_") - dbType := dbm.BackendType(config.DBBackend) - stateDB, err := dbm.NewDB("state", dbType, config.DBDir()) + dbType := metadb.BackendType(config.DBBackend) + stateDB, err := metadb.NewDB("state", dbType, config.DBDir()) stateStore := sm.NewStore(stateDB) require.NoError(t, err) state, err := stateStore.LoadFromDBOrGenesisFile(config.GenesisFile()) @@ -112,7 +113,7 @@ func TestABCIResponsesSaveLoad1(t *testing.T) { 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{ - types.TM2PB.NewValidatorUpdate(ed25519.GenPrivKey().PubKey(), 10), + types.OC2PB.NewValidatorUpdate(ed25519.GenPrivKey().PubKey(), 10), }} err := stateStore.SaveABCIResponses(block.Height, abciResponses) @@ -275,7 +276,7 @@ func TestOneValidatorChangesSaveLoad(t *testing.T) { power++ } header, blockID, responses := makeHeaderPartsResponsesValPowerChange(state, power) - validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.EndBlock.ValidatorUpdates) + validatorUpdates, err = types.PB2OC.ValidatorUpdates(responses.EndBlock.ValidatorUpdates) require.NoError(t, err) state, err = sm.UpdateState(state, blockID, &header, responses, validatorUpdates) require.NoError(t, err) @@ -534,7 +535,7 @@ func TestProposerPriorityDoesNotGetResetToZero(t *testing.T) { BeginBlock: &abci.ResponseBeginBlock{}, EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil}, } - validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) + validatorUpdates, err := types.PB2OC.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) require.NoError(t, err) updatedState, err := sm.UpdateState(state, blockID, &block.Header, abciResponses, validatorUpdates) assert.NoError(t, err) @@ -549,7 +550,7 @@ func TestProposerPriorityDoesNotGetResetToZero(t *testing.T) { require.NoError(t, err) updateAddVal := abci.ValidatorUpdate{PubKey: fvp, Power: val2StakingPower} - validatorUpdates, err = types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{updateAddVal}) + validatorUpdates, err = types.PB2OC.ValidatorUpdates([]abci.ValidatorUpdate{updateAddVal}) assert.NoError(t, err) updatedState2, err := sm.UpdateState(updatedState, blockID, &block.Header, abciResponses, validatorUpdates) assert.NoError(t, err) @@ -585,7 +586,7 @@ func TestProposerPriorityDoesNotGetResetToZero(t *testing.T) { // 1. Add - Val2 StakingPower change to 1 => updatedVotingPowVal2 := int64(1) updateVal := abci.ValidatorUpdate{PubKey: fvp, Power: updatedVotingPowVal2} - validatorUpdates, err = types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{updateVal}) + validatorUpdates, err = types.PB2OC.ValidatorUpdates([]abci.ValidatorUpdate{updateVal}) assert.NoError(t, err) // this will cause the diff of priorities (77) @@ -651,7 +652,7 @@ func TestProposerPriorityProposerAlternates(t *testing.T) { BeginBlock: &abci.ResponseBeginBlock{}, EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil}, } - validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) + validatorUpdates, err := types.PB2OC.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) require.NoError(t, err) updatedState, err := sm.UpdateState(state, blockID, &block.Header, abciResponses, validatorUpdates) @@ -668,7 +669,7 @@ func TestProposerPriorityProposerAlternates(t *testing.T) { fvp, err := cryptoenc.PubKeyToProto(val2PubKey) require.NoError(t, err) updateAddVal := abci.ValidatorUpdate{PubKey: fvp, Power: val1StakingPower} - validatorUpdates, err = types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{updateAddVal}) + validatorUpdates, err = types.PB2OC.ValidatorUpdates([]abci.ValidatorUpdate{updateAddVal}) assert.NoError(t, err) updatedState2, err := sm.UpdateState(updatedState, blockID, &block.Header, abciResponses, validatorUpdates) @@ -711,7 +712,7 @@ func TestProposerPriorityProposerAlternates(t *testing.T) { updatedVal2, ) - validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) + validatorUpdates, err = types.PB2OC.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) require.NoError(t, err) updatedState3, err := sm.UpdateState(updatedState2, blockID, &block.Header, abciResponses, validatorUpdates) @@ -754,7 +755,7 @@ func TestProposerPriorityProposerAlternates(t *testing.T) { BeginBlock: &abci.ResponseBeginBlock{}, EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil}, } - validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) + validatorUpdates, err = types.PB2OC.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) require.NoError(t, err) oldState, err = sm.UpdateState(oldState, blockID, &block.Header, abciResponses, validatorUpdates) @@ -770,7 +771,7 @@ func TestProposerPriorityProposerAlternates(t *testing.T) { BeginBlock: &abci.ResponseBeginBlock{}, EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil}, } - validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) + validatorUpdates, err = types.PB2OC.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) require.NoError(t, err) updatedState, err := sm.UpdateState(oldState, blockID, &block.Header, abciResponses, validatorUpdates) @@ -829,7 +830,7 @@ func TestLargeGenesisValidator(t *testing.T) { BeginBlock: &abci.ResponseBeginBlock{}, EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil}, } - validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) + validatorUpdates, err := types.PB2OC.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) require.NoError(t, err) block := makeBlock(oldState, oldState.LastBlockHeight+1) @@ -856,7 +857,7 @@ func TestLargeGenesisValidator(t *testing.T) { fvp, err := cryptoenc.PubKeyToProto(firstAddedValPubKey) require.NoError(t, err) firstAddedVal := abci.ValidatorUpdate{PubKey: fvp, Power: firstAddedValStakingPower} - validatorUpdates, err := types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{firstAddedVal}) + validatorUpdates, err := types.PB2OC.ValidatorUpdates([]abci.ValidatorUpdate{firstAddedVal}) assert.NoError(t, err) abciResponses := &tmstate.ABCIResponses{ BeginBlock: &abci.ResponseBeginBlock{}, @@ -874,7 +875,7 @@ func TestLargeGenesisValidator(t *testing.T) { BeginBlock: &abci.ResponseBeginBlock{}, EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil}, } - validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) + validatorUpdates, err := types.PB2OC.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) require.NoError(t, err) block := makeBlock(lastState, lastState.LastBlockHeight+1) @@ -903,7 +904,7 @@ func TestLargeGenesisValidator(t *testing.T) { ap, err := cryptoenc.PubKeyToProto(addedPubKey) require.NoError(t, err) addedVal := abci.ValidatorUpdate{PubKey: ap, Power: firstAddedValStakingPower} - validatorUpdates, err := types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{addedVal}) + validatorUpdates, err := types.PB2OC.ValidatorUpdates([]abci.ValidatorUpdate{addedVal}) assert.NoError(t, err) abciResponses := &tmstate.ABCIResponses{ @@ -927,7 +928,7 @@ func TestLargeGenesisValidator(t *testing.T) { } block = makeBlock(oldState, oldState.LastBlockHeight+1) blockID = types.BlockID{Hash: block.Hash(), PartSetHeader: block.MakePartSet(testPartSize).Header()} - validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) + validatorUpdates, err = types.PB2OC.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) require.NoError(t, err) updatedState, err = sm.UpdateState(state, blockID, &block.Header, abciResponses, validatorUpdates) require.NoError(t, err) @@ -944,7 +945,7 @@ func TestLargeGenesisValidator(t *testing.T) { BeginBlock: &abci.ResponseBeginBlock{}, EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil}, } - validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) + validatorUpdates, err = types.PB2OC.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) require.NoError(t, err) block = makeBlock(curState, curState.LastBlockHeight+1) blockID = types.BlockID{Hash: block.Hash(), PartSetHeader: block.MakePartSet(testPartSize).Header()} @@ -969,7 +970,7 @@ func TestLargeGenesisValidator(t *testing.T) { BeginBlock: &abci.ResponseBeginBlock{}, EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil}, } - validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) + validatorUpdates, err := types.PB2OC.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates) require.NoError(t, err) block := makeBlock(updatedState, updatedState.LastBlockHeight+1) @@ -1040,7 +1041,7 @@ func TestManyValidatorChangesSaveLoad(t *testing.T) { // Save state etc. var validatorUpdates []*types.Validator - validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.EndBlock.ValidatorUpdates) + validatorUpdates, err = types.PB2OC.ValidatorUpdates(responses.EndBlock.ValidatorUpdates) require.NoError(t, err) state, err = sm.UpdateState(state, blockID, &header, responses, validatorUpdates) require.Nil(t, err) @@ -1122,7 +1123,7 @@ func TestConsensusParamsChangesSaveLoad(t *testing.T) { cp = params[changeIndex] } header, blockID, responses := makeHeaderPartsResponsesParams(state, cp) - validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.EndBlock.ValidatorUpdates) + validatorUpdates, err = types.PB2OC.ValidatorUpdates(responses.EndBlock.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 630b03d2b..964da2ef9 100644 --- a/state/store.go +++ b/state/store.go @@ -5,7 +5,7 @@ import ( "fmt" "github.com/gogo/protobuf/proto" - dbm "github.com/tendermint/tm-db" + dbm "github.com/line/tm-db/v2" abci "github.com/line/ostracon/abci/types" tmmath "github.com/line/ostracon/libs/math" @@ -80,7 +80,7 @@ type Store interface { PruneStates(int64, int64) error } -// dbStore wraps a db (github.com/tendermint/tm-db) +// dbStore wraps a db (github.com/line/tm-db/v2) type dbStore struct { db dbm.DB } @@ -171,7 +171,7 @@ func (store dbStore) save(state State, key []byte) error { // If first block, save validators for the block. if nextHeight == 1 { nextHeight = state.InitialHeight - // This extra logic due to Tendermint validator set changes being delayed 1 block. + // This extra logic due to Ostracon validator set changes being delayed 1 block. // It may get overwritten due to InitChain validator updates. if err := store.saveValidatorsInfo(nextHeight, nextHeight, state.Validators); err != nil { return err diff --git a/state/store_test.go b/state/store_test.go index 430fa87a5..dee26b402 100644 --- a/state/store_test.go +++ b/state/store_test.go @@ -5,11 +5,11 @@ import ( "os" "testing" + "github.com/line/tm-db/v2/memdb" + "github.com/line/tm-db/v2/metadb" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - dbm "github.com/tendermint/tm-db" - abci "github.com/line/ostracon/abci/types" cfg "github.com/line/ostracon/config" "github.com/line/ostracon/crypto" @@ -22,7 +22,7 @@ import ( ) func TestStoreLoadValidators(t *testing.T) { - stateDB := dbm.NewMemDB() + stateDB := memdb.NewDB() stateStore := sm.NewStore(stateDB) val, _ := types.RandValidator(true, 10) vals := types.NewValidatorSet([]*types.Validator{val}) @@ -47,7 +47,7 @@ func TestStoreLoadValidators(t *testing.T) { } func TestStoreLoadVoters(t *testing.T) { - stateDB := dbm.NewMemDB() + stateDB := memdb.NewDB() stateStore := sm.NewStore(stateDB) val, _ := types.RandValidator(true, 10) vals := types.NewValidatorSet([]*types.Validator{val}) @@ -64,8 +64,8 @@ func BenchmarkLoadValidators(b *testing.B) { config := cfg.ResetTestRoot("state_") defer os.RemoveAll(config.RootDir) - dbType := dbm.BackendType(config.DBBackend) - stateDB, err := dbm.NewDB("state", dbType, config.DBDir()) + dbType := metadb.BackendType(config.DBBackend) + stateDB, err := metadb.NewDB("state", dbType, config.DBDir()) require.NoError(b, err) stateStore := sm.NewStore(stateDB) state, err := stateStore.LoadFromDBOrGenesisFile(config.GenesisFile()) @@ -145,7 +145,7 @@ func TestPruneStates(t *testing.T) { for name, tc := range testcases { tc := tc t.Run(name, func(t *testing.T) { - db := dbm.NewMemDB() + db := memdb.NewDB() stateStore := sm.NewStore(db) pk := ed25519.GenPrivKey().PubKey() diff --git a/state/tx_filter.go b/state/tx_filter.go index 66bb14943..aa940badd 100644 --- a/state/tx_filter.go +++ b/state/tx_filter.go @@ -14,9 +14,3 @@ func TxPreCheck(state State) mempl.PreCheckFunc { ) return mempl.PreCheckMaxBytes(maxDataBytes) } - -// TxPostCheck returns a function to filter transactions after processing. -// The function limits the gas wanted by a transaction to the block's maximum total gas. -func TxPostCheck(state State) mempl.PostCheckFunc { - return mempl.PostCheckMaxGas(state.ConsensusParams.Block.MaxGas) -} diff --git a/state/tx_filter_test.go b/state/tx_filter_test.go index 12532f2e5..a1446be39 100644 --- a/state/tx_filter_test.go +++ b/state/tx_filter_test.go @@ -4,11 +4,10 @@ import ( "os" "testing" + "github.com/line/tm-db/v2/metadb" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - dbm "github.com/tendermint/tm-db" - tmrand "github.com/line/ostracon/libs/rand" sm "github.com/line/ostracon/state" "github.com/line/ostracon/types" @@ -31,7 +30,7 @@ func TestTxFilter(t *testing.T) { } for i, tc := range testCases { - stateDB, err := dbm.NewDB("state", "memdb", os.TempDir()) + stateDB, err := metadb.NewDB("state", "memdb", os.TempDir()) require.NoError(t, err) stateStore := sm.NewStore(stateDB) state, err := stateStore.LoadFromDBOrGenesisDoc(genDoc) diff --git a/state/txindex/indexer_service_test.go b/state/txindex/indexer_service_test.go index ba209a86e..941768625 100644 --- a/state/txindex/indexer_service_test.go +++ b/state/txindex/indexer_service_test.go @@ -4,11 +4,10 @@ import ( "testing" "time" + "github.com/line/tm-db/v2/memdb" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - db "github.com/tendermint/tm-db" - abci "github.com/line/ostracon/abci/types" "github.com/line/ostracon/libs/log" "github.com/line/ostracon/state/txindex" @@ -29,7 +28,7 @@ func TestIndexerServiceIndexesBlocks(t *testing.T) { }) // tx indexer - store := db.NewMemDB() + store := memdb.NewDB() txIndexer := kv.NewTxIndex(store) service := txindex.NewIndexerService(txIndexer, eventBus) diff --git a/state/txindex/kv/kv.go b/state/txindex/kv/kv.go index a890d1f05..b15511e5b 100644 --- a/state/txindex/kv/kv.go +++ b/state/txindex/kv/kv.go @@ -10,7 +10,7 @@ import ( "time" "github.com/gogo/protobuf/proto" - dbm "github.com/tendermint/tm-db" + dbm "github.com/line/tm-db/v2" abci "github.com/line/ostracon/abci/types" "github.com/line/ostracon/libs/pubsub/query" @@ -407,7 +407,7 @@ func (txi *TxIndex) match( switch { case c.Op == query.OpEqual: - it, err := dbm.IteratePrefix(txi.store, startKeyBz) + it, err := txi.store.PrefixIterator(startKeyBz) if err != nil { panic(err) } @@ -430,7 +430,7 @@ func (txi *TxIndex) match( case c.Op == query.OpExists: // XXX: can't use startKeyBz here because c.Operand is nil // (e.g. "account.owner//" won't match w/ a single row) - it, err := dbm.IteratePrefix(txi.store, startKey(c.CompositeKey)) + it, err := txi.store.PrefixIterator(startKey(c.CompositeKey)) if err != nil { panic(err) } @@ -454,7 +454,7 @@ func (txi *TxIndex) match( // XXX: startKey does not apply here. // For example, if startKey = "account.owner/an/" and search query = "account.owner CONTAINS an" // we can't iterate with prefix "account.owner/an/" because we might miss keys like "account.owner/Ulan/" - it, err := dbm.IteratePrefix(txi.store, startKey(c.CompositeKey)) + it, err := txi.store.PrefixIterator(startKey(c.CompositeKey)) if err != nil { panic(err) } @@ -534,7 +534,7 @@ func (txi *TxIndex) matchRange( lowerBound := r.lowerBoundValue() upperBound := r.upperBoundValue() - it, err := dbm.IteratePrefix(txi.store, startKey) + it, err := txi.store.PrefixIterator(startKey) if err != nil { panic(err) } diff --git a/state/txindex/kv/kv_bench_test.go b/state/txindex/kv/kv_bench_test.go index 9f49cf4b9..0471089d8 100644 --- a/state/txindex/kv/kv_bench_test.go +++ b/state/txindex/kv/kv_bench_test.go @@ -7,7 +7,7 @@ import ( "io/ioutil" "testing" - dbm "github.com/tendermint/tm-db" + "github.com/line/tm-db/v2/goleveldb" abci "github.com/line/ostracon/abci/types" "github.com/line/ostracon/libs/pubsub/query" @@ -20,7 +20,7 @@ func BenchmarkTxSearch(b *testing.B) { b.Errorf("failed to create temporary directory: %s", err) } - db, err := dbm.NewGoLevelDB("benchmark_tx_search_test", dbDir) + db, err := goleveldb.NewDB("benchmark_tx_search_test", dbDir) if err != nil { b.Errorf("failed to create database: %s", err) } diff --git a/state/txindex/kv/kv_test.go b/state/txindex/kv/kv_test.go index 3dd8cd2f7..eff276d41 100644 --- a/state/txindex/kv/kv_test.go +++ b/state/txindex/kv/kv_test.go @@ -8,11 +8,11 @@ import ( "testing" "github.com/gogo/protobuf/proto" + "github.com/line/tm-db/v2/memdb" + "github.com/line/tm-db/v2/metadb" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - db "github.com/tendermint/tm-db" - abci "github.com/line/ostracon/abci/types" "github.com/line/ostracon/libs/pubsub/query" tmrand "github.com/line/ostracon/libs/rand" @@ -21,7 +21,7 @@ import ( ) func TestTxIndex(t *testing.T) { - indexer := NewTxIndex(db.NewMemDB()) + indexer := NewTxIndex(memdb.NewDB()) tx := types.Tx("HELLO WORLD") txResult := &abci.TxResult{ @@ -67,7 +67,7 @@ func TestTxIndex(t *testing.T) { } func TestTxSearch(t *testing.T) { - indexer := NewTxIndex(db.NewMemDB()) + indexer := NewTxIndex(memdb.NewDB()) txResult := txResultWithEvents([]abci.Event{ {Type: "account", Attributes: []abci.EventAttribute{{Key: []byte("number"), Value: []byte("1"), Index: true}}}, @@ -141,7 +141,7 @@ func TestTxSearch(t *testing.T) { } func TestTxSearchWithCancelation(t *testing.T) { - indexer := NewTxIndex(db.NewMemDB()) + indexer := NewTxIndex(memdb.NewDB()) txResult := txResultWithEvents([]abci.Event{ {Type: "account", Attributes: []abci.EventAttribute{{Key: []byte("number"), Value: []byte("1"), Index: true}}}, @@ -159,7 +159,7 @@ func TestTxSearchWithCancelation(t *testing.T) { } func TestTxSearchDeprecatedIndexing(t *testing.T) { - indexer := NewTxIndex(db.NewMemDB()) + indexer := NewTxIndex(memdb.NewDB()) // index tx using events indexing (composite key) txResult1 := txResultWithEvents([]abci.Event{ @@ -238,7 +238,7 @@ func TestTxSearchDeprecatedIndexing(t *testing.T) { } func TestTxSearchOneTxWithMultipleSameTagsButDifferentValues(t *testing.T) { - indexer := NewTxIndex(db.NewMemDB()) + indexer := NewTxIndex(memdb.NewDB()) txResult := txResultWithEvents([]abci.Event{ {Type: "account", Attributes: []abci.EventAttribute{{Key: []byte("number"), Value: []byte("1"), Index: true}}}, @@ -260,7 +260,7 @@ func TestTxSearchOneTxWithMultipleSameTagsButDifferentValues(t *testing.T) { } func TestTxSearchMultipleTxs(t *testing.T) { - indexer := NewTxIndex(db.NewMemDB()) + indexer := NewTxIndex(memdb.NewDB()) // indexed first, but bigger height (to test the order of transactions) txResult := txResultWithEvents([]abci.Event{ @@ -333,7 +333,7 @@ func benchmarkTxIndex(txsCount int64, b *testing.B) { require.NoError(b, err) defer os.RemoveAll(dir) - store, err := db.NewDB("tx_index", "goleveldb", dir) + store, err := metadb.NewDB("tx_index", "goleveldb", dir) require.NoError(b, err) indexer := NewTxIndex(store) diff --git a/statesync/stateprovider.go b/statesync/stateprovider.go index bebdd831b..29c398a4b 100644 --- a/statesync/stateprovider.go +++ b/statesync/stateprovider.go @@ -7,9 +7,6 @@ import ( "time" "github.com/line/ostracon/crypto/vrf" - - dbm "github.com/tendermint/tm-db" - "github.com/line/ostracon/libs/log" tmsync "github.com/line/ostracon/libs/sync" "github.com/line/ostracon/light" @@ -21,6 +18,7 @@ import ( rpchttp "github.com/line/ostracon/rpc/client/http" sm "github.com/line/ostracon/state" "github.com/line/ostracon/types" + "github.com/line/tm-db/v2/memdb" ) //go:generate mockery --case underscore --name StateProvider @@ -83,7 +81,7 @@ func NewLightClientStateProvider( } lc, err := light.NewClient(ctx, chainID, trustOptions, providers[0], providers[1:], - lightdb.New(dbm.NewMemDB(), ""), voterParams, light.Logger(logger), light.MaxRetryAttempts(5)) + lightdb.New(memdb.NewDB(), ""), voterParams, light.Logger(logger), light.MaxRetryAttempts(5)) if err != nil { return nil, err } diff --git a/statesync/syncer_test.go b/statesync/syncer_test.go index 7f4af632b..d0ccfa6da 100644 --- a/statesync/syncer_test.go +++ b/statesync/syncer_test.go @@ -51,7 +51,7 @@ func TestSyncer_SyncAny(t *testing.T) { App: 0, }, - Software: version.TMCoreSemVer, + Software: version.OCCoreSemVer, }, LastBlockHeight: 1, diff --git a/store/store.go b/store/store.go index e70ae569e..b28f38054 100644 --- a/store/store.go +++ b/store/store.go @@ -6,7 +6,7 @@ import ( "github.com/gogo/protobuf/proto" - dbm "github.com/tendermint/tm-db" + dbm "github.com/line/tm-db/v2" tmsync "github.com/line/ostracon/libs/sync" tmstore "github.com/line/ostracon/proto/ostracon/store" diff --git a/store/store_test.go b/store/store_test.go index a5bbe8c16..404ad85fb 100644 --- a/store/store_test.go +++ b/store/store_test.go @@ -10,9 +10,10 @@ import ( "time" "github.com/gogo/protobuf/proto" + dbm "github.com/line/tm-db/v2" + "github.com/line/tm-db/v2/memdb" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - dbm "github.com/tendermint/tm-db" cfg "github.com/line/ostracon/config" "github.com/line/ostracon/crypto" @@ -57,10 +58,10 @@ func makeBlock(height int64, state sm.State, lastCommit *types.Commit) *types.Bl func makeStateAndBlockStore(logger log.Logger) (sm.State, *BlockStore, cleanupFunc) { config := cfg.ResetTestRoot("blockchain_reactor_test") - // blockDB := dbm.NewDebugDB("blockDB", dbm.NewMemDB()) - // stateDB := dbm.NewDebugDB("stateDB", dbm.NewMemDB()) - blockDB := dbm.NewMemDB() - stateDB := dbm.NewMemDB() + // blockDB := dbm.NewDebugDB("blockDB", memdb.NewDB()) + // stateDB := dbm.NewDebugDB("stateDB", memdb.NewDB()) + blockDB := memdb.NewDB() + stateDB := memdb.NewDB() stateStore := sm.NewStore(stateDB) state, err := stateStore.LoadFromDBOrGenesisFile(config.GenesisFile()) if err != nil { @@ -85,7 +86,7 @@ func TestLoadBlockStoreState(t *testing.T) { } for _, tc := range testCases { - db := dbm.NewMemDB() + db := memdb.NewDB() SaveBlockStoreState(tc.bss, db) retrBSJ := LoadBlockStoreState(db) assert.Equal(t, tc.want, retrBSJ, "expected the retrieved DBs to match: %s", tc.testName) @@ -93,7 +94,7 @@ func TestLoadBlockStoreState(t *testing.T) { } func TestNewBlockStore(t *testing.T) { - db := dbm.NewMemDB() + db := memdb.NewDB() bss := tmstore.BlockStoreState{Base: 100, Height: 10000} bz, _ := proto.Marshal(&bss) err := db.Set(blockStoreKey, bz) @@ -130,7 +131,7 @@ func TestNewBlockStore(t *testing.T) { } func freshBlockStore() (*BlockStore, dbm.DB) { - db := dbm.NewMemDB() + db := memdb.NewDB() return NewBlockStore(db), db } @@ -145,7 +146,7 @@ var ( func TestMain(m *testing.M) { var cleanup cleanupFunc - state, _, cleanup = makeStateAndBlockStore(log.NewTMLogger(new(bytes.Buffer))) + state, _, cleanup = makeStateAndBlockStore(log.NewOCLogger(new(bytes.Buffer))) block = makeBlock(1, state, new(types.Commit)) partSet = block.MakePartSet(2) part1 = partSet.GetPart(0) @@ -159,7 +160,7 @@ func TestMain(m *testing.M) { // TODO: This test should be simplified ... func TestBlockStoreSaveLoadBlock(t *testing.T) { - state, bs, cleanup := makeStateAndBlockStore(log.NewTMLogger(new(bytes.Buffer))) + state, bs, cleanup := makeStateAndBlockStore(log.NewOCLogger(new(bytes.Buffer))) defer cleanup() require.Equal(t, bs.Base(), int64(0), "initially the base should be zero") require.Equal(t, bs.Height(), int64(0), "initially the height should be zero") @@ -370,10 +371,10 @@ func TestBlockStoreSaveLoadBlock(t *testing.T) { func TestLoadBaseMeta(t *testing.T) { config := cfg.ResetTestRoot("blockchain_reactor_test") defer os.RemoveAll(config.RootDir) - stateStore := sm.NewStore(dbm.NewMemDB()) + stateStore := sm.NewStore(memdb.NewDB()) state, err := stateStore.LoadFromDBOrGenesisFile(config.GenesisFile()) require.NoError(t, err) - bs := NewBlockStore(dbm.NewMemDB()) + bs := NewBlockStore(memdb.NewDB()) for h := int64(1); h <= 10; h++ { block := makeBlock(h, state, new(types.Commit)) @@ -405,7 +406,7 @@ func TestLoadBlockPart(t *testing.T) { require.Nil(t, res, "a non-existent block part should return nil") // 2. Next save a corrupted block then try to load it - err := db.Set(calcBlockPartKey(height, index), []byte("Tendermint")) + err := db.Set(calcBlockPartKey(height, index), []byte("Ostracon")) require.NoError(t, err) res, _, panicErr = doFn(loadPart) require.NotNil(t, panicErr, "expecting a non-nil panic") @@ -426,10 +427,10 @@ func TestLoadBlockPart(t *testing.T) { func TestPruneBlocks(t *testing.T) { config := cfg.ResetTestRoot("blockchain_reactor_test") defer os.RemoveAll(config.RootDir) - stateStore := sm.NewStore(dbm.NewMemDB()) + stateStore := sm.NewStore(memdb.NewDB()) state, err := stateStore.LoadFromDBOrGenesisFile(config.GenesisFile()) require.NoError(t, err) - db := dbm.NewMemDB() + db := memdb.NewDB() bs := NewBlockStore(db) assert.EqualValues(t, 0, bs.Base()) assert.EqualValues(t, 0, bs.Height()) @@ -525,7 +526,7 @@ func TestLoadBlockMeta(t *testing.T) { require.Nil(t, res, "a non-existent blockMeta should return nil") // 2. Next save a corrupted blockMeta then try to load it - err := db.Set(calcBlockMetaKey(height), []byte("Tendermint-Meta")) + err := db.Set(calcBlockMetaKey(height), []byte("Ostracon-Meta")) require.NoError(t, err) res, _, panicErr = doFn(loadMeta) require.NotNil(t, panicErr, "expecting a non-nil panic") @@ -550,7 +551,7 @@ func TestLoadBlockMeta(t *testing.T) { } func TestBlockFetchAtHeight(t *testing.T) { - state, bs, cleanup := makeStateAndBlockStore(log.NewTMLogger(new(bytes.Buffer))) + state, bs, cleanup := makeStateAndBlockStore(log.NewOCLogger(new(bytes.Buffer))) defer cleanup() require.Equal(t, bs.Height(), int64(0), "initially the height should be zero") block := makeBlock(bs.Height()+1, state, new(types.Commit)) diff --git a/test/app/test.sh b/test/app/test.sh index c4a06b539..5b569e8f8 100755 --- a/test/app/test.sh +++ b/test/app/test.sh @@ -9,10 +9,10 @@ set -ex # TODO: install everything export PATH="$GOBIN:$PATH" -export TMHOME=$HOME/.ostracon_app +export OCHOME=$HOME/.ostracon_app function kvstore_over_socket(){ - rm -rf $TMHOME + rm -rf $OCHOME ostracon init echo "Starting kvstore_over_socket" abci-cli kvstore > /dev/null & @@ -29,7 +29,7 @@ function kvstore_over_socket(){ # start ostracon first function kvstore_over_socket_reorder(){ - rm -rf $TMHOME + rm -rf $OCHOME ostracon init echo "Starting kvstore_over_socket_reorder (ie. start ostracon first)" ostracon node > ostracon.log & @@ -47,7 +47,7 @@ function kvstore_over_socket_reorder(){ function counter_over_socket() { - rm -rf $TMHOME + rm -rf $OCHOME ostracon init echo "Starting counter_over_socket" abci-cli counter --serial > /dev/null & @@ -63,7 +63,7 @@ function counter_over_socket() { } function counter_over_grpc() { - rm -rf $TMHOME + rm -rf $OCHOME ostracon init echo "Starting counter_over_grpc" abci-cli counter --serial --abci grpc > /dev/null & @@ -79,7 +79,7 @@ function counter_over_grpc() { } function counter_over_grpc_grpc() { - rm -rf $TMHOME + rm -rf $OCHOME ostracon init echo "Starting counter_over_grpc_grpc (ie. with grpc broadcast_tx)" abci-cli counter --serial --abci grpc > /dev/null & diff --git a/test/e2e/README.md b/test/e2e/README.md index 33b3a2656..600c59148 100644 --- a/test/e2e/README.md +++ b/test/e2e/README.md @@ -1,6 +1,6 @@ # End-to-End Tests -Spins up and tests Tendermint networks in Docker Compose based on a testnet manifest. To run the CI testnet: +Spins up and tests Ostracon networks in Docker Compose based on a testnet manifest. To run the CI testnet: ```sh make diff --git a/test/e2e/app/app.go b/test/e2e/app/app.go index fda128502..43dea19d1 100644 --- a/test/e2e/app/app.go +++ b/test/e2e/app/app.go @@ -41,7 +41,7 @@ func NewApplication(cfg *Config) (*Application, error) { return nil, err } return &Application{ - logger: log.NewTMLogger(log.NewSyncWriter(os.Stdout)), + logger: log.NewOCLogger(log.NewSyncWriter(os.Stdout)), state: state, snapshots: snapshots, cfg: cfg, diff --git a/test/e2e/app/main.go b/test/e2e/app/main.go index 82c5e0bbf..5dbdf268d 100644 --- a/test/e2e/app/main.go +++ b/test/e2e/app/main.go @@ -24,7 +24,7 @@ import ( maverick "github.com/line/ostracon/test/maverick/node" ) -var logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout)) +var logger = log.NewOCLogger(log.NewSyncWriter(os.Stdout)) // main is the binary entrypoint. func main() { @@ -83,7 +83,7 @@ func run(configFile string) error { } } -// startApp starts the application server, listening for connections from Tendermint. +// startApp starts the application server, listening for connections from Ostracon. func startApp(cfg *Config) error { app, err := NewApplication(cfg) if err != nil { @@ -101,8 +101,8 @@ func startApp(cfg *Config) error { return nil } -// startNode starts a Tendermint node running the application directly. It assumes the Tendermint -// configuration is in $TMHOME/config/ostracon.toml. +// startNode starts an Ostracon node running the application directly. It assumes the Ostracon +// configuration is in $OCHOME/config/ostracon.toml. // // FIXME There is no way to simply load the configuration from a file, so we need to pull in Viper. func startNode(cfg *Config) error { @@ -139,8 +139,8 @@ func startNode(cfg *Config) error { return n.Start() } -// startMaverick starts a Maverick node that runs the application directly. It assumes the Tendermint -// configuration is in $TMHOME/config/ostracon.toml. +// startMaverick starts a Maverick node that runs the application directly. It assumes the Ostracon +// configuration is in $OCHOME/config/ostracon.toml. func startMaverick(cfg *Config) error { app, err := NewApplication(cfg) if err != nil { @@ -205,9 +205,9 @@ func startSigner(cfg *Config) error { func setupNode() (*config.Config, log.Logger, *p2p.NodeKey, error) { var tmcfg *config.Config - home := os.Getenv("TMHOME") + home := os.Getenv("OCHOME") if home == "" { - return nil, nil, nil, errors.New("TMHOME not set") + return nil, nil, nil, errors.New("OCHOME not set") } viper.AddConfigPath(filepath.Join(home, "config")) @@ -230,7 +230,7 @@ func setupNode() (*config.Config, log.Logger, *p2p.NodeKey, error) { } if tmcfg.LogFormat == config.LogFormatJSON { - logger = log.NewTMJSONLogger(log.NewSyncWriter(os.Stdout)) + logger = log.NewOCJSONLogger(log.NewSyncWriter(os.Stdout)) } nodeLogger, err := tmflags.ParseLogLevel(tmcfg.LogLevel, logger, config.DefaultLogLevel) diff --git a/test/e2e/docker/Dockerfile b/test/e2e/docker/Dockerfile index 24b8b30fc..c4d05d18c 100644 --- a/test/e2e/docker/Dockerfile +++ b/test/e2e/docker/Dockerfile @@ -1,10 +1,18 @@ # We need to build in a Linux environment to support C libraries, e.g. RocksDB. # We use Debian instead of Alpine, so that we can use binary database packages -# instead of spending time compiling them. +# instead of spending time compiling them. +# -> There is currently no librocksdb-dev v6.17.x that is necessary by line/gorocksdb. +# So we download rocksdb and build it. + FROM golang:1.15 RUN apt-get -qq update -y && apt-get -qq upgrade -y >/dev/null -RUN apt-get -qq install -y libleveldb-dev librocksdb-dev libtool >/dev/null +RUN apt-get -qq install -y libleveldb-dev make libc-dev libtool >/dev/null +WORKDIR / +RUN wget -O rocksdb-v6.20.3.tar.gz https://github.com/facebook/rocksdb/archive/v6.20.3.tar.gz +RUN tar -zxvf rocksdb-v6.20.3.tar.gz +RUN cd rocksdb-6.20.3 && make -j2 shared_lib && make install-shared +RUN cp /usr/local/lib/librocksdb.so* /usr/lib # Set up build directory /src/ostracon ENV OSTRACON_BUILD_OPTIONS badgerdb,boltdb,cleveldb,rocksdb @@ -26,7 +34,7 @@ RUN cd test/e2e && make app && cp build/app /usr/bin/app # e.g. leveldb and rocksdb which are already installed in the build image. WORKDIR /ostracon VOLUME /ostracon -ENV TMHOME=/ostracon +ENV OCHOME=/ostracon EXPOSE 26656 26657 26660 6060 ENTRYPOINT ["/usr/bin/entrypoint"] diff --git a/test/e2e/generator/main.go b/test/e2e/generator/main.go index 96c573ac9..a538d0992 100644 --- a/test/e2e/generator/main.go +++ b/test/e2e/generator/main.go @@ -17,7 +17,7 @@ const ( randomSeed int64 = 4827085738 ) -var logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout)) +var logger = log.NewOCLogger(log.NewSyncWriter(os.Stdout)) func main() { NewCLI().Run() diff --git a/test/e2e/pkg/manifest.go b/test/e2e/pkg/manifest.go index 3fbf14558..3d919a449 100644 --- a/test/e2e/pkg/manifest.go +++ b/test/e2e/pkg/manifest.go @@ -73,8 +73,8 @@ type ManifestNode struct { // ABCIProtocol specifies the protocol used to communicate with the ABCI // application: "unix", "tcp", "grpc", or "builtin". Defaults to unix. - // builtin will build a complete Tendermint node into the application and - // launch it instead of launching a separate Tendermint process. + // builtin will build a complete Ostracon node into the application and + // launch it instead of launching a separate Ostracon process. ABCIProtocol string `toml:"abci_protocol"` // PrivvalProtocol specifies the protocol used to sign consensus messages: diff --git a/test/e2e/pkg/testnet.go b/test/e2e/pkg/testnet.go index ee7078bec..34fbd5c93 100644 --- a/test/e2e/pkg/testnet.go +++ b/test/e2e/pkg/testnet.go @@ -61,7 +61,7 @@ type Testnet struct { KeyType string } -// Node represents a Tendermint node in a testnet. +// Node represents an Ostracon node in a testnet. type Node struct { Name string Testnet *Testnet diff --git a/test/e2e/runner/cleanup.go b/test/e2e/runner/cleanup.go index 5071d8040..82060aa3f 100644 --- a/test/e2e/runner/cleanup.go +++ b/test/e2e/runner/cleanup.go @@ -61,7 +61,7 @@ func cleanupDir(dir string) error { logger.Info(fmt.Sprintf("Removing testnet directory %q", dir)) - // On Linux, some local files in the volume will be owned by root since Tendermint + // On Linux, some local files in the volume will be owned by root since Ostracon // runs as root inside the container, so we need to clean them up from within a // container running as root too. absDir, err := filepath.Abs(dir) diff --git a/test/e2e/runner/main.go b/test/e2e/runner/main.go index 5cac654c2..d701a5712 100644 --- a/test/e2e/runner/main.go +++ b/test/e2e/runner/main.go @@ -12,7 +12,7 @@ import ( ) var ( - logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout)) + logger = log.NewOCLogger(log.NewSyncWriter(os.Stdout)) ) func main() { diff --git a/test/e2e/runner/setup.go b/test/e2e/runner/setup.go index 05ee77920..2f1e01855 100644 --- a/test/e2e/runner/setup.go +++ b/test/e2e/runner/setup.go @@ -107,7 +107,7 @@ func Setup(testnet *e2e.Testnet) error { filepath.Join(nodeDir, PrivvalStateFile), )).Save() - // Set up a dummy validator. Tendermint requires a file PV even when not used, so we + // Set up a dummy validator. Ostracon requires a file PV even when not used, so we // give it a dummy such that it will fail if it actually tries to use it. (privval.NewFilePV(ed25519.GenPrivKey(), filepath.Join(nodeDir, PrivvalDummyKeyFile), @@ -201,7 +201,7 @@ func MakeGenesis(testnet *e2e.Testnet) (types.GenesisDoc, error) { Power: power, }) } - // The validator set will be sorted internally by Tendermint ranked by power, + // The validator set will be sorted internally by Ostracon ranked by power, // but we sort it here as well so that all genesis files are identical. sort.Slice(genesis.Validators, func(i, j int) bool { return strings.Compare(genesis.Validators[i].Name, genesis.Validators[j].Name) == -1 @@ -216,7 +216,7 @@ func MakeGenesis(testnet *e2e.Testnet) (types.GenesisDoc, error) { return genesis, genesis.ValidateAndComplete() } -// MakeConfig generates a Tendermint config for a node. +// MakeConfig generates an Ostracon config for a node. func MakeConfig(node *e2e.Node) (*config.Config, error) { cfg := config.DefaultConfig() cfg.Moniker = node.Name @@ -243,7 +243,7 @@ func MakeConfig(node *e2e.Node) (*config.Config, error) { return nil, fmt.Errorf("unexpected ABCI protocol setting %q", node.ABCIProtocol) } - // Tendermint errors if it does not have a privval key set up, regardless of whether + // Ostracon errors if it does not have a privval key set up, regardless of whether // it's actually needed (e.g. for remote KMS or non-validators). We set up a dummy // key here by default, and use the real key for actual validators that should use // the file privval. diff --git a/test/fuzz/README.md b/test/fuzz/README.md index 707217afd..64822a237 100644 --- a/test/fuzz/README.md +++ b/test/fuzz/README.md @@ -1,6 +1,6 @@ # fuzz -Fuzzing for various packages in Tendermint using [go-fuzz](https://github.com/dvyukov/go-fuzz) library. +Fuzzing for various packages in Ostracon using [go-fuzz](https://github.com/dvyukov/go-fuzz) library. Inputs: diff --git a/test/fuzz/mempool/checktx.go b/test/fuzz/mempool/checktx.go index 320a393ee..f6f0e25e3 100644 --- a/test/fuzz/mempool/checktx.go +++ b/test/fuzz/mempool/checktx.go @@ -25,7 +25,7 @@ func init() { } func Fuzz(data []byte) int { - err := mempool.CheckTx(data, nil, mempl.TxInfo{}) + _, err := mempool.CheckTxSync(data, mempl.TxInfo{}) if err != nil { return 0 } diff --git a/test/fuzz/p2p/secret_connection/init-corpus/main.go b/test/fuzz/p2p/secret_connection/init-corpus/main.go index 635f2d99f..cb5c85d2c 100644 --- a/test/fuzz/p2p/secret_connection/init-corpus/main.go +++ b/test/fuzz/p2p/secret_connection/init-corpus/main.go @@ -33,7 +33,7 @@ func initCorpus(baseDir string) { `{"a": 12, "tsp": 999, k: "blue"}`, `9999.999`, `""`, - `Tendermint fuzzing`, + `Ostracon fuzzing`, } for i, datum := range data { diff --git a/test/fuzz/rpc/jsonrpc/server/handler.go b/test/fuzz/rpc/jsonrpc/server/handler.go index 993a81608..d5ef9d372 100644 --- a/test/fuzz/rpc/jsonrpc/server/handler.go +++ b/test/fuzz/rpc/jsonrpc/server/handler.go @@ -20,7 +20,7 @@ var mux *http.ServeMux func init() { mux := http.NewServeMux() buf := new(bytes.Buffer) - lgr := log.NewTMLogger(buf) + lgr := log.NewOCLogger(buf) rs.RegisterRPCFuncs(mux, rpcFuncMap, lgr) } diff --git a/test/maverick/README.md b/test/maverick/README.md index cbdf7b798..5e86d8e32 100644 --- a/test/maverick/README.md +++ b/test/maverick/README.md @@ -1,6 +1,6 @@ # Maverick -A byzantine node used to test Tendermint consensus against a plethora of different faulty misbehaviors. Designed to easily create new faulty misbehaviors to examine how a Tendermint network reacts to the misbehavior. Can also be used for fuzzy testing with different network arrangements. +A byzantine node used to test Ostracon consensus against a plethora of different faulty misbehaviors. Designed to easily create new faulty misbehaviors to examine how an Ostracon network reacts to the misbehavior. Can also be used for fuzzy testing with different network arrangements. ## Misbehaviors @@ -34,7 +34,7 @@ var MisbehaviorList = map[string]Misbehavior{ ## Setup -The maverick node takes most of the functionality from the existing Tendermint CLI. To install this, in the directory of this readme, run: +The maverick node takes most of the functionality from the existing Ostracon CLI. To install this, in the directory of this readme, run: ```bash go build diff --git a/test/maverick/consensus/reactor.go b/test/maverick/consensus/reactor.go index f1d3648de..0ce2cfe72 100644 --- a/test/maverick/consensus/reactor.go +++ b/test/maverick/consensus/reactor.go @@ -1404,15 +1404,15 @@ func (ps *PeerState) StringIndented(indent string) string { //----------------------------------------------------------------------------- // func init() { -// tmjson.RegisterType(&NewRoundStepMessage{}, "tendermint/NewRoundStepMessage") -// tmjson.RegisterType(&NewValidBlockMessage{}, "tendermint/NewValidBlockMessage") -// tmjson.RegisterType(&ProposalMessage{}, "tendermint/Proposal") -// tmjson.RegisterType(&ProposalPOLMessage{}, "tendermint/ProposalPOL") -// tmjson.RegisterType(&BlockPartMessage{}, "tendermint/BlockPart") -// tmjson.RegisterType(&VoteMessage{}, "tendermint/Vote") -// tmjson.RegisterType(&HasVoteMessage{}, "tendermint/HasVote") -// tmjson.RegisterType(&VoteSetMaj23Message{}, "tendermint/VoteSetMaj23") -// tmjson.RegisterType(&VoteSetBitsMessage{}, "tendermint/VoteSetBits") +// tmjson.RegisterType(&NewRoundStepMessage{}, "ostracon/NewRoundStepMessage") +// tmjson.RegisterType(&NewValidBlockMessage{}, "ostracon/NewValidBlockMessage") +// tmjson.RegisterType(&ProposalMessage{}, "ostracon/Proposal") +// tmjson.RegisterType(&ProposalPOLMessage{}, "ostracon/ProposalPOL") +// tmjson.RegisterType(&BlockPartMessage{}, "ostracon/BlockPart") +// tmjson.RegisterType(&VoteMessage{}, "ostracon/Vote") +// tmjson.RegisterType(&HasVoteMessage{}, "ostracon/HasVote") +// tmjson.RegisterType(&VoteSetMaj23Message{}, "ostracon/VoteSetMaj23") +// tmjson.RegisterType(&VoteSetBitsMessage{}, "ostracon/VoteSetBits") // } func decodeMsg(bz []byte) (msg tmcon.Message, err error) { diff --git a/test/maverick/consensus/replay.go b/test/maverick/consensus/replay.go index 94cca13c9..25842984e 100644 --- a/test/maverick/consensus/replay.go +++ b/test/maverick/consensus/replay.go @@ -271,7 +271,7 @@ func (h *Handshaker) Handshake(proxyApp proxy.AppConns) error { return fmt.Errorf("error on replay: %v", err) } - h.logger.Info("Completed ABCI Handshake - Tendermint and App are synced", + h.logger.Info("Completed ABCI Handshake - Ostracon and App are synced", "appHeight", blockHeight, "appHash", appHash) // TODO: (on restart) replay mempool @@ -307,8 +307,8 @@ func (h *Handshaker) ReplayBlocks( validators[i] = types.NewValidator(val.PubKey, val.Power) } validatorSet := types.NewValidatorSet(validators) - nextVals := types.TM2PB.ValidatorUpdates(validatorSet) - csParams := types.TM2PB.ConsensusParams(h.genDoc.ConsensusParams) + nextVals := types.OC2PB.ValidatorUpdates(validatorSet) + csParams := types.OC2PB.ConsensusParams(h.genDoc.ConsensusParams) req := abci.RequestInitChain{ Time: h.genDoc.GenesisTime, ChainId: h.genDoc.ChainID, @@ -333,7 +333,7 @@ func (h *Handshaker) ReplayBlocks( } // If the app returned validators or consensus params, update the state. if len(res.Validators) > 0 { - vals, err := types.PB2TM.ValidatorUpdates(res.Validators) + vals, err := types.PB2OC.ValidatorUpdates(res.Validators) if err != nil { return nil, err } @@ -377,11 +377,11 @@ func (h *Handshaker) ReplayBlocks( return appHash, sm.ErrAppBlockHeightTooHigh{CoreHeight: storeBlockHeight, AppHeight: appBlockHeight} case storeBlockHeight < stateBlockHeight: - // the state should never be ahead of the store (this is under tendermint's control) + // the state should never be ahead of the store (this is under ostracon's control) panic(fmt.Sprintf("StateBlockHeight (%d) > StoreBlockHeight (%d)", stateBlockHeight, storeBlockHeight)) case storeBlockHeight > stateBlockHeight+1: - // store should be at most one ahead of the state (this is under tendermint's control) + // store should be at most one ahead of the state (this is under ostracon's control) panic(fmt.Sprintf("StoreBlockHeight (%d) > StateBlockHeight + 1 (%d)", storeBlockHeight, stateBlockHeight+1)) } @@ -389,7 +389,7 @@ func (h *Handshaker) ReplayBlocks( // Now either store is equal to state, or one ahead. // For each, consider all cases of where the app could be, given app <= store if storeBlockHeight == stateBlockHeight { - // Tendermint ran Commit and saved the state. + // Ostracon ran Commit and saved the state. // Either the app is asking for replay, or we're all synced up. if appBlockHeight < storeBlockHeight { // the app is behind, so replay blocks, but no need to go through WAL (state is already synced to store) @@ -510,7 +510,7 @@ func (h *Handshaker) replayBlock(state sm.State, height int64, proxyApp proxy.Ap blockExec.SetEventBus(h.eventBus) var err error - state, _, err = blockExec.ApplyBlock(state, meta.BlockID, block) + state, _, err = blockExec.ApplyBlock(state, meta.BlockID, block, nil) if err != nil { return sm.State{}, err } @@ -537,7 +537,7 @@ func assertAppHashEqualsOneFromState(appHash []byte, state sm.State) { State: %v -Did you reset Tendermint without resetting your application's data?`, +Did you reset Ostracon without resetting your application's data?`, appHash, state.AppHash, state)) } } diff --git a/test/maverick/consensus/replay_file.go b/test/maverick/consensus/replay_file.go index a9b4d0d70..b7474de35 100644 --- a/test/maverick/consensus/replay_file.go +++ b/test/maverick/consensus/replay_file.go @@ -10,7 +10,7 @@ import ( "strconv" "strings" - dbm "github.com/tendermint/tm-db" + "github.com/line/tm-db/v2/metadb" cfg "github.com/line/ostracon/config" tmcon "github.com/line/ostracon/consensus" @@ -285,16 +285,16 @@ func (pb *playback) replayConsoleLoop() int { // convenience for replay mode func newConsensusStateForReplay(config cfg.BaseConfig, csConfig *cfg.ConsensusConfig) *State { - dbType := dbm.BackendType(config.DBBackend) + dbType := metadb.BackendType(config.DBBackend) // Get BlockStore - blockStoreDB, err := dbm.NewDB("blockstore", dbType, config.DBDir()) + blockStoreDB, err := metadb.NewDB("blockstore", dbType, config.DBDir()) if err != nil { tmos.Exit(err.Error()) } blockStore := store.NewBlockStore(blockStoreDB) // Get State - stateDB, err := dbm.NewDB("state", dbType, config.DBDir()) + stateDB, err := metadb.NewDB("state", dbType, config.DBDir()) if err != nil { tmos.Exit(err.Error()) } diff --git a/test/maverick/consensus/replay_stubs.go b/test/maverick/consensus/replay_stubs.go index 39c84b578..b21e3cfad 100644 --- a/test/maverick/consensus/replay_stubs.go +++ b/test/maverick/consensus/replay_stubs.go @@ -18,17 +18,17 @@ var _ mempl.Mempool = emptyMempool{} func (emptyMempool) Lock() {} func (emptyMempool) Unlock() {} func (emptyMempool) Size() int { return 0 } -func (emptyMempool) CheckTx(_ types.Tx, _ func(*abci.Response), _ mempl.TxInfo) error { - return nil +func (emptyMempool) CheckTxSync(_ types.Tx, _ mempl.TxInfo) (*abci.Response, error) { + return nil, nil +} +func (emptyMempool) CheckTxAsync(_ types.Tx, _ mempl.TxInfo, _ func(error), _ func(*abci.Response)) { } func (emptyMempool) ReapMaxBytesMaxGas(_, _ int64) types.Txs { return types.Txs{} } func (emptyMempool) ReapMaxTxs(n int) types.Txs { return types.Txs{} } func (emptyMempool) Update( - _ int64, - _ types.Txs, + _ *types.Block, _ []*abci.ResponseDeliverTx, _ mempl.PreCheckFunc, - _ mempl.PostCheckFunc, ) error { return nil } diff --git a/test/maverick/consensus/state.go b/test/maverick/consensus/state.go index b0dc28a91..b65c43787 100644 --- a/test/maverick/consensus/state.go +++ b/test/maverick/consensus/state.go @@ -873,7 +873,7 @@ func (cs *State) updateToState(state sm.State) { } cs.LastCommit = cs.Votes.Precommits(cs.CommitRound) case cs.LastCommit == nil: - // NOTE: when Tendermint starts, it has no votes. reconstructLastCommit + // NOTE: when Ostracon starts, it has no votes. reconstructLastCommit // must be called to reconstruct LastCommit from SeenCommit. panic(fmt.Sprintf("LastCommit cannot be empty after initial block (H:%d)", state.LastBlockHeight+1, @@ -1514,7 +1514,7 @@ func (cs *State) finalizeCommit(height int64) { stateCopy, retainHeight, err = cs.blockExec.ApplyBlock( stateCopy, types.BlockID{Hash: block.Hash(), PartSetHeader: blockParts.Header()}, - block) + block, nil) if err != nil { cs.Logger.Error("Error on ApplyBlock", "err", err) return @@ -1647,7 +1647,7 @@ func (cs *State) recordMetrics(height int64, block *types.Block) { if height > 1 { lastBlockMeta := cs.blockStore.LoadBlockMeta(height - 1) if lastBlockMeta != nil { - cs.metrics.BlockIntervalSeconds.Observe( + cs.metrics.BlockIntervalSeconds.Set( block.Time.Sub(lastBlockMeta.Header.Time).Seconds(), ) } diff --git a/test/maverick/consensus/wal.go b/test/maverick/consensus/wal.go index d95d5e417..3640651ca 100644 --- a/test/maverick/consensus/wal.go +++ b/test/maverick/consensus/wal.go @@ -32,9 +32,9 @@ const ( //-------------------------------------------------------- // types and functions for savings consensus messages // func init() { -// tmjson.RegisterType(msgInfo{}, "tendermint/wal/MsgInfo") -// tmjson.RegisterType(timeoutInfo{}, "tendermint/wal/TimeoutInfo") -// tmjson.RegisterType(tmcon.EndHeightMessage {}, "tendermint/wal/EndHeightMessage ") +// tmjson.RegisterType(msgInfo{}, "ostracon/wal/MsgInfo") +// tmjson.RegisterType(timeoutInfo{}, "ostracon/wal/TimeoutInfo") +// tmjson.RegisterType(tmcon.EndHeightMessage {}, "ostracon/wal/EndHeightMessage ") // } // Write ahead logger writes msgs to disk before they are processed. diff --git a/test/maverick/consensus/wal_generator.go b/test/maverick/consensus/wal_generator.go index ea050c5e2..e5cac8a57 100644 --- a/test/maverick/consensus/wal_generator.go +++ b/test/maverick/consensus/wal_generator.go @@ -9,7 +9,7 @@ import ( "testing" "time" - db "github.com/tendermint/tm-db" + "github.com/line/tm-db/v2/memdb" "github.com/line/ostracon/abci/example/kvstore" cfg "github.com/line/ostracon/config" @@ -50,7 +50,7 @@ func WALGenerateNBlocks(t *testing.T, wr io.Writer, numBlocks int) (err error) { if err != nil { return fmt.Errorf("failed to read genesis file: %w", err) } - blockStoreDB := db.NewMemDB() + blockStoreDB := memdb.NewDB() stateDB := blockStoreDB stateStore := sm.NewStore(stateDB) state, err := sm.MakeGenesisState(genDoc) diff --git a/test/maverick/main.go b/test/maverick/main.go index b749cb8ec..dca2f416d 100644 --- a/test/maverick/main.go +++ b/test/maverick/main.go @@ -25,7 +25,7 @@ import ( var ( config = cfg.DefaultConfig() - logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout)) + logger = log.NewOCLogger(log.NewSyncWriter(os.Stdout)) misbehaviorFlag = "" ) @@ -51,11 +51,11 @@ func ParseConfig() (*cfg.Config, error) { return conf, err } -// RootCmd is the root command for Tendermint core. +// RootCmd is the root command for Ostracon core. var RootCmd = &cobra.Command{ Use: "maverick", - Short: "Tendermint Maverick Node", - Long: "Tendermint Maverick Node for testing with faulty consensus misbehaviors in a testnet. Contains " + + Short: "Ostracon Maverick Node", + Long: "Ostracon Maverick Node for testing with faulty consensus misbehaviors in a testnet. Contains " + "all the functionality of a normal node but custom misbehaviors can be injected when running the node " + "through a flag. See maverick node --help for how the misbehavior flag is constructured", PersistentPreRunE: func(cmd *cobra.Command, args []string) (err error) { @@ -67,7 +67,7 @@ var RootCmd = &cobra.Command{ } if config.LogFormat == cfg.LogFormatJSON { - logger = log.NewTMJSONLogger(log.NewSyncWriter(os.Stdout)) + logger = log.NewOCJSONLogger(log.NewSyncWriter(os.Stdout)) } logger, err = tmflags.ParseLogLevel(config.LogLevel, logger, cfg.DefaultLogLevel) @@ -125,7 +125,7 @@ func main() { "e.g. --misbehaviors double-prevote,3\n"+ "You can also have multiple misbehaviors: e.g. double-prevote,3,no-vote,5") - cmd := cli.PrepareBaseCmd(rootCmd, "TM", os.ExpandEnv(filepath.Join("$HOME", cfg.DefaultOstraconDir))) + cmd := cli.PrepareBaseCmd(rootCmd, "OC", os.ExpandEnv(filepath.Join("$HOME", cfg.DefaultOstraconDir))) if err := cmd.Execute(); err != nil { panic(err) } @@ -163,7 +163,7 @@ func startNode(config *cfg.Config, logger log.Logger, misbehaviorFlag string) er var InitFilesCmd = &cobra.Command{ Use: "init", - Short: "Initialize Tendermint", + Short: "Initialize Ostracon", RunE: initFiles, } diff --git a/test/maverick/node/node.go b/test/maverick/node/node.go index c293c361f..066cbd6c5 100644 --- a/test/maverick/node/node.go +++ b/test/maverick/node/node.go @@ -12,11 +12,12 @@ import ( "strings" "time" + "github.com/line/tm-db/v2/metadb" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/rs/cors" - dbm "github.com/tendermint/tm-db" + dbm "github.com/line/tm-db/v2" abci "github.com/line/ostracon/abci/types" bcv0 "github.com/line/ostracon/blockchain/v0" @@ -95,8 +96,8 @@ type DBProvider func(*DBContext) (dbm.DB, error) // DefaultDBProvider returns a database using the DBBackend and DBDir // specified in the ctx.Config. func DefaultDBProvider(ctx *DBContext) (dbm.DB, error) { - dbType := dbm.BackendType(ctx.Config.DBBackend) - return dbm.NewDB(ctx.ID, dbType, ctx.Config.DBDir()) + dbType := metadb.BackendType(ctx.Config.DBBackend) + return metadb.NewDB(ctx.ID, dbType, ctx.Config.DBDir()) } // GenesisDocProvider returns a GenesisDoc. @@ -115,7 +116,7 @@ func DefaultGenesisDocProviderFunc(config *cfg.Config) GenesisDocProvider { // Provider takes a config and a logger and returns a ready to go Node. type Provider func(*cfg.Config, log.Logger) (*Node, error) -// DefaultNewNode returns a Tendermint node with default settings for the +// DefaultNewNode returns an Ostracon node with default settings for the // PrivValidator, ClientCreator, GenesisDoc, and DBProvider. // It implements NodeProvider. func DefaultNewNode(config *cfg.Config, logger log.Logger, misbehaviors map[int64]cs.Misbehavior) (*Node, error) { @@ -220,7 +221,7 @@ func StateProvider(stateProvider statesync.StateProvider) Option { //------------------------------------------------------------------------------ -// Node is the highest level interface to a full Tendermint node. +// Node is the highest level interface to a full Ostracon node. // It includes all configuration information and running services. type Node struct { service.BaseService @@ -338,7 +339,7 @@ func doHandshake( func logNodeStartupInfo(state sm.State, pubKey crypto.PubKey, logger, consensusLogger log.Logger) { // Log the version info. logger.Info("Version info", - "software", version.TMCoreSemVer, + "software", version.OCCoreSemVer, "block", version.BlockProtocol, "p2p", version.P2PProtocol, ) @@ -377,7 +378,6 @@ func createMempoolAndMempoolReactor(config *cfg.Config, proxyApp proxy.AppConns, state.LastBlockHeight, mempl.WithMetrics(memplMetrics), mempl.WithPreCheck(sm.TxPreCheck(state)), - mempl.WithPostCheck(sm.TxPostCheck(state)), ) mempoolLogger := logger.With("module", "mempool") mempoolReactor := mempl.NewReactor(config.Mempool, config.P2P.RecvAsync, config.P2P.MempoolRecvBufSize, mempool) @@ -697,7 +697,7 @@ func startStateSync(ssR *statesync.Reactor, bcR fastSyncReactor, conR *cs.Reacto return nil } -// NewNode returns a new, ready to go, Tendermint Node. +// NewNode returns a new, ready to go, Ostracon Node. func NewNode(config *cfg.Config, privValidator types.PrivValidator, nodeKey *p2p.NodeKey, @@ -1332,7 +1332,7 @@ func makeNodeInfo( ), DefaultNodeID: nodeKey.ID(), Network: genDoc.ChainID, - Version: version.TMCoreSemVer, + Version: version.OCCoreSemVer, Channels: []byte{ bcChannel, cs.StateChannel, cs.DataChannel, cs.VoteChannel, cs.VoteSetBitsChannel, diff --git a/tools/README.md b/tools/README.md index 44bd0691d..59a9cc061 100644 --- a/tools/README.md +++ b/tools/README.md @@ -1,5 +1,5 @@ # tools -Tools for working with Tendermint and associated technologies. Documentation for +Tools for working with Ostracon and associated technologies. Documentation for these tools can be found online in the [Tendermint tools documentation](https://docs.tendermint.com/master/tools/). diff --git a/tools/mintnet-kubernetes/README.rst b/tools/mintnet-kubernetes/README.rst index b402993a0..93d755e68 100644 --- a/tools/mintnet-kubernetes/README.rst +++ b/tools/mintnet-kubernetes/README.rst @@ -207,7 +207,7 @@ First pod details: kubectl describe pod tm-0 -Tendermint app logs from the first pod: +Ostracon app logs from the first pod: :: @@ -219,7 +219,7 @@ App logs from the first pod: kubectl logs tm-0 -c app -f -Status of the second pod's Tendermint app: +Status of the second pod's Ostracon app: :: @@ -287,4 +287,4 @@ Init containers (``tm-gen-validator``) are run before all other containers, creating public-private key pair for each pod. Every ``tm`` container then asks other pods for their public keys, which are served with nginx (``pub-key`` container). When ``tm`` container have all the -keys, it forms a genesis file and starts the Tendermint process. +keys, it forms a genesis file and starts the Ostracon process. diff --git a/tools/mintnet-kubernetes/app.template.yaml b/tools/mintnet-kubernetes/app.template.yaml index e463e20b3..777a0c5c3 100644 --- a/tools/mintnet-kubernetes/app.template.yaml +++ b/tools/mintnet-kubernetes/app.template.yaml @@ -111,7 +111,7 @@ spec: configMapKeyRef: name: tm-config key: validators - - name: TMHOME + - name: OCHOME value: /ostracon command: - bash diff --git a/tools/mintnet-kubernetes/examples/counter/app.yaml b/tools/mintnet-kubernetes/examples/counter/app.yaml index 56aaabe19..59070913f 100644 --- a/tools/mintnet-kubernetes/examples/counter/app.yaml +++ b/tools/mintnet-kubernetes/examples/counter/app.yaml @@ -103,7 +103,7 @@ spec: configMapKeyRef: name: tm-config key: validators - - name: TMHOME + - name: OCHOME value: /ostracon command: - bash diff --git a/tools/mintnet-kubernetes/examples/dummy/app.yaml b/tools/mintnet-kubernetes/examples/dummy/app.yaml index 0a1ef3afb..d029a0bc5 100644 --- a/tools/mintnet-kubernetes/examples/dummy/app.yaml +++ b/tools/mintnet-kubernetes/examples/dummy/app.yaml @@ -103,7 +103,7 @@ spec: configMapKeyRef: name: tm-config key: validators - - name: TMHOME + - name: OCHOME value: /ostracon command: - bash diff --git a/tools/tm-signer-harness/internal/test_harness.go b/tools/tm-signer-harness/internal/test_harness.go index b4e227b9b..521fecbdb 100644 --- a/tools/tm-signer-harness/internal/test_harness.go +++ b/tools/tm-signer-harness/internal/test_harness.go @@ -49,7 +49,7 @@ type TestHarnessError struct { var _ error = (*TestHarnessError)(nil) // TestHarness allows for testing of a remote signer to ensure compatibility -// with this version of Tendermint. +// with this version of Ostracon. type TestHarness struct { addr string signerClient *privval.SignerClient @@ -85,7 +85,7 @@ type timeoutError interface { Timeout() bool } -// NewTestHarness will load Tendermint data from the given files (including +// NewTestHarness will load Ostracon data from the given files (including // validator public/private keypairs and chain details) and create a new // harness. func NewTestHarness(logger log.Logger, cfg TestHarnessConfig) (*TestHarness, error) { @@ -189,7 +189,7 @@ func (th *TestHarness) Run() { // TestPublicKey just validates that we can (1) fetch the public key from the // remote signer, and (2) it matches the public key we've configured for our -// local Tendermint version. +// local Ostracon version. func (th *TestHarness) TestPublicKey() error { th.logger.Info("TEST: Public key of remote signer") fpvk, err := th.fpv.GetPubKey() diff --git a/tools/tm-signer-harness/internal/test_harness_test.go b/tools/tm-signer-harness/internal/test_harness_test.go index 61ad16567..dc8005fde 100644 --- a/tools/tm-signer-harness/internal/test_harness_test.go +++ b/tools/tm-signer-harness/internal/test_harness_test.go @@ -21,11 +21,11 @@ const ( keyFileContents = `{ "address": "D08FCA3BA74CF17CBFC15E64F9505302BB0E2748", "pub_key": { - "type": "tendermint/PubKeyEd25519", + "type": "ostracon/PubKeyEd25519", "value": "ZCsuTjaczEyon70nmKxwvwu+jqrbq5OH3yQjcK0SFxc=" }, "priv_key": { - "type": "tendermint/PrivKeyEd25519", + "type": "ostracon/PrivKeyEd25519", "value": "8O39AkQsoe1sBQwud/Kdul8lg8K9SFsql9aZvwXQSt1kKy5ONpzMTKifvSeYrHC/C76Oqturk4ffJCNwrRIXFw==" } }` @@ -61,7 +61,7 @@ const ( { "address": "D08FCA3BA74CF17CBFC15E64F9505302BB0E2748", "pub_key": { - "type": "tendermint/PubKeyEd25519", + "type": "ostracon/PubKeyEd25519", "value": "ZCsuTjaczEyon70nmKxwvwu+jqrbq5OH3yQjcK0SFxc=" }, "power": "10", diff --git a/tools/tm-signer-harness/main.go b/tools/tm-signer-harness/main.go index 450d4dc53..63557364e 100644 --- a/tools/tm-signer-harness/main.go +++ b/tools/tm-signer-harness/main.go @@ -18,19 +18,19 @@ import ( const ( defaultAcceptRetries = 100 defaultBindAddr = "tcp://127.0.0.1:0" - defaultTMHome = "~/.ostracon" + defaultOCHome = "~/.ostracon" defaultAcceptDeadline = 1 defaultConnDeadline = 3 defaultExtractKeyOutput = "./signing.key" ) -var logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout)) +var logger = log.NewOCLogger(log.NewSyncWriter(os.Stdout)) // Command line flags var ( flagAcceptRetries int flagBindAddr string - flagTMHome string + flagOCHome string flagKeyOutputPath string ) @@ -45,13 +45,13 @@ var ( func init() { rootCmd = flag.NewFlagSet("root", flag.ExitOnError) rootCmd.Usage = func() { - fmt.Println(`Remote signer test harness for Tendermint. + fmt.Println(`Remote signer test harness for Ostracon. Usage: tm-signer-harness [flags] Available Commands: - extract_key Extracts a signing key from a local Tendermint instance + extract_key Extracts a signing key from a local Ostracon instance help Help on the available commands run Runs the test harness version Display version information and exit @@ -66,9 +66,9 @@ Use "tm-signer-harness help " for more information about that command.` defaultAcceptRetries, "The number of attempts to listen for incoming connections") runCmd.StringVar(&flagBindAddr, "addr", defaultBindAddr, "Bind to this address for the testing") - runCmd.StringVar(&flagTMHome, "tmhome", defaultTMHome, "Path to the Tendermint home directory") + runCmd.StringVar(&flagOCHome, "ochome", defaultOCHome, "Path to the Ostracon home directory") runCmd.Usage = func() { - fmt.Println(`Runs the remote signer test harness for Tendermint. + fmt.Println(`Runs the remote signer test harness for Ostracon. Usage: tm-signer-harness run [flags] @@ -83,9 +83,9 @@ Flags:`) "output", defaultExtractKeyOutput, "Path to which signing key should be written") - extractKeyCmd.StringVar(&flagTMHome, "tmhome", defaultTMHome, "Path to the Tendermint home directory") + extractKeyCmd.StringVar(&flagOCHome, "ochome", defaultOCHome, "Path to the Ostracon home directory") extractKeyCmd.Usage = func() { - fmt.Println(`Extracts a signing key from a local Tendermint instance for use in the remote + fmt.Println(`Extracts a signing key from a local Ostracon instance for use in the remote signer under test. Usage: @@ -99,7 +99,7 @@ Flags:`) versionCmd = flag.NewFlagSet("version", flag.ExitOnError) versionCmd.Usage = func() { fmt.Println(` -Prints the Tendermint version for which this remote signer harness was built. +Prints the Ostracon version for which this remote signer harness was built. Usage: tm-signer-harness version`) @@ -107,13 +107,13 @@ Usage: } } -func runTestHarness(acceptRetries int, bindAddr, tmhome string) { - tmhome = internal.ExpandPath(tmhome) +func runTestHarness(acceptRetries int, bindAddr, ochome string) { + ochome = internal.ExpandPath(ochome) cfg := internal.TestHarnessConfig{ BindAddr: bindAddr, - KeyFile: filepath.Join(tmhome, "config", "priv_validator_key.json"), - StateFile: filepath.Join(tmhome, "data", "priv_validator_state.json"), - GenesisFile: filepath.Join(tmhome, "config", "genesis.json"), + KeyFile: filepath.Join(ochome, "config", "priv_validator_key.json"), + StateFile: filepath.Join(ochome, "data", "priv_validator_state.json"), + GenesisFile: filepath.Join(ochome, "config", "genesis.json"), AcceptDeadline: time.Duration(defaultAcceptDeadline) * time.Second, AcceptRetries: acceptRetries, ConnDeadline: time.Duration(defaultConnDeadline) * time.Second, @@ -131,9 +131,9 @@ func runTestHarness(acceptRetries int, bindAddr, tmhome string) { harness.Run() } -func extractKey(tmhome, outputPath string) { - keyFile := filepath.Join(internal.ExpandPath(tmhome), "config", "priv_validator_key.json") - stateFile := filepath.Join(internal.ExpandPath(tmhome), "data", "priv_validator_state.json") +func extractKey(ochome, outputPath string) { + keyFile := filepath.Join(internal.ExpandPath(ochome), "config", "priv_validator_key.json") + stateFile := filepath.Join(internal.ExpandPath(ochome), "data", "priv_validator_state.json") fpv := privval.LoadFilePV(keyFile, stateFile) pkb := []byte(fpv.Key.PrivKey.(ed25519.PrivKey)) if err := ioutil.WriteFile(internal.ExpandPath(outputPath), pkb[:32], 0600); err != nil { @@ -173,15 +173,15 @@ func main() { fmt.Printf("Error parsing flags: %v\n", err) os.Exit(1) } - runTestHarness(flagAcceptRetries, flagBindAddr, flagTMHome) + runTestHarness(flagAcceptRetries, flagBindAddr, flagOCHome) case "extract_key": if err := extractKeyCmd.Parse(os.Args[2:]); err != nil { fmt.Printf("Error parsing flags: %v\n", err) os.Exit(1) } - extractKey(flagTMHome, flagKeyOutputPath) + extractKey(flagOCHome, flagKeyOutputPath) case "version": - fmt.Println(version.TMCoreSemVer) + fmt.Println(version.OCCoreSemVer) default: fmt.Printf("Unrecognized command: %s\n", flag.Arg(0)) os.Exit(1) diff --git a/types/block.go b/types/block.go index fbf6eca10..ef1fa23c5 100644 --- a/types/block.go +++ b/types/block.go @@ -43,7 +43,7 @@ const ( MaxOverheadForBlock int64 = 11 ) -// Block defines the atomic unit of a Tendermint blockchain. +// Block defines the atomic unit of an Ostracon blockchain. type Block struct { mtx tmsync.Mutex @@ -329,7 +329,7 @@ func MaxDataBytesNoEvidence(maxBytes int64, valsCount int) int64 { //----------------------------------------------------------------------------- -// Header defines the structure of a Tendermint block header. +// Header defines the structure of an Ostracon block header. // NOTE: changes to the Header should be duplicated in: // - header.Hash() // - abci.Header diff --git a/types/event_bus.go b/types/event_bus.go index a998f0563..d32226219 100644 --- a/types/event_bus.go +++ b/types/event_bus.go @@ -99,7 +99,7 @@ func (b *EventBus) UnsubscribeAll(ctx context.Context, subscriber string) error return b.pubsub.UnsubscribeAll(ctx, subscriber) } -func (b *EventBus) Publish(eventType string, eventData TMEventData) error { +func (b *EventBus) Publish(eventType string, eventData OCEventData) error { // no explicit deadline for publishing events ctx := context.Background() return b.pubsub.PublishWithEvents(ctx, eventData, map[string][]string{EventTypeKey: {eventType}}) diff --git a/types/events.go b/types/events.go index 5256c33f6..db5b809e1 100644 --- a/types/events.go +++ b/types/events.go @@ -40,22 +40,22 @@ const ( // ENCODING / DECODING -// TMEventData implements events.EventData. -type TMEventData interface { +// OCEventData implements events.EventData. +type OCEventData interface { // empty interface } func init() { - tmjson.RegisterType(EventDataNewBlock{}, "tendermint/event/NewBlock") - tmjson.RegisterType(EventDataNewBlockHeader{}, "tendermint/event/NewBlockHeader") - tmjson.RegisterType(EventDataNewEvidence{}, "tendermint/event/NewEvidence") - tmjson.RegisterType(EventDataTx{}, "tendermint/event/Tx") - tmjson.RegisterType(EventDataRoundState{}, "tendermint/event/RoundState") - tmjson.RegisterType(EventDataNewRound{}, "tendermint/event/NewRound") - tmjson.RegisterType(EventDataCompleteProposal{}, "tendermint/event/CompleteProposal") - tmjson.RegisterType(EventDataVote{}, "tendermint/event/Vote") - tmjson.RegisterType(EventDataValidatorSetUpdates{}, "tendermint/event/ValidatorSetUpdates") - tmjson.RegisterType(EventDataString(""), "tendermint/event/ProposalString") + tmjson.RegisterType(EventDataNewBlock{}, "ostracon/event/NewBlock") + tmjson.RegisterType(EventDataNewBlockHeader{}, "ostracon/event/NewBlockHeader") + tmjson.RegisterType(EventDataNewEvidence{}, "ostracon/event/NewEvidence") + tmjson.RegisterType(EventDataTx{}, "ostracon/event/Tx") + tmjson.RegisterType(EventDataRoundState{}, "ostracon/event/RoundState") + tmjson.RegisterType(EventDataNewRound{}, "ostracon/event/NewRound") + tmjson.RegisterType(EventDataCompleteProposal{}, "ostracon/event/CompleteProposal") + tmjson.RegisterType(EventDataVote{}, "ostracon/event/Vote") + tmjson.RegisterType(EventDataValidatorSetUpdates{}, "ostracon/event/ValidatorSetUpdates") + tmjson.RegisterType(EventDataString(""), "ostracon/event/ProposalString") } // Most event messages are basic types (a block, a transaction) diff --git a/types/evidence.go b/types/evidence.go index c0c28c1a9..4d97b625b 100644 --- a/types/evidence.go +++ b/types/evidence.go @@ -515,8 +515,8 @@ func EvidenceFromProto(evidence *tmproto.Evidence) (Evidence, error) { } func init() { - tmjson.RegisterType(&DuplicateVoteEvidence{}, "tendermint/DuplicateVoteEvidence") - tmjson.RegisterType(&LightClientAttackEvidence{}, "tendermint/LightClientAttackEvidence") + tmjson.RegisterType(&DuplicateVoteEvidence{}, "ostracon/DuplicateVoteEvidence") + tmjson.RegisterType(&LightClientAttackEvidence{}, "ostracon/LightClientAttackEvidence") } //-------------------------------------------- ERRORS -------------------------------------- diff --git a/types/genesis_test.go b/types/genesis_test.go index 11fc49ddd..841486796 100644 --- a/types/genesis_test.go +++ b/types/genesis_test.go @@ -29,7 +29,7 @@ func TestGenesisBad(t *testing.T) { []byte( `{"validators":[` + `{"pub_key":{` + - `"type":"tendermint/PubKeyEd25519","value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="` + + `"type":"ostracon/PubKeyEd25519","value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="` + `},"power":"10","name":""}` + `]}`, ), @@ -37,7 +37,7 @@ func TestGenesisBad(t *testing.T) { []byte( `{"chain_id": "Lorem ipsum dolor sit amet, consectetuer adipiscing", "validators": [` + `{"pub_key":{` + - `"type":"tendermint/PubKeyEd25519","value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="` + + `"type":"ostracon/PubKeyEd25519","value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="` + `},"power":"10","name":""}` + `]}`, ), @@ -45,7 +45,7 @@ func TestGenesisBad(t *testing.T) { []byte( `{"chain_id":"mychain", "validators":[` + `{"address": "A", "pub_key":{` + - `"type":"tendermint/PubKeyEd25519","value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="` + + `"type":"ostracon/PubKeyEd25519","value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="` + `},"power":"10","name":""}` + `]}`, ), @@ -53,7 +53,7 @@ func TestGenesisBad(t *testing.T) { []byte( `{"chain_id":"mychain", "validators":[` + `{"pub_key":{` + - `"type":"tendermint/PubKeyEd25519","value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="` + + `"type":"ostracon/PubKeyEd25519","value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="` + `},"power":"10","name":""}], ` + `"voter_params":{"voter_election_threshold":"1"}` + `}`, @@ -75,7 +75,7 @@ func TestGenesisGood(t *testing.T) { "initial_height": "1000", "consensus_params": null, "validators": [{ - "pub_key":{"type":"tendermint/PubKeyEd25519","value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="}, + "pub_key":{"type":"ostracon/PubKeyEd25519","value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="}, "power":"10", "name":"" }], diff --git a/types/priv_validator.go b/types/priv_validator.go index 969488338..268438017 100644 --- a/types/priv_validator.go +++ b/types/priv_validator.go @@ -14,7 +14,7 @@ import ( tmproto "github.com/line/ostracon/proto/ostracon/types" ) -// PrivValidator defines the functionality of a local Tendermint validator +// PrivValidator defines the functionality of a local Ostracon validator // that signs votes and proposals, and never double signs. type PrivValidator interface { GetPubKey() (crypto.PubKey, error) diff --git a/types/protobuf.go b/types/protobuf.go index 352125345..c534eb655 100644 --- a/types/protobuf.go +++ b/types/protobuf.go @@ -32,13 +32,13 @@ var ABCIPubKeyTypesToNames = map[string]string{ //------------------------------------------------------- -// TM2PB is used for converting Tendermint ABCI to protobuf ABCI. +// OC2PB is used for converting Ostracon ABCI to protobuf ABCI. // UNSTABLE -var TM2PB = tm2pb{} +var OC2PB = oc2pb{} -type tm2pb struct{} +type oc2pb struct{} -func (tm2pb) Header(header *Header) tmproto.Header { +func (oc2pb) Header(header *Header) tmproto.Header { return tmproto.Header{ Version: header.Version, ChainID: header.ChainID, @@ -61,21 +61,21 @@ func (tm2pb) Header(header *Header) tmproto.Header { } } -func (tm2pb) Validator(val *Validator) abci.Validator { +func (oc2pb) Validator(val *Validator) abci.Validator { return abci.Validator{ Address: val.PubKey.Address(), Power: val.StakingPower, } } -func (tm2pb) BlockID(blockID BlockID) tmproto.BlockID { +func (oc2pb) BlockID(blockID BlockID) tmproto.BlockID { return tmproto.BlockID{ Hash: blockID.Hash, - PartSetHeader: TM2PB.PartSetHeader(blockID.PartSetHeader), + PartSetHeader: OC2PB.PartSetHeader(blockID.PartSetHeader), } } -func (tm2pb) PartSetHeader(header PartSetHeader) tmproto.PartSetHeader { +func (oc2pb) PartSetHeader(header PartSetHeader) tmproto.PartSetHeader { return tmproto.PartSetHeader{ Total: header.Total, Hash: header.Hash, @@ -83,7 +83,7 @@ func (tm2pb) PartSetHeader(header PartSetHeader) tmproto.PartSetHeader { } // XXX: panics on unknown pubkey type -func (tm2pb) ValidatorUpdate(val *Validator) abci.ValidatorUpdate { +func (oc2pb) ValidatorUpdate(val *Validator) abci.ValidatorUpdate { pk, err := cryptoenc.PubKeyToProto(val.PubKey) if err != nil { panic(err) @@ -95,15 +95,15 @@ func (tm2pb) ValidatorUpdate(val *Validator) abci.ValidatorUpdate { } // XXX: panics on nil or unknown pubkey type -func (tm2pb) ValidatorUpdates(vals *ValidatorSet) []abci.ValidatorUpdate { +func (oc2pb) ValidatorUpdates(vals *ValidatorSet) []abci.ValidatorUpdate { validators := make([]abci.ValidatorUpdate, vals.Size()) for i, val := range vals.Validators { - validators[i] = TM2PB.ValidatorUpdate(val) + validators[i] = OC2PB.ValidatorUpdate(val) } return validators } -func (tm2pb) ConsensusParams(params *tmproto.ConsensusParams) *abci.ConsensusParams { +func (oc2pb) ConsensusParams(params *tmproto.ConsensusParams) *abci.ConsensusParams { return &abci.ConsensusParams{ Block: &abci.BlockParams{ MaxBytes: params.Block.MaxBytes, @@ -115,7 +115,7 @@ func (tm2pb) ConsensusParams(params *tmproto.ConsensusParams) *abci.ConsensusPar } // XXX: panics on nil or unknown pubkey type -func (tm2pb) NewValidatorUpdate(pubkey crypto.PubKey, power int64) abci.ValidatorUpdate { +func (oc2pb) NewValidatorUpdate(pubkey crypto.PubKey, power int64) abci.ValidatorUpdate { pubkeyABCI, err := cryptoenc.PubKeyToProto(pubkey) if err != nil { panic(err) @@ -128,9 +128,9 @@ func (tm2pb) NewValidatorUpdate(pubkey crypto.PubKey, power int64) abci.Validato //---------------------------------------------------------------------------- -// PB2TM is used for converting protobuf ABCI to Tendermint ABCI. +// PB2OC is used for converting protobuf ABCI to Ostracon ABCI. // UNSTABLE -var PB2TM = pb2tm{} +var PB2OC = pb2tm{} type pb2tm struct{} diff --git a/types/protobuf_test.go b/types/protobuf_test.go index 6a2faf725..566631384 100644 --- a/types/protobuf_test.go +++ b/types/protobuf_test.go @@ -53,26 +53,26 @@ func TestABCIValidators(t *testing.T) { tmVal := NewValidator(pkEd, 10) - abciVal := TM2PB.ValidatorUpdate(tmVal) - tmVals, err := PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{abciVal}) + abciVal := OC2PB.ValidatorUpdate(tmVal) + tmVals, err := PB2OC.ValidatorUpdates([]abci.ValidatorUpdate{abciVal}) assert.Nil(t, err) assert.Equal(t, tmValExpected, tmVals[0]) - abciVals := TM2PB.ValidatorUpdates(NewValidatorSet(tmVals)) + abciVals := OC2PB.ValidatorUpdates(NewValidatorSet(tmVals)) assert.Equal(t, []abci.ValidatorUpdate{abciVal}, abciVals) // val with address tmVal.Address = pkEd.Address() - abciVal = TM2PB.ValidatorUpdate(tmVal) - tmVals, err = PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{abciVal}) + abciVal = OC2PB.ValidatorUpdate(tmVal) + tmVals, err = PB2OC.ValidatorUpdates([]abci.ValidatorUpdate{abciVal}) assert.Nil(t, err) assert.Equal(t, tmValExpected, tmVals[0]) } func TestABCIConsensusParams(t *testing.T) { cp := DefaultConsensusParams() - abciCP := TM2PB.ConsensusParams(cp) + abciCP := OC2PB.ConsensusParams(cp) cp2 := UpdateConsensusParams(*cp, abciCP) assert.Equal(t, *cp, cp2) @@ -112,7 +112,7 @@ func TestABCIHeader(t *testing.T) { cdc := amino.NewCodec() headerBz := cdc.MustMarshalBinaryBare(header) - pbHeader := TM2PB.Header(header) + pbHeader := OC2PB.Header(header) pbHeaderBz, err := proto.Marshal(&pbHeader) assert.NoError(t, err) @@ -168,17 +168,17 @@ func (pubKeyEddie) Type() string func TestABCIValidatorFromPubKeyAndPower(t *testing.T) { pubkey := ed25519.GenPrivKey().PubKey() - abciVal := TM2PB.NewValidatorUpdate(pubkey, 10) + abciVal := OC2PB.NewValidatorUpdate(pubkey, 10) assert.Equal(t, int64(10), abciVal.Power) - assert.Panics(t, func() { TM2PB.NewValidatorUpdate(nil, 10) }) - assert.Panics(t, func() { TM2PB.NewValidatorUpdate(pubKeyEddie{}, 10) }) + assert.Panics(t, func() { OC2PB.NewValidatorUpdate(nil, 10) }) + assert.Panics(t, func() { OC2PB.NewValidatorUpdate(pubKeyEddie{}, 10) }) } func TestABCIValidatorWithoutPubKey(t *testing.T) { pkEd := ed25519.GenPrivKey().PubKey() - abciVal := TM2PB.Validator(NewValidator(pkEd, 10)) + abciVal := OC2PB.Validator(NewValidator(pkEd, 10)) // pubkey must be nil tmValExpected := abci.Validator{ diff --git a/types/tx.go b/types/tx.go index 6a506c6d3..41f3120e6 100644 --- a/types/tx.go +++ b/types/tx.go @@ -16,7 +16,7 @@ import ( // Might we want types here ? type Tx []byte -// Hash computes the TMHASH hash of the wire encoded transaction. +// Hash computes the OCHASH hash of the wire encoded transaction. func (tx Tx) Hash() []byte { return tmhash.Sum(tx) } diff --git a/types/tx_test.go b/types/tx_test.go index 08e00c7a7..c8e239834 100644 --- a/types/tx_test.go +++ b/types/tx_test.go @@ -149,3 +149,33 @@ func assertBadProof(t *testing.T, root []byte, bad []byte, good TxProof) { } } } + +func TestComputeProtoSizeForTxs(t *testing.T) { + tests := []struct { + count int + }{ + {1}, + {2}, + {30}, + {450}, + {1352}, + {2543}, + {4000}, + } + + for _, tt := range tests { + allTxs := make(Txs, tt.count) + for i := 0; i < tt.count; i++ { + size := tmrand.Intn(500) + allTxs[i] = tmrand.Bytes(size) + } + + txs := make([]Tx, 0, len(allTxs)) + protoTxs := tmproto.Data{} + for _, tx := range allTxs { + protoTxs.Txs = append(protoTxs.Txs, tx) + txs = append(txs, tx) + require.Equal(t, int64(protoTxs.Size()), ComputeProtoSizeForTxs(txs)) + } + } +} diff --git a/types/utils.go b/types/utils.go index cec47e202..2646464dd 100644 --- a/types/utils.go +++ b/types/utils.go @@ -1,6 +1,21 @@ package types -import "reflect" +import ( + "reflect" + "time" +) + +type StepDuration struct { + Start time.Time + End time.Time +} + +func (sd *StepDuration) GetDuration() float64 { + if sd.End.After(sd.Start) { + return float64(sd.End.Sub(sd.Start).Microseconds()) / 1000 + } + return 0 +} // Go lacks a simple and safe way to see if something is a typed nil. // See: diff --git a/version/version.go b/version/version.go index 4050db234..51ba5a873 100644 --- a/version/version.go +++ b/version/version.go @@ -1,15 +1,15 @@ package version var ( - // TMCoreSemVer is the current version of Tendermint Core. + // OCCoreSemVer is the current version of Ostracon Core. // It's the Semantic Version of the software. - TMCoreSemVer string + OCCoreSemVer string // GitCommit is the current HEAD set using ldflags. GitCommit string // Version is the built softwares version. - Version = TMCoreSemVer + "-" + LINECoreSemVer + Version = OCCoreSemVer + "-" + LINECoreSemVer ) func init() { @@ -19,7 +19,7 @@ func init() { } const ( - // LINECoreSemVer is the current version of LINE Tendermint Core. + // LINECoreSemVer is the current version of LINE Ostracon Core. LINECoreSemVer = "0.3" // ABCISemVer is the semantic version of the ABCI library