Skip to content

Commit e69417a

Browse files
committed
implement Clone methods for Beef and MerklePath types
1 parent d655473 commit e69417a

File tree

2 files changed

+64
-3
lines changed

2 files changed

+64
-3
lines changed

transaction/beef.go

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,15 +1138,67 @@ txLoop:
11381138
return log
11391139
}
11401140

1141+
// Clone creates a deep copy of the Beef object.
1142+
// All nested structures are copied, so modifications to the clone
1143+
// will not affect the original.
11411144
func (b *Beef) Clone() *Beef {
11421145
c := &Beef{
11431146
Version: b.Version,
1144-
BUMPs: append([]*MerklePath(nil), b.BUMPs...),
1147+
BUMPs: make([]*MerklePath, len(b.BUMPs)),
11451148
Transactions: make(map[chainhash.Hash]*BeefTx, len(b.Transactions)),
11461149
}
1147-
for k, v := range b.Transactions {
1148-
c.Transactions[k] = v
1150+
1151+
// Deep clone BUMPs
1152+
for i, mp := range b.BUMPs {
1153+
c.BUMPs[i] = mp.Clone()
11491154
}
1155+
1156+
// First pass: ShallowClone all Transactions
1157+
for txid, beefTx := range b.Transactions {
1158+
cloned := &BeefTx{
1159+
DataFormat: beefTx.DataFormat,
1160+
BumpIndex: beefTx.BumpIndex,
1161+
}
1162+
1163+
if beefTx.KnownTxID != nil {
1164+
id := *beefTx.KnownTxID
1165+
cloned.KnownTxID = &id
1166+
}
1167+
1168+
if beefTx.InputTxids != nil {
1169+
cloned.InputTxids = make([]*chainhash.Hash, len(beefTx.InputTxids))
1170+
for i, inputTxid := range beefTx.InputTxids {
1171+
if inputTxid != nil {
1172+
id := *inputTxid
1173+
cloned.InputTxids[i] = &id
1174+
}
1175+
}
1176+
}
1177+
1178+
if beefTx.Transaction != nil {
1179+
cloned.Transaction = beefTx.Transaction.ShallowClone()
1180+
// Link to cloned BUMP
1181+
if beefTx.DataFormat == RawTxAndBumpIndex && beefTx.BumpIndex >= 0 && beefTx.BumpIndex < len(c.BUMPs) {
1182+
cloned.Transaction.MerklePath = c.BUMPs[beefTx.BumpIndex]
1183+
}
1184+
}
1185+
1186+
c.Transactions[txid] = cloned
1187+
}
1188+
1189+
// Second pass: wire up SourceTransaction references
1190+
for _, beefTx := range c.Transactions {
1191+
if beefTx.Transaction != nil {
1192+
for _, input := range beefTx.Transaction.Inputs {
1193+
if input.SourceTXID != nil {
1194+
if sourceBeefTx, ok := c.Transactions[*input.SourceTXID]; ok && sourceBeefTx.Transaction != nil {
1195+
input.SourceTransaction = sourceBeefTx.Transaction
1196+
}
1197+
}
1198+
}
1199+
}
1200+
}
1201+
11501202
return c
11511203
}
11521204

transaction/merklepath.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ func (ip IndexedPath) GetOffsetLeaf(layer int, offset uint64) *PathElement {
5555
return nil
5656
}
5757

58+
// Clone creates a deep copy of the MerklePath by serializing and deserializing.
59+
func (mp *MerklePath) Clone() *MerklePath {
60+
if mp == nil {
61+
return nil
62+
}
63+
clone, _ := NewMerklePathFromBinary(mp.Bytes())
64+
return clone
65+
}
66+
5867
// NewMerklePath creates a new MerklePath with the given block height and path
5968
func NewMerklePath(blockHeight uint32, path [][]*PathElement) *MerklePath {
6069
return &MerklePath{

0 commit comments

Comments
 (0)