Browse Source

initial suite of tests

wb/txrset
William Banfield 3 years ago
parent
commit
7e75f88780
No known key found for this signature in database GPG Key ID: EFAD3442BF29E3AC
3 changed files with 188 additions and 0 deletions
  1. +11
    -0
      abci/types/types.go
  2. +164
    -0
      internal/state/execution_test.go
  3. +13
    -0
      types/tx.go

+ 11
- 0
abci/types/types.go View File

@ -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 {


+ 164
- 0
internal/state/execution_test.go View File

@ -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
- 0
types/tx.go View File

@ -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"`


Loading…
Cancel
Save