Skip to content

Commit ee99359

Browse files
committed
simpler implementation
1 parent 7aedb5a commit ee99359

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

subtree_data.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,83 @@ func (s *Data) WriteTransactionsToWriter(w io.Writer, startIdx, endIdx int) erro
148148
return nil
149149
}
150150

151+
// WriteTransactionChunk writes a slice of transactions directly to a writer.
152+
//
153+
// This is a simplified streaming function that writes transactions without requiring a SubtreeData
154+
// structure. It's useful for workflows where transactions are already loaded and just need to be
155+
// streamed to disk.
156+
//
157+
// Parameters:
158+
// - w: Writer to stream transactions to
159+
// - txs: Slice of transactions to write
160+
//
161+
// Returns an error if writing fails.
162+
func WriteTransactionChunk(w io.Writer, txs []*bt.Tx) error {
163+
for _, tx := range txs {
164+
if tx == nil {
165+
continue // Skip nil transactions
166+
}
167+
168+
txBytes := tx.SerializeBytes()
169+
if _, err := w.Write(txBytes); err != nil {
170+
return fmt.Errorf("%w: %w", ErrTransactionWrite, err)
171+
}
172+
}
173+
174+
return nil
175+
}
176+
177+
// ReadTransactionChunk reads and validates a chunk of transactions from a reader.
178+
//
179+
// This is a simplified streaming function that reads transactions directly into a new slice,
180+
// validates them against the subtree structure, and returns the populated slice. This is more
181+
// memory-efficient than ReadTransactionsFromReader for processing workflows where the SubtreeData
182+
// array is not needed.
183+
//
184+
// Parameters:
185+
// - r: Reader to read transactions from
186+
// - subtree: Subtree structure for hash validation
187+
// - startIdx: Starting index in subtree for validation
188+
// - count: Number of transactions to read
189+
//
190+
// Returns a slice of transactions and any error encountered.
191+
func ReadTransactionChunk(r io.Reader, subtree *Subtree, startIdx, count int) ([]*bt.Tx, error) {
192+
if subtree == nil || len(subtree.Nodes) == 0 {
193+
return nil, ErrSubtreeNodesEmpty
194+
}
195+
196+
txs := make([]*bt.Tx, 0, count)
197+
198+
for i := 0; i < count; i++ {
199+
idx := startIdx + i
200+
if idx >= len(subtree.Nodes) {
201+
break // Reached end of subtree
202+
}
203+
204+
// Skip coinbase placeholder
205+
if idx == 0 && subtree.Nodes[0].Hash.Equal(CoinbasePlaceholderHashValue) {
206+
continue
207+
}
208+
209+
tx := &bt.Tx{}
210+
if _, err := tx.ReadFrom(r); err != nil {
211+
if errors.Is(err, io.EOF) {
212+
break
213+
}
214+
return txs, fmt.Errorf("%w at index %d: %w", ErrTransactionRead, idx, err)
215+
}
216+
217+
// Validate tx hash matches expected
218+
if !subtree.Nodes[idx].Hash.Equal(*tx.TxIDChainHash()) {
219+
return txs, ErrTxHashMismatch
220+
}
221+
222+
txs = append(txs, tx)
223+
}
224+
225+
return txs, nil
226+
}
227+
151228
// ReadTransactionsFromReader reads a range of transactions from a reader.
152229
//
153230
// This enables memory-efficient deserialization by reading only a chunk of transactions

0 commit comments

Comments
 (0)