mirror of
https://github.com/tendermint/tendermint.git
synced 2026-08-19 05:36:15 +00:00
initial suite of tests
This commit is contained in:
@@ -233,6 +233,17 @@ func (rpp *ResponsePrepareProposal) RemovedTxs() []*TxRecord {
|
||||
return trs
|
||||
}
|
||||
|
||||
// AddedTxs returns all of the TxRecords that are marked as added to the proposal.
|
||||
func (rpp *ResponsePrepareProposal) AddedTxs() []*TxRecord {
|
||||
trs := []*TxRecord{}
|
||||
for _, tr := range rpp.TxRecords {
|
||||
if tr.Action == TxRecord_ADDED {
|
||||
trs = append(trs, tr)
|
||||
}
|
||||
}
|
||||
return trs
|
||||
}
|
||||
|
||||
// Validate checks that the fields of the ResponsePrepareProposal are properly
|
||||
// constructed. Validate returns an error if any of the validation checks fail.
|
||||
func (rpp *ResponsePrepareProposal) Validate(maxSizeBytes int64, otxs [][]byte) error {
|
||||
|
||||
@@ -657,6 +657,170 @@ func TestEmptyPrepareProposal(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
// TestPrepareProposalRemoveTxs tests that any transactions marked as REMOVED
|
||||
// are not included in the block produced by CreateProposalBlock. The test also
|
||||
// ensures that any transactions removed are also removed from the mempool.
|
||||
func TestPrepareProposalRemoveTxs(t *testing.T) {
|
||||
const height = 2
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
state, stateDB, privVals := makeState(t, 1, height)
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
|
||||
evpool := &mocks.EvidencePool{}
|
||||
evpool.On("PendingEvidence", mock.Anything).Return([]types.Evidence{}, int64(0))
|
||||
|
||||
txs := factory.MakeTenTxs(height)
|
||||
mp := &mpmocks.Mempool{}
|
||||
mp.On("ReapMaxBytesMaxGas", mock.Anything, mock.Anything).Return(types.Txs(txs))
|
||||
|
||||
trs := types.TxsToTxRecords(types.Txs(txs))
|
||||
trs[0].Action = abci.TxRecord_REMOVED
|
||||
trs[1].Action = abci.TxRecord_REMOVED
|
||||
mp.On("RemoveTxByKey", mock.Anything).Return(nil).Twice()
|
||||
|
||||
app := abcimocks.NewBaseMock()
|
||||
app.On("PrepareProposal", mock.Anything).Return(abci.ResponsePrepareProposal{
|
||||
ModifiedTx: true,
|
||||
TxRecords: trs,
|
||||
}, nil)
|
||||
|
||||
cc := abciclient.NewLocalCreator(app)
|
||||
logger := log.TestingLogger()
|
||||
proxyApp := proxy.NewAppConns(cc, logger, proxy.NopMetrics())
|
||||
err := proxyApp.Start(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
blockExec := sm.NewBlockExecutor(
|
||||
stateStore,
|
||||
logger,
|
||||
proxyApp.Consensus(),
|
||||
mp,
|
||||
evpool,
|
||||
nil,
|
||||
)
|
||||
pa, _ := state.Validators.GetByIndex(0)
|
||||
commit := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
|
||||
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, block.Data.Txs.ToSliceOfBytes(), len(trs)-2)
|
||||
|
||||
require.Equal(t, -1, block.Data.Txs.Index(types.Tx(trs[0].Tx)))
|
||||
require.Equal(t, -1, block.Data.Txs.Index(types.Tx(trs[1].Tx)))
|
||||
|
||||
mp.AssertCalled(t, "RemoveTxByKey", types.Tx(trs[0].Tx).Key())
|
||||
mp.AssertCalled(t, "RemoveTxByKey", types.Tx(trs[1].Tx).Key())
|
||||
mp.AssertExpectations(t)
|
||||
}
|
||||
|
||||
// TestPrepareProposalAddedTxsIncluded tests that any transactions marked as ADDED
|
||||
// in the prepare proposal response are included in the block. The test also
|
||||
// ensures that any transactions added are also checked into the mempool.
|
||||
func TestPrepareProposalAddedTxsIncluded(t *testing.T) {
|
||||
const height = 2
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
state, stateDB, privVals := makeState(t, 1, height)
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
|
||||
evpool := &mocks.EvidencePool{}
|
||||
evpool.On("PendingEvidence", mock.Anything).Return([]types.Evidence{}, int64(0))
|
||||
|
||||
txs := factory.MakeTenTxs(height)
|
||||
mp := &mpmocks.Mempool{}
|
||||
mp.On("ReapMaxBytesMaxGas", mock.Anything, mock.Anything).Return(types.Txs(txs[2:]))
|
||||
mp.On("CheckTx", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil).Twice()
|
||||
|
||||
trs := types.TxsToTxRecords(types.Txs(txs))
|
||||
trs[0].Action = abci.TxRecord_ADDED
|
||||
trs[1].Action = abci.TxRecord_ADDED
|
||||
|
||||
app := abcimocks.NewBaseMock()
|
||||
app.On("PrepareProposal", mock.Anything).Return(abci.ResponsePrepareProposal{
|
||||
ModifiedTx: true,
|
||||
TxRecords: trs,
|
||||
}, nil)
|
||||
|
||||
cc := abciclient.NewLocalCreator(app)
|
||||
logger := log.TestingLogger()
|
||||
proxyApp := proxy.NewAppConns(cc, logger, proxy.NopMetrics())
|
||||
err := proxyApp.Start(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
blockExec := sm.NewBlockExecutor(
|
||||
stateStore,
|
||||
logger,
|
||||
proxyApp.Consensus(),
|
||||
mp,
|
||||
evpool,
|
||||
nil,
|
||||
)
|
||||
pa, _ := state.Validators.GetByIndex(0)
|
||||
commit := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
|
||||
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, txs[0], block.Data.Txs[0])
|
||||
require.Equal(t, txs[1], block.Data.Txs[1])
|
||||
|
||||
mp.AssertExpectations(t)
|
||||
mp.AssertCalled(t, "CheckTx", mock.Anything, types.Tx(trs[0].Tx), mock.Anything, mock.Anything)
|
||||
mp.AssertCalled(t, "CheckTx", mock.Anything, types.Tx(trs[1].Tx), mock.Anything, mock.Anything)
|
||||
}
|
||||
|
||||
// TestPrepareProposalReorderTxs tests that CreateBlock produces a block with transactions
|
||||
// in the order matching the order they are returned from PrepareProposal.
|
||||
func TestPrepareProposalReorderTxs(t *testing.T) {
|
||||
const height = 2
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
state, stateDB, privVals := makeState(t, 1, height)
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
|
||||
evpool := &mocks.EvidencePool{}
|
||||
evpool.On("PendingEvidence", mock.Anything).Return([]types.Evidence{}, int64(0))
|
||||
|
||||
txs := factory.MakeTenTxs(height)
|
||||
mp := &mpmocks.Mempool{}
|
||||
mp.On("ReapMaxBytesMaxGas", mock.Anything, mock.Anything).Return(types.Txs(txs))
|
||||
|
||||
trs := types.TxsToTxRecords(types.Txs(txs))
|
||||
trs = append(trs[len(trs)/2:], trs[:len(trs)/2]...)
|
||||
|
||||
app := abcimocks.NewBaseMock()
|
||||
app.On("PrepareProposal", mock.Anything).Return(abci.ResponsePrepareProposal{
|
||||
ModifiedTx: true,
|
||||
TxRecords: trs,
|
||||
}, nil)
|
||||
|
||||
cc := abciclient.NewLocalCreator(app)
|
||||
logger := log.TestingLogger()
|
||||
proxyApp := proxy.NewAppConns(cc, logger, proxy.NopMetrics())
|
||||
err := proxyApp.Start(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
blockExec := sm.NewBlockExecutor(
|
||||
stateStore,
|
||||
logger,
|
||||
proxyApp.Consensus(),
|
||||
mp,
|
||||
evpool,
|
||||
nil,
|
||||
)
|
||||
pa, _ := state.Validators.GetByIndex(0)
|
||||
commit := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
|
||||
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa)
|
||||
require.NoError(t, err)
|
||||
for i, tx := range block.Data.Txs {
|
||||
require.Equal(t, types.Tx(trs[i].Tx), tx)
|
||||
}
|
||||
|
||||
mp.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func makeBlockID(hash []byte, partSetSize uint32, partSetHash []byte) types.BlockID {
|
||||
var (
|
||||
h = make([]byte, tmhash.Size)
|
||||
|
||||
+13
@@ -112,6 +112,19 @@ func TxRecordsToTxs(trs []*abci.TxRecord) Txs {
|
||||
return txs
|
||||
}
|
||||
|
||||
// TxsToTxRecords converts from a list of Txs to a list of TxRecords. All of the
|
||||
// resulting TxRecords are returned with the status TxRecord_UNMODIFIED.
|
||||
func TxsToTxRecords(txs []Tx) []*abci.TxRecord {
|
||||
trs := make([]*abci.TxRecord, len(txs))
|
||||
for i, tx := range txs {
|
||||
trs[i] = &abci.TxRecord{
|
||||
Action: abci.TxRecord_UNMODIFIED,
|
||||
Tx: tx,
|
||||
}
|
||||
}
|
||||
return trs
|
||||
}
|
||||
|
||||
// TxProof represents a Merkle proof of the presence of a transaction in the Merkle tree.
|
||||
type TxProof struct {
|
||||
RootHash tmbytes.HexBytes `json:"root_hash"`
|
||||
|
||||
Reference in New Issue
Block a user