@@ -12,11 +12,13 @@ import (
1212 "github.com/bsv-blockchain/go-bt/v2/chainhash"
1313)
1414
15+ // Inpoint represents an input point in a transaction, consisting of a parent transaction hash and an index.
1516type Inpoint struct {
1617 Hash chainhash.Hash
1718 Index uint32
1819}
1920
21+ // TxInpoints represents a collection of transaction inpoints, which are the parent transaction hashes and their corresponding indexes.
2022type TxInpoints struct {
2123 ParentTxHashes []chainhash.Hash
2224 Idxs [][]uint32
@@ -25,20 +27,23 @@ type TxInpoints struct {
2527 nrInpoints int
2628}
2729
30+ // NewTxInpoints creates a new TxInpoints object with initialized slices for parent transaction hashes and indexes.
2831func NewTxInpoints () TxInpoints {
2932 return TxInpoints {
30- ParentTxHashes : make ([]chainhash.Hash , 0 , 8 ), // initial capacity of 8, can grow as needed
31- Idxs : make ([][]uint32 , 0 , 16 ), // initial capacity of 16, can grow as needed
33+ ParentTxHashes : make ([]chainhash.Hash , 0 , 8 ), // initial capacity of 8 can grow as needed
34+ Idxs : make ([][]uint32 , 0 , 16 ), // the initial capacity of 16 can grow as needed
3235 }
3336}
3437
38+ // NewTxInpointsFromTx creates a new TxInpoints object from a given transaction.
3539func NewTxInpointsFromTx (tx * bt.Tx ) (TxInpoints , error ) {
3640 p := NewTxInpoints ()
3741 p .addTx (tx )
3842
3943 return p , nil
4044}
4145
46+ // NewTxInpointsFromInputs creates a new TxInpoints object from a slice of transaction inputs.
4247func NewTxInpointsFromInputs (inputs []* bt.Input ) (TxInpoints , error ) {
4348 p := TxInpoints {}
4449
@@ -50,6 +55,7 @@ func NewTxInpointsFromInputs(inputs []*bt.Input) (TxInpoints, error) {
5055 return p , nil
5156}
5257
58+ // NewTxInpointsFromBytes creates a new TxInpoints object from a byte slice.
5359func NewTxInpointsFromBytes (data []byte ) (TxInpoints , error ) {
5460 p := TxInpoints {}
5561
@@ -60,6 +66,7 @@ func NewTxInpointsFromBytes(data []byte) (TxInpoints, error) {
6066 return p , nil
6167}
6268
69+ // NewTxInpointsFromReader creates a new TxInpoints object from an io.Reader.
6370func NewTxInpointsFromReader (buf io.Reader ) (TxInpoints , error ) {
6471 p := TxInpoints {}
6572
@@ -70,32 +77,17 @@ func NewTxInpointsFromReader(buf io.Reader) (TxInpoints, error) {
7077 return p , nil
7178}
7279
80+ // String returns a string representation of the TxInpoints object.
7381func (p * TxInpoints ) String () string {
7482 return fmt .Sprintf ("TxInpoints{ParentTxHashes: %v, Idxs: %v}" , p .ParentTxHashes , p .Idxs )
7583}
7684
77- func (p * TxInpoints ) addTx (tx * bt.Tx ) {
78- // Do not error out for transactions without inputs, seeded Teranodes will have txs without inputs
79- for _ , input := range tx .Inputs {
80- hash := * input .PreviousTxIDChainHash ()
81-
82- index := slices .Index (p .ParentTxHashes , hash )
83- if index != - 1 {
84- p .Idxs [index ] = append (p .Idxs [index ], input .PreviousTxOutIndex )
85- } else {
86- p .ParentTxHashes = append (p .ParentTxHashes , hash )
87- p .Idxs = append (p .Idxs , []uint32 {input .PreviousTxOutIndex })
88- }
89-
90- p .nrInpoints ++
91- }
92- }
93-
9485// GetParentTxHashes returns the unique parent tx hashes
9586func (p * TxInpoints ) GetParentTxHashes () []chainhash.Hash {
9687 return p .ParentTxHashes
9788}
9889
90+ // GetParentTxHashAtIndex returns the parent transaction hash at the specified index.
9991func (p * TxInpoints ) GetParentTxHashAtIndex (index int ) (chainhash.Hash , error ) {
10092 if index >= len (p .ParentTxHashes ) {
10193 return chainhash.Hash {}, fmt .Errorf ("index out of range" )
@@ -120,6 +112,7 @@ func (p *TxInpoints) GetTxInpoints() []Inpoint {
120112 return inpoints
121113}
122114
115+ // GetParentVoutsAtIndex returns the parent transaction output indexes at the specified index.
123116func (p * TxInpoints ) GetParentVoutsAtIndex (index int ) ([]uint32 , error ) {
124117 if index >= len (p .ParentTxHashes ) {
125118 return nil , fmt .Errorf ("index out of range" )
@@ -128,6 +121,7 @@ func (p *TxInpoints) GetParentVoutsAtIndex(index int) ([]uint32, error) {
128121 return p .Idxs [index ], nil
129122}
130123
124+ // Serialize serializes the TxInpoints object into a byte slice.
131125func (p * TxInpoints ) Serialize () ([]byte , error ) {
132126 if len (p .ParentTxHashes ) != len (p .Idxs ) {
133127 return nil , fmt .Errorf ("parent tx hashes and indexes length mismatch" )
@@ -144,13 +138,13 @@ func (p *TxInpoints) Serialize() ([]byte, error) {
144138 binary .LittleEndian .PutUint32 (bytesUint32 [:], len32 (p .ParentTxHashes ))
145139
146140 if _ , err = buf .Write (bytesUint32 [:]); err != nil {
147- return nil , fmt .Errorf ("unable to write number of parent inpoints: %s " , err )
141+ return nil , fmt .Errorf ("unable to write number of parent inpoints: %w " , err )
148142 }
149143
150144 // write the parent tx hashes
151145 for _ , hash := range p .ParentTxHashes {
152146 if _ , err = buf .Write (hash [:]); err != nil {
153- return nil , fmt .Errorf ("unable to write parent tx hash: %s " , err )
147+ return nil , fmt .Errorf ("unable to write parent tx hash: %w " , err )
154148 }
155149 }
156150
@@ -159,27 +153,46 @@ func (p *TxInpoints) Serialize() ([]byte, error) {
159153 binary .LittleEndian .PutUint32 (bytesUint32 [:], len32 (indexes ))
160154
161155 if _ , err = buf .Write (bytesUint32 [:]); err != nil {
162- return nil , fmt .Errorf ("unable to write number of parent indexes: %s " , err )
156+ return nil , fmt .Errorf ("unable to write number of parent indexes: %w " , err )
163157 }
164158
165159 for _ , idx := range indexes {
166160 binary .LittleEndian .PutUint32 (bytesUint32 [:], idx )
167161
168162 if _ , err = buf .Write (bytesUint32 [:]); err != nil {
169- return nil , fmt .Errorf ("unable to write parent index: %s " , err )
163+ return nil , fmt .Errorf ("unable to write parent index: %w " , err )
170164 }
171165 }
172166 }
173167
174168 return buf .Bytes (), nil
175169}
176170
171+ // addTx adds a transaction to the TxInpoints object, extracting its inputs and updating the parent transaction hashes and indexes.
172+ func (p * TxInpoints ) addTx (tx * bt.Tx ) {
173+ // Do not error out for transactions without inputs, seeded Teranodes will have txs without inputs
174+ for _ , input := range tx .Inputs {
175+ hash := * input .PreviousTxIDChainHash ()
176+
177+ index := slices .Index (p .ParentTxHashes , hash )
178+ if index != - 1 {
179+ p .Idxs [index ] = append (p .Idxs [index ], input .PreviousTxOutIndex )
180+ } else {
181+ p .ParentTxHashes = append (p .ParentTxHashes , hash )
182+ p .Idxs = append (p .Idxs , []uint32 {input .PreviousTxOutIndex })
183+ }
184+
185+ p .nrInpoints ++
186+ }
187+ }
188+
189+ // deserializeFromReader reads the TxInpoints data from the provided reader and populates the TxInpoints object.
177190func (p * TxInpoints ) deserializeFromReader (buf io.Reader ) error {
178191 // read the number of parent inpoints
179192 var bytesUint32 [4 ]byte
180193
181194 if _ , err := io .ReadFull (buf , bytesUint32 [:]); err != nil {
182- return fmt .Errorf ("unable to read number of parent inpoints: %s " , err )
195+ return fmt .Errorf ("unable to read number of parent inpoints: %w " , err )
183196 }
184197
185198 totalInpointsLen := binary .LittleEndian .Uint32 (bytesUint32 [:])
@@ -197,14 +210,14 @@ func (p *TxInpoints) deserializeFromReader(buf io.Reader) error {
197210 // read the parent tx hash
198211 for i := uint32 (0 ); i < totalInpointsLen ; i ++ {
199212 if _ , err := io .ReadFull (buf , p .ParentTxHashes [i ][:]); err != nil {
200- return fmt .Errorf ("unable to read parent tx hash: %s " , err )
213+ return fmt .Errorf ("unable to read parent tx hash: %w " , err )
201214 }
202215 }
203216
204217 // read the number of parent indexes
205218 for i := uint32 (0 ); i < totalInpointsLen ; i ++ {
206219 if _ , err := io .ReadFull (buf , bytesUint32 [:]); err != nil {
207- return fmt .Errorf ("unable to read number of parent indexes: %s " , err )
220+ return fmt .Errorf ("unable to read number of parent indexes: %w " , err )
208221 }
209222
210223 parentIndexesLen := binary .LittleEndian .Uint32 (bytesUint32 [:])
@@ -214,7 +227,7 @@ func (p *TxInpoints) deserializeFromReader(buf io.Reader) error {
214227
215228 for j := uint32 (0 ); j < parentIndexesLen ; j ++ {
216229 if _ , err := io .ReadFull (buf , bytesUint32 [:]); err != nil {
217- return fmt .Errorf ("unable to read parent index: %s " , err )
230+ return fmt .Errorf ("unable to read parent index: %w " , err )
218231 }
219232
220233 p.Idxs [i ][j ] = binary .LittleEndian .Uint32 (bytesUint32 [:])
0 commit comments