blacklist.go raw

   1  package blockchain
   2  
   3  import (
   4  	"github.com/p9c/p9/pkg/btcaddr"
   5  	"github.com/p9c/p9/pkg/fork"
   6  	"github.com/p9c/p9/pkg/txscript"
   7  	"github.com/p9c/p9/pkg/util"
   8  )
   9  
  10  // ContainsBlacklisted returns true if one of the given addresses is found in the transaction
  11  func ContainsBlacklisted(b *BlockChain, tx *util.Tx, blacklist []btcaddr.Address) (hasBlacklisted bool) {
  12  	// in tests this function is not relevant
  13  	if b == nil {
  14  		return false
  15  	}
  16  	// blacklist only applies from hard fork
  17  	if fork.GetCurrent(b.BestSnapshot().Height) < 1 {
  18  		return false
  19  	}
  20  	var addrs []btcaddr.Address
  21  	// first decode transaction and collect all addresses in the transaction outputs
  22  	txo := tx.MsgTx().TxOut
  23  	for i := range txo {
  24  		script := txo[i].PkScript
  25  		_, a, _, _ := txscript.ExtractPkScriptAddrs(script, b.params)
  26  		addrs = append(addrs, a...)
  27  	}
  28  	// next get the addresses from the input transactions outpoints
  29  	txi := tx.MsgTx().TxIn
  30  	for i := range txi {
  31  		bb, e := b.BlockByHash(&txi[i].PreviousOutPoint.Hash)
  32  		if e == nil {
  33  			txs := bb.WireBlock().Transactions
  34  			for j := range txs {
  35  				txitxo := txs[j].TxOut
  36  				for k := range txitxo {
  37  					script := txitxo[k].PkScript
  38  					_, a, _, _ := txscript.ExtractPkScriptAddrs(script, b.params)
  39  					addrs = append(addrs, a...)
  40  				}
  41  			}
  42  		}
  43  	}
  44  	// check if the set of addresses intersects with the blacklist
  45  	return Intersects(addrs, blacklist)
  46  }
  47  
  48  // Intersects returns whether one slice of byte slices contains a match in another
  49  func Intersects(a, b []btcaddr.Address) bool {
  50  	for x := range a {
  51  		for y := range b {
  52  			if a[x].EncodeAddress() == b[y].EncodeAddress() {
  53  				// If we find one match the two arrays intersect
  54  				return true
  55  			}
  56  		}
  57  	}
  58  	return false
  59  }
  60