mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-13 05:11:21 +00:00
Test Tx proofs secure
This commit is contained in:
105
types/tx_test.go
Normal file
105
types/tx_test.go
Normal file
@ -0,0 +1,105 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
cmn "github.com/tendermint/go-common"
|
||||
ctest "github.com/tendermint/go-common/test"
|
||||
wire "github.com/tendermint/go-wire"
|
||||
)
|
||||
|
||||
func makeTxs(cnt, size int) Txs {
|
||||
txs := make(Txs, cnt)
|
||||
for i := 0; i < cnt; i++ {
|
||||
txs[i] = cmn.RandBytes(size)
|
||||
}
|
||||
return txs
|
||||
}
|
||||
|
||||
func randInt(low, high int) int {
|
||||
off := cmn.RandInt() % (high - low)
|
||||
return low + off
|
||||
}
|
||||
|
||||
func TestValidTxProof(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
cases := []struct {
|
||||
txs Txs
|
||||
}{
|
||||
{Txs{{1, 4, 34, 87, 163, 1}}},
|
||||
{Txs{{5, 56, 165, 2}, {4, 77}}},
|
||||
{Txs{Tx("foo"), Tx("bar"), Tx("baz")}},
|
||||
{makeTxs(20, 5)},
|
||||
{makeTxs(7, 81)},
|
||||
{makeTxs(61, 15)},
|
||||
}
|
||||
|
||||
for h, tc := range cases {
|
||||
txs := tc.txs
|
||||
root := txs.Hash()
|
||||
// make sure valid proof for every tx
|
||||
for i := range txs {
|
||||
leaf := txs[i]
|
||||
leafHash := leaf.Hash()
|
||||
proof := txs.Proof(i)
|
||||
assert.Equal(i, proof.Index, "%d: %d", h, i)
|
||||
assert.Equal(len(txs), proof.Total, "%d: %d", h, i)
|
||||
assert.Equal(root, proof.RootHash, "%d: %d", h, i)
|
||||
assert.Equal(leaf, proof.Data, "%d: %d", h, i)
|
||||
assert.Equal(leafHash, proof.LeafHash(), "%d: %d", h, i)
|
||||
assert.Nil(proof.Validate(root), "%d: %d", h, i)
|
||||
assert.NotNil(proof.Validate([]byte("foobar")), "%d: %d", h, i)
|
||||
|
||||
// read-write must also work
|
||||
var p2 TxProof
|
||||
bin := wire.BinaryBytes(proof)
|
||||
err := wire.ReadBinaryBytes(bin, &p2)
|
||||
if assert.Nil(err, "%d: %d: %+v", h, i, err) {
|
||||
assert.Nil(p2.Validate(root), "%d: %d", h, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTxProofUnchangable(t *testing.T) {
|
||||
// run the other test a bunch...
|
||||
for i := 0; i < 4; i++ {
|
||||
testTxProofUnchangable(t)
|
||||
}
|
||||
}
|
||||
|
||||
func testTxProofUnchangable(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
// make some proof
|
||||
txs := makeTxs(randInt(2, 100), randInt(16, 128))
|
||||
root := txs.Hash()
|
||||
i := randInt(0, len(txs)-1)
|
||||
proof := txs.Proof(i)
|
||||
|
||||
// make sure it is valid to start with
|
||||
assert.Nil(proof.Validate(root))
|
||||
bin := wire.BinaryBytes(proof)
|
||||
|
||||
// try mutating the data and make sure nothing breaks
|
||||
for j := 0; j < 50; j++ {
|
||||
bad := ctest.MutateByteSlice(bin)
|
||||
assertBadProof(t, root, bad)
|
||||
}
|
||||
}
|
||||
|
||||
// this make sure the proof doesn't deserialize into something valid
|
||||
func assertBadProof(t *testing.T, root []byte, bad []byte) {
|
||||
// we kind of expect this to panic sometimes... (bad, go-wire, bad)
|
||||
defer func() {
|
||||
recover()
|
||||
}()
|
||||
|
||||
var proof TxProof
|
||||
err := wire.ReadBinaryBytes(bad, &proof)
|
||||
if err == nil {
|
||||
err = proof.Validate(root)
|
||||
assert.NotNil(t, err, "%+v", err)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user