@@ -111,6 +111,86 @@ func (s *Data) Serialize() ([]byte, error) {
111111 return buf .Bytes (), nil
112112}
113113
114+ // WriteTransactionsToWriter writes a range of transactions directly to a writer.
115+ //
116+ // This enables memory-efficient serialization by streaming transactions to disk as they are loaded,
117+ // without requiring all transactions to be in memory simultaneously. Transactions in the specified
118+ // range are written sequentially, skipping any nil entries.
119+ //
120+ // Parameters:
121+ // - w: Writer to stream transactions to
122+ // - startIdx: Starting index (inclusive) of transactions to write
123+ // - endIdx: Ending index (exclusive) of transactions to write
124+ //
125+ // Returns an error if writing fails or if required transactions are missing (nil).
126+ func (s * Data ) WriteTransactionsToWriter (w io.Writer , startIdx , endIdx int ) error {
127+ if s .Subtree == nil {
128+ return ErrCannotSerializeSubtreeNotSet
129+ }
130+
131+ for i := startIdx ; i < endIdx ; i ++ {
132+ // Skip coinbase placeholder if it's the first transaction
133+ if i == 0 && s .Subtree .Nodes [0 ].Hash .Equal (* CoinbasePlaceholderHash ) {
134+ continue
135+ }
136+
137+ if s .Txs [i ] == nil {
138+ return fmt .Errorf ("transaction at index %d is nil, cannot serialize" , i )
139+ }
140+
141+ // Serialize and stream transaction bytes to writer
142+ txBytes := s .Txs [i ].SerializeBytes ()
143+ if _ , err := w .Write (txBytes ); err != nil {
144+ return fmt .Errorf ("error writing transaction at index %d: %w" , i , err )
145+ }
146+ }
147+
148+ return nil
149+ }
150+
151+ // ReadTransactionsFromReader reads a range of transactions from a reader.
152+ //
153+ // This enables memory-efficient deserialization by reading only a chunk of transactions
154+ // from disk at a time, rather than loading all transactions into memory.
155+ //
156+ // Parameters:
157+ // - r: Reader to read transactions from
158+ // - startIdx: Starting index (inclusive) where transactions should be stored
159+ // - endIdx: Ending index (exclusive) where transactions should be stored
160+ //
161+ // Returns the number of transactions read and any error encountered.
162+ func (s * Data ) ReadTransactionsFromReader (r io.Reader , startIdx , endIdx int ) (int , error ) {
163+ if s .Subtree == nil || len (s .Subtree .Nodes ) == 0 {
164+ return 0 , ErrSubtreeNodesEmpty
165+ }
166+
167+ txsRead := 0
168+ for i := startIdx ; i < endIdx ; i ++ {
169+ // Skip coinbase placeholder
170+ if i == 0 && s .Subtree .Nodes [0 ].Hash .Equal (CoinbasePlaceholderHashValue ) {
171+ continue
172+ }
173+
174+ tx := & bt.Tx {}
175+ if _ , err := tx .ReadFrom (r ); err != nil {
176+ if errors .Is (err , io .EOF ) {
177+ break
178+ }
179+ return txsRead , fmt .Errorf ("error reading transaction at index %d: %w" , i , err )
180+ }
181+
182+ // Validate tx hash matches expected
183+ if ! s .Subtree .Nodes [i ].Hash .Equal (* tx .TxIDChainHash ()) {
184+ return txsRead , ErrTxHashMismatch
185+ }
186+
187+ s .Txs [i ] = tx
188+ txsRead ++
189+ }
190+
191+ return txsRead , nil
192+ }
193+
114194// serializeFromReader reads transactions from the provided reader and populates the Txs field.
115195func (s * Data ) serializeFromReader (buf io.Reader ) error {
116196 var (
0 commit comments