@@ -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