mirror of
https://github.com/tendermint/tendermint.git
synced 2026-09-19 22:44:24 +00:00
remove methods from abci tx records
This commit is contained in:
@@ -3,8 +3,6 @@ package types
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/gogo/protobuf/jsonpb"
|
"github.com/gogo/protobuf/jsonpb"
|
||||||
|
|
||||||
@@ -197,90 +195,3 @@ func TxResultsToByteSlices(r []*ExecTxResult) ([][]byte, error) {
|
|||||||
}
|
}
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tr *TxRecord) isIncluded() bool {
|
|
||||||
return tr.Action == TxRecord_ADDED || tr.Action == TxRecord_UNMODIFIED
|
|
||||||
}
|
|
||||||
|
|
||||||
// IncludedTxs returns all of the TxRecords that are marked for inclusion in the
|
|
||||||
// proposed block.
|
|
||||||
func (rpp *ResponsePrepareProposal) IncludedTxs() []*TxRecord {
|
|
||||||
trs := []*TxRecord{}
|
|
||||||
for _, tr := range rpp.TxRecords {
|
|
||||||
if tr.isIncluded() {
|
|
||||||
trs = append(trs, tr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return trs
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemovedTxs returns all of the TxRecords that are marked for removal from the
|
|
||||||
// mempool.
|
|
||||||
func (rpp *ResponsePrepareProposal) RemovedTxs() []*TxRecord {
|
|
||||||
var trs []*TxRecord
|
|
||||||
for _, tr := range rpp.TxRecords {
|
|
||||||
if tr.Action == TxRecord_REMOVED {
|
|
||||||
trs = append(trs, tr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return trs
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddedTxs returns all of the TxRecords that are marked as added to the proposal.
|
|
||||||
func (rpp *ResponsePrepareProposal) AddedTxs() []*TxRecord {
|
|
||||||
var 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 {
|
|
||||||
if !rpp.ModifiedTx {
|
|
||||||
// This method currently only checks the validity of the TxRecords field.
|
|
||||||
// If ModifiedTx is false, then we can ignore the validity of the TxRecords field.
|
|
||||||
//
|
|
||||||
// TODO: When implementing VoteExensions, AppSignedUpdates may be modified by the application
|
|
||||||
// and this method should be updated to validate the AppSignedUpdates.
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: this feels like a large amount allocated data. We move all the Txs into strings
|
|
||||||
// in the map. The map will be as large as the original byte slice.
|
|
||||||
// Is there a key we can use?
|
|
||||||
otxsSet := make(map[string]struct{}, len(otxs))
|
|
||||||
for _, tx := range otxs {
|
|
||||||
otxsSet[string(tx)] = struct{}{}
|
|
||||||
}
|
|
||||||
ntx := map[string]struct{}{}
|
|
||||||
var size int64
|
|
||||||
for _, tr := range rpp.TxRecords {
|
|
||||||
if tr.isIncluded() {
|
|
||||||
size += int64(len(tr.Tx))
|
|
||||||
if size > maxSizeBytes {
|
|
||||||
return fmt.Errorf("transaction data size %d exceeds maximum %d", size, maxSizeBytes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if _, ok := ntx[string(tr.Tx)]; ok {
|
|
||||||
return errors.New("TxRecords contains duplicate transaction")
|
|
||||||
}
|
|
||||||
ntx[string(tr.Tx)] = struct{}{}
|
|
||||||
if _, ok := otxsSet[string(tr.Tx)]; ok {
|
|
||||||
if tr.Action == TxRecord_ADDED {
|
|
||||||
return fmt.Errorf("unmodified transaction incorrectly marked as %s", tr.Action.String())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if tr.Action == TxRecord_REMOVED || tr.Action == TxRecord_UNMODIFIED {
|
|
||||||
return fmt.Errorf("unmodified transaction incorrectly marked as %s", tr.Action.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if tr.Action == TxRecord_UNKNOWN {
|
|
||||||
return fmt.Errorf("transaction incorrectly marked as %s", tr.Action.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package types_test
|
package types_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
fmt "fmt"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@@ -71,127 +70,3 @@ func TestHashDeterministicFieldsOnly(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, merkle.HashFromByteSlices(r1), merkle.HashFromByteSlices(r2))
|
require.Equal(t, merkle.HashFromByteSlices(r1), merkle.HashFromByteSlices(r2))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestValidateResponsePrepareProposal(t *testing.T) {
|
|
||||||
t.Run("should error on total transaction size exceeding max data size", func(t *testing.T) {
|
|
||||||
rpp := &abci.ResponsePrepareProposal{
|
|
||||||
ModifiedTx: true,
|
|
||||||
TxRecords: []*abci.TxRecord{
|
|
||||||
{
|
|
||||||
Action: abci.TxRecord_ADDED,
|
|
||||||
Tx: []byte{1, 2, 3, 4, 5},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Action: abci.TxRecord_ADDED,
|
|
||||||
Tx: []byte{6, 7, 8, 9, 10},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
err := rpp.Validate(9, [][]byte{})
|
|
||||||
require.Error(t, err)
|
|
||||||
})
|
|
||||||
t.Run("should error on duplicate transactions with the same action", func(t *testing.T) {
|
|
||||||
rpp := &abci.ResponsePrepareProposal{
|
|
||||||
ModifiedTx: true,
|
|
||||||
TxRecords: []*abci.TxRecord{
|
|
||||||
{
|
|
||||||
Action: abci.TxRecord_ADDED,
|
|
||||||
Tx: []byte{1, 2, 3, 4, 5},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Action: abci.TxRecord_ADDED,
|
|
||||||
Tx: []byte{100},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Action: abci.TxRecord_ADDED,
|
|
||||||
Tx: []byte{1, 2, 3, 4, 5},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Action: abci.TxRecord_ADDED,
|
|
||||||
Tx: []byte{200},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
err := rpp.Validate(100, [][]byte{})
|
|
||||||
require.Error(t, err)
|
|
||||||
})
|
|
||||||
t.Run("should error on duplicate transactions with mixed actions", func(t *testing.T) {
|
|
||||||
rpp := &abci.ResponsePrepareProposal{
|
|
||||||
ModifiedTx: true,
|
|
||||||
TxRecords: []*abci.TxRecord{
|
|
||||||
{
|
|
||||||
Action: abci.TxRecord_ADDED,
|
|
||||||
Tx: []byte{1, 2, 3, 4, 5},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Action: abci.TxRecord_ADDED,
|
|
||||||
Tx: []byte{100},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Action: abci.TxRecord_REMOVED,
|
|
||||||
Tx: []byte{1, 2, 3, 4, 5},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Action: abci.TxRecord_ADDED,
|
|
||||||
Tx: []byte{200},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
err := rpp.Validate(100, [][]byte{})
|
|
||||||
require.Error(t, err)
|
|
||||||
})
|
|
||||||
t.Run("should error on new transactions marked UNMODIFIED", func(t *testing.T) {
|
|
||||||
rpp := &abci.ResponsePrepareProposal{
|
|
||||||
ModifiedTx: true,
|
|
||||||
TxRecords: []*abci.TxRecord{
|
|
||||||
{
|
|
||||||
Action: abci.TxRecord_UNMODIFIED,
|
|
||||||
Tx: []byte{1, 2, 3, 4, 5},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
err := rpp.Validate(100, [][]byte{})
|
|
||||||
fmt.Println(err)
|
|
||||||
require.Error(t, err)
|
|
||||||
})
|
|
||||||
t.Run("should error on new transactions marked REMOVED", func(t *testing.T) {
|
|
||||||
rpp := &abci.ResponsePrepareProposal{
|
|
||||||
ModifiedTx: true,
|
|
||||||
TxRecords: []*abci.TxRecord{
|
|
||||||
{
|
|
||||||
Action: abci.TxRecord_REMOVED,
|
|
||||||
Tx: []byte{1, 2, 3, 4, 5},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
err := rpp.Validate(100, [][]byte{})
|
|
||||||
fmt.Println(err)
|
|
||||||
require.Error(t, err)
|
|
||||||
})
|
|
||||||
t.Run("should error on existing transaction marked as ADDED", func(t *testing.T) {
|
|
||||||
rpp := &abci.ResponsePrepareProposal{
|
|
||||||
ModifiedTx: true,
|
|
||||||
TxRecords: []*abci.TxRecord{
|
|
||||||
{
|
|
||||||
Action: abci.TxRecord_ADDED,
|
|
||||||
Tx: []byte{1, 2, 3, 4, 5},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
err := rpp.Validate(100, [][]byte{{1, 2, 3, 4, 5}})
|
|
||||||
require.Error(t, err)
|
|
||||||
})
|
|
||||||
t.Run("should error if any transaction marked as UNKNOWN", func(t *testing.T) {
|
|
||||||
rpp := &abci.ResponsePrepareProposal{
|
|
||||||
ModifiedTx: true,
|
|
||||||
TxRecords: []*abci.TxRecord{
|
|
||||||
{
|
|
||||||
Action: abci.TxRecord_UNKNOWN,
|
|
||||||
Tx: []byte{1, 2, 3, 4, 5},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
err := rpp.Validate(100, [][]byte{})
|
|
||||||
require.Error(t, err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user