forked from stellar/go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathledger_transaction_reader_test.go
143 lines (125 loc) · 4.19 KB
/
ledger_transaction_reader_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package ingest
import (
"io"
"testing"
"github.com/stellar/go/keypair"
"github.com/stellar/go/network"
"github.com/stellar/go/support/collections/set"
"github.com/stellar/go/xdr"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
var (
passphrase = network.TestNetworkPassphrase
// Test prep:
// - two different envelopes which resolve to two different hashes
// - two basically-empty metas that contain the corresponding hashes
// - a ledger that has 5 txs with metas corresponding to these two envs
// - specifically, in the order [first, first, second, second, second]
//
// This tests both hash <--> envelope mapping and indexed iteration.
txEnvs, txHashes, txMetas = makeTransactions(5)
// barebones LCM structure so that the tx reader works w/o nil derefs, 5 txs
ledgerCloseMeta = xdr.LedgerCloseMeta{V: 1,
V1: &xdr.LedgerCloseMetaV1{
TxProcessing: txMetas,
TxSet: xdr.GeneralizedTransactionSet{V: 1,
V1TxSet: &xdr.TransactionSetV1{
Phases: []xdr.TransactionPhase{{V: 0,
V0Components: &[]xdr.TxSetComponent{{
TxsMaybeDiscountedFee: &xdr.TxSetComponentTxsMaybeDiscountedFee{
Txs: txEnvs,
}},
},
}},
},
},
},
}
)
func TestTransactionReader(t *testing.T) {
s := set.NewSet[xdr.Hash](5)
for _, hash := range txHashes {
s.Add(hash)
}
require.Lenf(t, s, len(txHashes), "precondition: hashes aren't unique, envs: %+v", txEnvs)
// simplest case: read from start
reader, err := NewLedgerTransactionReaderFromLedgerCloseMeta(passphrase, ledgerCloseMeta)
require.NoError(t, err)
for i := 0; i < 5; i++ {
tx, ierr := reader.Read()
require.NoError(t, ierr)
assert.EqualValues(t, i+1, tx.Index, "iteration i=%d", i)
thisHash, ierr := network.HashTransactionInEnvelope(tx.Envelope, passphrase)
require.NoError(t, ierr)
assert.Equal(t, txEnvs[tx.Index-1], tx.Envelope)
assert.Equal(t, txHashes[tx.Index-1], thisHash)
}
_, err = reader.Read()
require.ErrorIs(t, err, io.EOF)
// start reading from the middle set of txs
require.NoError(t, reader.Seek(2))
for i := 0; i < 3; i++ {
tx, ierr := reader.Read()
require.NoError(t, ierr)
assert.EqualValues(t,
/* txIndex is 1-based, iter is 0-based, start at 3rd tx, 5 total */
1+(i+2)%5,
tx.Index,
"iteration i=%d", i)
thisHash, ierr := network.HashTransactionInEnvelope(tx.Envelope, passphrase)
require.NoError(t, ierr)
assert.Equal(t, txEnvs[tx.Index-1], tx.Envelope)
assert.Equal(t, txHashes[tx.Index-1], thisHash)
}
_, err = reader.Read()
require.ErrorIs(t, err, io.EOF)
// edge case: start from the last tx
require.NoError(t, reader.Seek(4))
tx, ierr := reader.Read()
require.NoError(t, ierr)
assert.EqualValues(t, 5, tx.Index)
thisHash, ierr := network.HashTransactionInEnvelope(tx.Envelope, passphrase)
require.NoError(t, ierr)
assert.Equal(t, txEnvs[4], tx.Envelope)
assert.Equal(t, txHashes[4], thisHash)
_, err = reader.Read()
require.ErrorIs(t, err, io.EOF)
// error case: too far or too close
for _, idx := range []int{-1, 5, 6} {
rdr, err := NewLedgerTransactionReaderFromLedgerCloseMeta(passphrase, ledgerCloseMeta)
require.NoError(t, err)
require.Error(t, rdr.Seek(idx), "no error when trying seek=%d", idx)
}
}
func makeTransactions(count int) (
envs []xdr.TransactionEnvelope,
hashes [][32]byte,
metas []xdr.TransactionResultMeta,
) {
seqNum := 123_456
for i := 0; i < count; i++ {
txEnv := xdr.TransactionEnvelope{
Type: xdr.EnvelopeTypeEnvelopeTypeTx,
V1: &xdr.TransactionV1Envelope{
Tx: xdr.Transaction{
Ext: xdr.TransactionExt{V: 0},
SourceAccount: xdr.MustMuxedAddress(keypair.MustRandom().Address()),
Operations: []xdr.Operation{},
Fee: xdr.Uint32(seqNum + i),
SeqNum: xdr.SequenceNumber(seqNum + i),
},
Signatures: []xdr.DecoratedSignature{},
},
}
txHash, _ := network.HashTransactionInEnvelope(txEnv, passphrase)
txMeta := xdr.TransactionResultMeta{
Result: xdr.TransactionResultPair{TransactionHash: xdr.Hash(txHash)},
TxApplyProcessing: xdr.TransactionMeta{V: 3, V3: &xdr.TransactionMetaV3{}},
}
envs = append(envs, txEnv)
hashes = append(hashes, txHash)
metas = append(metas, txMeta)
}
return
}