github.com/intfoundation/intchain@v0.0.0-20220727031208-4316ad31ca73/consensus/ipbft/types/tx_test.go (about) 1 package types 2 3 import ( 4 "bytes" 5 "testing" 6 7 "github.com/stretchr/testify/assert" 8 cmn "github.com/intfoundation/go-common" 9 ctest "github.com/intfoundation/go-common/test" 10 wire "github.com/intfoundation/go-wire" 11 ) 12 13 func makeTxs(cnt, size int) Txs { 14 txs := make(Txs, cnt) 15 for i := 0; i < cnt; i++ { 16 txs[i] = cmn.RandBytes(size) 17 } 18 return txs 19 } 20 21 func randInt(low, high int) int { 22 off := cmn.RandInt() % (high - low) 23 return low + off 24 } 25 26 func TestTxIndex(t *testing.T) { 27 assert := assert.New(t) 28 for i := 0; i < 20; i++ { 29 txs := makeTxs(15, 60) 30 for j := 0; j < len(txs); j++ { 31 tx := txs[j] 32 idx := txs.Index(tx) 33 assert.Equal(j, idx) 34 } 35 assert.Equal(-1, txs.Index(nil)) 36 assert.Equal(-1, txs.Index(Tx("foodnwkf"))) 37 } 38 } 39 40 func TestValidTxProof(t *testing.T) { 41 assert := assert.New(t) 42 cases := []struct { 43 txs Txs 44 }{ 45 {Txs{{1, 4, 34, 87, 163, 1}}}, 46 {Txs{{5, 56, 165, 2}, {4, 77}}}, 47 {Txs{Tx("foo"), Tx("bar"), Tx("baz")}}, 48 {makeTxs(20, 5)}, 49 {makeTxs(7, 81)}, 50 {makeTxs(61, 15)}, 51 } 52 53 for h, tc := range cases { 54 txs := tc.txs 55 root := txs.Hash() 56 // make sure valid proof for every tx 57 for i := range txs { 58 leaf := txs[i] 59 leafHash := leaf.Hash() 60 proof := txs.Proof(i) 61 assert.Equal(i, proof.Index, "%d: %d", h, i) 62 assert.Equal(len(txs), proof.Total, "%d: %d", h, i) 63 assert.Equal(root, proof.RootHash, "%d: %d", h, i) 64 assert.Equal(leaf, proof.Data, "%d: %d", h, i) 65 assert.Equal(leafHash, proof.LeafHash(), "%d: %d", h, i) 66 assert.Nil(proof.Validate(root), "%d: %d", h, i) 67 assert.NotNil(proof.Validate([]byte("foobar")), "%d: %d", h, i) 68 69 // read-write must also work 70 var p2 TxProof 71 bin := wire.BinaryBytes(proof) 72 err := wire.ReadBinaryBytes(bin, &p2) 73 if assert.Nil(err, "%d: %d: %+v", h, i, err) { 74 assert.Nil(p2.Validate(root), "%d: %d", h, i) 75 } 76 } 77 } 78 } 79 80 func TestTxProofUnchangable(t *testing.T) { 81 // run the other test a bunch... 82 for i := 0; i < 40; i++ { 83 testTxProofUnchangable(t) 84 } 85 } 86 87 func testTxProofUnchangable(t *testing.T) { 88 assert := assert.New(t) 89 90 // make some proof 91 txs := makeTxs(randInt(2, 100), randInt(16, 128)) 92 root := txs.Hash() 93 i := randInt(0, len(txs)-1) 94 proof := txs.Proof(i) 95 96 // make sure it is valid to start with 97 assert.Nil(proof.Validate(root)) 98 bin := wire.BinaryBytes(proof) 99 100 // try mutating the data and make sure nothing breaks 101 for j := 0; j < 500; j++ { 102 bad := ctest.MutateByteSlice(bin) 103 if !bytes.Equal(bad, bin) { 104 assertBadProof(t, root, bad, proof) 105 } 106 } 107 } 108 109 // this make sure the proof doesn't deserialize into something valid 110 func assertBadProof(t *testing.T, root []byte, bad []byte, good TxProof) { 111 var proof TxProof 112 err := wire.ReadBinaryBytes(bad, &proof) 113 if err == nil { 114 err = proof.Validate(root) 115 if err == nil { 116 // okay, this can happen if we have a slightly different total 117 // (where the path ends up the same), if it is something else, we have 118 // a real problem 119 assert.NotEqual(t, proof.Total, good.Total, "bad: %#v\ngood: %#v", proof, good) 120 } 121 } 122 }