mirror of
https://github.com/tendermint/tendermint.git
synced 2026-09-27 10:24:36 +00:00
abci: make tendermint example+test clients manage a mutex (#7978)
This is the first step in removing the mutex from ABCI applications: making our test applications hold mutexes, which this does, hopefully with zero impact. If this lands well, then we can explore deleting the other mutexes (in the ABCI server and the clients.) While this change is not user impacting at all, removing the other mutexes *will* be. In persuit of this, I've changed the KV app somewhat, to put almost all of the logic in the base application and make the persistent application mostly be a wrapper on top of that with a different storage layer.
This commit is contained in:
+35
-4
@@ -8,6 +8,7 @@ import (
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/tendermint/tendermint/abci/example/code"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
@@ -21,6 +22,7 @@ import (
|
||||
// to disk as JSON, taking state sync snapshots if requested.
|
||||
type Application struct {
|
||||
abci.BaseApplication
|
||||
mu sync.Mutex
|
||||
logger log.Logger
|
||||
state *State
|
||||
snapshots *SnapshotStore
|
||||
@@ -98,8 +100,8 @@ func NewApplication(cfg *Config) (*Application, error) {
|
||||
|
||||
// Info implements ABCI.
|
||||
func (app *Application) Info(req abci.RequestInfo) abci.ResponseInfo {
|
||||
app.state.RLock()
|
||||
defer app.state.RUnlock()
|
||||
app.mu.Lock()
|
||||
defer app.mu.Unlock()
|
||||
|
||||
return abci.ResponseInfo{
|
||||
Version: version.ABCIVersion,
|
||||
@@ -111,6 +113,9 @@ func (app *Application) Info(req abci.RequestInfo) abci.ResponseInfo {
|
||||
|
||||
// Info implements ABCI.
|
||||
func (app *Application) InitChain(req abci.RequestInitChain) abci.ResponseInitChain {
|
||||
app.mu.Lock()
|
||||
defer app.mu.Unlock()
|
||||
|
||||
var err error
|
||||
app.state.initialHeight = uint64(req.InitialHeight)
|
||||
if len(req.AppStateBytes) > 0 {
|
||||
@@ -135,6 +140,9 @@ func (app *Application) InitChain(req abci.RequestInitChain) abci.ResponseInitCh
|
||||
|
||||
// CheckTx implements ABCI.
|
||||
func (app *Application) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx {
|
||||
app.mu.Lock()
|
||||
defer app.mu.Unlock()
|
||||
|
||||
_, _, err := parseTx(req.Tx)
|
||||
if err != nil {
|
||||
return abci.ResponseCheckTx{
|
||||
@@ -149,6 +157,9 @@ func (app *Application) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx {
|
||||
func (app *Application) FinalizeBlock(req abci.RequestFinalizeBlock) abci.ResponseFinalizeBlock {
|
||||
var txs = make([]*abci.ResponseDeliverTx, len(req.Txs))
|
||||
|
||||
app.mu.Lock()
|
||||
defer app.mu.Unlock()
|
||||
|
||||
for i, tx := range req.Txs {
|
||||
key, value, err := parseTx(tx)
|
||||
if err != nil {
|
||||
@@ -187,6 +198,9 @@ func (app *Application) FinalizeBlock(req abci.RequestFinalizeBlock) abci.Respon
|
||||
|
||||
// Commit implements ABCI.
|
||||
func (app *Application) Commit() abci.ResponseCommit {
|
||||
app.mu.Lock()
|
||||
defer app.mu.Unlock()
|
||||
|
||||
height, hash, err := app.state.Commit()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -214,6 +228,9 @@ func (app *Application) Commit() abci.ResponseCommit {
|
||||
|
||||
// Query implements ABCI.
|
||||
func (app *Application) Query(req abci.RequestQuery) abci.ResponseQuery {
|
||||
app.mu.Lock()
|
||||
defer app.mu.Unlock()
|
||||
|
||||
return abci.ResponseQuery{
|
||||
Height: int64(app.state.Height),
|
||||
Key: req.Data,
|
||||
@@ -223,6 +240,9 @@ func (app *Application) Query(req abci.RequestQuery) abci.ResponseQuery {
|
||||
|
||||
// ListSnapshots implements ABCI.
|
||||
func (app *Application) ListSnapshots(req abci.RequestListSnapshots) abci.ResponseListSnapshots {
|
||||
app.mu.Lock()
|
||||
defer app.mu.Unlock()
|
||||
|
||||
snapshots, err := app.snapshots.List()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -232,6 +252,9 @@ func (app *Application) ListSnapshots(req abci.RequestListSnapshots) abci.Respon
|
||||
|
||||
// LoadSnapshotChunk implements ABCI.
|
||||
func (app *Application) LoadSnapshotChunk(req abci.RequestLoadSnapshotChunk) abci.ResponseLoadSnapshotChunk {
|
||||
app.mu.Lock()
|
||||
defer app.mu.Unlock()
|
||||
|
||||
chunk, err := app.snapshots.LoadChunk(req.Height, req.Format, req.Chunk)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -241,6 +264,9 @@ func (app *Application) LoadSnapshotChunk(req abci.RequestLoadSnapshotChunk) abc
|
||||
|
||||
// OfferSnapshot implements ABCI.
|
||||
func (app *Application) OfferSnapshot(req abci.RequestOfferSnapshot) abci.ResponseOfferSnapshot {
|
||||
app.mu.Lock()
|
||||
defer app.mu.Unlock()
|
||||
|
||||
if app.restoreSnapshot != nil {
|
||||
panic("A snapshot is already being restored")
|
||||
}
|
||||
@@ -251,6 +277,9 @@ func (app *Application) OfferSnapshot(req abci.RequestOfferSnapshot) abci.Respon
|
||||
|
||||
// ApplySnapshotChunk implements ABCI.
|
||||
func (app *Application) ApplySnapshotChunk(req abci.RequestApplySnapshotChunk) abci.ResponseApplySnapshotChunk {
|
||||
app.mu.Lock()
|
||||
defer app.mu.Unlock()
|
||||
|
||||
if app.restoreSnapshot == nil {
|
||||
panic("No restore in progress")
|
||||
}
|
||||
@@ -270,12 +299,14 @@ func (app *Application) ApplySnapshotChunk(req abci.RequestApplySnapshotChunk) a
|
||||
return abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}
|
||||
}
|
||||
|
||||
func (app *Application) PrepareProposal(
|
||||
req abci.RequestPrepareProposal) abci.ResponsePrepareProposal {
|
||||
func (app *Application) PrepareProposal(req abci.RequestPrepareProposal) abci.ResponsePrepareProposal {
|
||||
return abci.ResponsePrepareProposal{BlockData: req.BlockData}
|
||||
}
|
||||
|
||||
func (app *Application) Rollback() error {
|
||||
app.mu.Lock()
|
||||
defer app.mu.Unlock()
|
||||
|
||||
return app.state.Rollback()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user