mirror of
https://github.com/tendermint/tendermint.git
synced 2026-09-04 07:07:13 +00:00
abci: PrepareProposal (#6544)
This commit is contained in:
@@ -301,3 +301,8 @@ func (app *CounterApplication) Commit() abci.ResponseCommit {
|
||||
binary.BigEndian.PutUint64(hash, uint64(app.txCount))
|
||||
return abci.ResponseCommit{Data: hash}
|
||||
}
|
||||
|
||||
func (app *CounterApplication) PrepareProposal(
|
||||
req abci.RequestPrepareProposal) abci.ResponsePrepareProposal {
|
||||
return abci.ResponsePrepareProposal{BlockData: req.BlockData} //nolint:gosimple
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ type AppConnConsensus interface {
|
||||
|
||||
InitChain(context.Context, types.RequestInitChain) (*types.ResponseInitChain, error)
|
||||
|
||||
PrepareProposal(context.Context, types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error)
|
||||
BeginBlock(context.Context, types.RequestBeginBlock) (*types.ResponseBeginBlock, error)
|
||||
DeliverTx(context.Context, types.RequestDeliverTx) (*types.ResponseDeliverTx, error)
|
||||
EndBlock(context.Context, types.RequestEndBlock) (*types.ResponseEndBlock, error)
|
||||
@@ -62,6 +63,8 @@ type appConnConsensus struct {
|
||||
appConn abciclient.Client
|
||||
}
|
||||
|
||||
var _ AppConnConsensus = (*appConnConsensus)(nil)
|
||||
|
||||
func NewAppConnConsensus(appConn abciclient.Client, metrics *Metrics) AppConnConsensus {
|
||||
return &appConnConsensus{
|
||||
metrics: metrics,
|
||||
@@ -85,6 +88,14 @@ func (app *appConnConsensus) InitChain(
|
||||
return app.appConn.InitChain(ctx, req)
|
||||
}
|
||||
|
||||
func (app *appConnConsensus) PrepareProposal(
|
||||
ctx context.Context,
|
||||
req types.RequestPrepareProposal,
|
||||
) (*types.ResponsePrepareProposal, error) {
|
||||
defer addTimeSample(app.metrics.MethodTiming.With("method", "prepare_proposal", "type", "sync"))()
|
||||
return app.appConn.PrepareProposal(ctx, req)
|
||||
}
|
||||
|
||||
func (app *appConnConsensus) BeginBlock(
|
||||
ctx context.Context,
|
||||
req types.RequestBeginBlock,
|
||||
|
||||
@@ -146,6 +146,29 @@ func (_m *AppConnConsensus) InitChain(_a0 context.Context, _a1 types.RequestInit
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// PrepareProposal provides a mock function with given fields: _a0, _a1
|
||||
func (_m *AppConnConsensus) PrepareProposal(_a0 context.Context, _a1 types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
var r0 *types.ResponsePrepareProposal
|
||||
if rf, ok := ret.Get(0).(func(context.Context, types.RequestPrepareProposal) *types.ResponsePrepareProposal); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*types.ResponsePrepareProposal)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, types.RequestPrepareProposal) error); ok {
|
||||
r1 = rf(_a0, _a1)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// SetResponseCallback provides a mock function with given fields: _a0
|
||||
func (_m *AppConnConsensus) SetResponseCallback(_a0 abciclient.Callback) {
|
||||
_m.Called(_a0)
|
||||
|
||||
@@ -99,6 +99,8 @@ func (blockExec *BlockExecutor) SetEventBus(eventBus types.BlockEventPublisher)
|
||||
// and txs from the mempool. The max bytes must be big enough to fit the commit.
|
||||
// Up to 1/10th of the block space is allcoated for maximum sized evidence.
|
||||
// The rest is given to txs, up to the max gas.
|
||||
//
|
||||
// Contract: application will not return more bytes than are sent over the wire.
|
||||
func (blockExec *BlockExecutor) CreateProposalBlock(
|
||||
height int64,
|
||||
state State, commit *types.Commit,
|
||||
@@ -115,7 +117,34 @@ func (blockExec *BlockExecutor) CreateProposalBlock(
|
||||
|
||||
txs := blockExec.mempool.ReapMaxBytesMaxGas(maxDataBytes, maxGas)
|
||||
|
||||
return state.MakeBlock(height, txs, commit, evidence, proposerAddr)
|
||||
preparedProposal, err := blockExec.proxyApp.PrepareProposal(
|
||||
context.Background(),
|
||||
abci.RequestPrepareProposal{BlockData: txs.ToSliceOfBytes(), BlockDataSize: maxDataBytes},
|
||||
)
|
||||
if err != nil {
|
||||
// The App MUST ensure that only valid (and hence 'processable') transactions
|
||||
// enter the mempool. Hence, at this point, we can't have any non-processable
|
||||
// transaction causing an error.
|
||||
//
|
||||
// Also, the App can simply skip any transaction that could cause any kind of trouble.
|
||||
// Either way, we can not recover in a meaningful way, unless we skip proposing
|
||||
// this block, repair what caused the error and try again. Hence, we panic on
|
||||
// purpose for now.
|
||||
panic(err)
|
||||
}
|
||||
newTxs := preparedProposal.GetBlockData()
|
||||
var txSize int
|
||||
for _, tx := range newTxs {
|
||||
txSize += len(tx)
|
||||
|
||||
if maxDataBytes < int64(txSize) {
|
||||
panic("block data exceeds max amount of allowed bytes")
|
||||
}
|
||||
}
|
||||
|
||||
modifiedTxs := types.ToTxs(preparedProposal.GetBlockData())
|
||||
|
||||
return state.MakeBlock(height, modifiedTxs, commit, evidence, proposerAddr)
|
||||
}
|
||||
|
||||
// ValidateBlock validates the given block against the given state.
|
||||
|
||||
Reference in New Issue
Block a user