Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: improve performance and modify some abci #287

Merged
merged 40 commits into from
Aug 26, 2021
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
208ceef
feat: more prometheus metrics for monitoring performance (#146) (#175)
Mar 4, 2021
727f843
chore: config timeout and connection pool (#150) (#171)
Feb 3, 2021
1cf27a5
fix: use line/tm-db instead of tendermint/tm-db
Jul 7, 2021
dce3c03
bump up tm-db, iavl; re-apply #201
Jul 7, 2021
04c5f31
chore: use default db backend among the available ones (#212)
Apr 6, 2021
877e670
feat: concurrent checkTx #213; fix tm-db call
Jul 7, 2021
5c8e180
fix: rename TM to OC
Jul 7, 2021
39067a6
fix: modify key name; tendermint -> ostracon
Jul 7, 2021
7ea6e35
chore: rename tendermint to ostracon
Jul 8, 2021
800cab3
chore: remove mempool.postCheck (#158) (#217)
Apr 16, 2021
05becb8
fix: revise to call Begin/EndRecheck even though mem.Size() is 0 (#219)
Apr 19, 2021
1221fe7
feat: concurrent recheckTx (#163) (#221)
Jul 8, 2021
94c8980
chore: increase the value of maxPerPage (#223)
Apr 27, 2021
7da95d6
chore: fix the type of consensus_block_interval_seconds from histogra…
Apr 27, 2021
4417941
feat: impl checkTxAsyncReactor() (#168) (#225)
Apr 28, 2021
e47f13d
chore: revise abci.Client, Async() interfaces (#169) (#226)
Apr 29, 2021
1413661
chore: remove iavl dependency (#228)
Apr 29, 2021
0ed36c7
fix: add more fixing for abci.Client, Async()
Jul 8, 2021
720052e
feat: revise metric for measuring performance
Jul 8, 2021
1a500f9
build: remove needless build tag `!libsecp256k1` (#246)
May 12, 2021
ceec05b
feat: add duration metrics of gauge type (#256)
May 17, 2021
162c63c
perf: optimize checking the txs size (#264)
Jun 4, 2021
50cffac
perf: do not flush wal when receive consensus msgs (#273)
Jun 10, 2021
5a06c8d
Merge branch 'main' of github.com:line/ostracon into merge_ebony_to_main
Aug 9, 2021
c755946
fix: ci failure
Aug 9, 2021
5df13f2
fix: lint failure
Aug 9, 2021
977def3
fix: ci-e2e build failure
Aug 11, 2021
ba7a3d0
fix: bump up tm-db
Aug 23, 2021
93534f4
Merge branch 'main' of github.com:line/ostracon into merge_ebony_to_main
Aug 23, 2021
e9d619a
fix: missing abci api
Aug 24, 2021
36a5be6
fix: bump up tm-db; use memdb
Aug 24, 2021
59e7bc7
test: add test case to raise test coverage
Aug 24, 2021
b3e4dba
fix: race error
Aug 24, 2021
9b49721
fix: race error
Aug 24, 2021
03a1d83
fix: race error
Aug 24, 2021
9a37eb9
fix: increase e2e test timeout
Aug 24, 2021
4f184f7
fix: add test case for coverage
Aug 24, 2021
dec7021
fix: e2e docker file
Aug 24, 2021
b229947
fix: apply comments
Aug 25, 2021
c8cbd4b
fix: a Ostracon to an Ostracon
Aug 25, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/feature-request.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ v without deliberation

<!-- Why do we need this feature?
What problems may be addressed by introducing this feature?
What benefits does Tendermint stand to gain by including this feature?
What benefits does Ostracon stand to gain by including this feature?
Are there any disadvantages of including this feature? -->

## Proposal
Expand Down
2 changes: 1 addition & 1 deletion .github/auto-comment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ pullRequestOpened: |
- [ ] Applied Appropriate Labels


Thank you for your contribution to Tendermint! :rocket:
Thank you for your contribution to Ostracon! :rocket:
2 changes: 1 addition & 1 deletion .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
@@ -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:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/proto-docker.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build & Push TM Proto Builder
name: Build & Push OC Proto Builder
on:
pull_request:
paths:
Expand Down
8 changes: 4 additions & 4 deletions DOCKER/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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" ]

8 changes: 4 additions & 4 deletions DOCKER/docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -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 "$@"
121 changes: 58 additions & 63 deletions abci/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
tmsync "github.com/line/ostracon/libs/sync"
)

//go:generate mockery --case underscore --name Client
const (
dialRetryIntervalSeconds = 3
echoRetryIntervalSeconds = 1
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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) {
Expand Down
Loading