diff --git a/bchain/mempool_bitcoin_type.go b/bchain/mempool_bitcoin_type.go index a45e998f..32a20b9d 100644 --- a/bchain/mempool_bitcoin_type.go +++ b/bchain/mempool_bitcoin_type.go @@ -133,11 +133,16 @@ func isTaproot(addrDesc AddressDescriptor) bool { } func (m *MempoolBitcoinType) computeGolombFilter(mtx *MempoolTx) string { + uniqueScripts := make(map[string]struct{}) filterData := make([][]byte, 0) for i := range mtx.Vin { vin := &mtx.Vin[i] if m.filterScripts == filterScriptsAll || (m.filterScripts == filterScriptsTaproot && isTaproot(vin.AddrDesc)) { - filterData = append(filterData, vin.AddrDesc) + s := string(vin.AddrDesc) + if _, found := uniqueScripts[s]; !found { + filterData = append(filterData, vin.AddrDesc) + uniqueScripts[s] = struct{}{} + } } } for i := range mtx.Vout { @@ -145,7 +150,11 @@ func (m *MempoolBitcoinType) computeGolombFilter(mtx *MempoolTx) string { b, err := hex.DecodeString(vout.ScriptPubKey.Hex) if err == nil { if m.filterScripts == filterScriptsAll || (m.filterScripts == filterScriptsTaproot && isTaproot(b)) { - filterData = append(filterData, b) + s := string(b) + if _, found := uniqueScripts[s]; !found { + filterData = append(filterData, b) + uniqueScripts[s] = struct{}{} + } } } } diff --git a/bchain/mempool_bitcoin_type_test.go b/bchain/mempool_bitcoin_type_test.go index 81a9c58a..f6b799cc 100644 --- a/bchain/mempool_bitcoin_type_test.go +++ b/bchain/mempool_bitcoin_type_test.go @@ -102,6 +102,49 @@ func TestMempoolBitcoinType_computeGolombFilter_taproot(t *testing.T) { }, want: "071143e4ad12730965a5247ac15db8c81c89b0bc", }, + { + name: "taproot duplicities", + mtx: MempoolTx{ + Txid: "33a03f983b47725bbdd6045f2d5ee0d95dce08eaaf7104759758aabd8af27d34", + Vin: []MempoolVin{ + { + // bc1px2k5tu5mfq23ekkwncz5apx6ccw2nr0rne25r8t8zk7nu035ryxqn9ge8p + AddrDesc: hexToBytes("512032ad45f29b48151cdace9e054e84dac61ca98de39e55419d6715bd3e3e34190c"), + }, + { + // bc1px2k5tu5mfq23ekkwncz5apx6ccw2nr0rne25r8t8zk7nu035ryxqn9ge8p + AddrDesc: hexToBytes("512032ad45f29b48151cdace9e054e84dac61ca98de39e55419d6715bd3e3e34190c"), + }, + }, + Vout: []Vout{ + { + ScriptPubKey: ScriptPubKey{ + Hex: "512032ad45f29b48151cdace9e054e84dac61ca98de39e55419d6715bd3e3e34190c", + Addresses: []string{ + "bc1px2k5tu5mfq23ekkwncz5apx6ccw2nr0rne25r8t8zk7nu035ryxqn9ge8p", + }, + }, + }, + { + ScriptPubKey: ScriptPubKey{ + Hex: "512032ad45f29b48151cdace9e054e84dac61ca98de39e55419d6715bd3e3e34190c", + Addresses: []string{ + "bc1px2k5tu5mfq23ekkwncz5apx6ccw2nr0rne25r8t8zk7nu035ryxqn9ge8p", + }, + }, + }, + { + ScriptPubKey: ScriptPubKey{ + Hex: "512032ad45f29b48151cdace9e054e84dac61ca98de39e55419d6715bd3e3e34190c", + Addresses: []string{ + "bc1px2k5tu5mfq23ekkwncz5apx6ccw2nr0rne25r8t8zk7nu035ryxqn9ge8p", + }, + }, + }, + }, + }, + want: "01778db0", + }, { name: "partial taproot", mtx: MempoolTx{