func (a *Anchor) checkTxMalleation(transaction *btcutil.Tx, details *btcjson.BlockDetails) { anchorLog.Debug("in checkTxMalleation") dirBlockInfos := make([]interfaces.IDirBlockInfo, 0, len(a.dirBlockInfoSlice)) for _, v := range a.dirBlockInfoSlice { // find those already anchored but no call back yet if v.GetBTCBlockHeight() == 0 && bytes.Compare(v.GetBTCTxHash().Bytes(), primitives.NewZeroHash().Bytes()) != 0 { dirBlockInfos = append(dirBlockInfos, v) } } sort.Sort(util.ByDirBlockInfoTimestamp(dirBlockInfos)) anchorLog.Debugf("malleated tx candidate count=%d, dirBlockInfo list=%s\n", len(dirBlockInfos), spew.Sdump(dirBlockInfos)) for _, dirBlockInfo := range dirBlockInfos { tx, err := a.wclient.GetRawTransaction(toShaHash(dirBlockInfo.GetBTCTxHash())) if err != nil { anchorLog.Debugf(err.Error()) continue } anchorLog.Debugf("GetRawTransaction=%s, dirBlockInfo=%s\n", spew.Sdump(tx), spew.Sdump(dirBlockInfo)) // compare OP_RETURN if reflect.DeepEqual(transaction.MsgTx().TxOut[0], tx.MsgTx().TxOut[0]) { anchorLog.Debugf("Tx Malleated: original.txid=%s, malleated.txid=%s\n", dirBlockInfo.GetBTCTxHash().(*primitives.Hash).BTCString(), transaction.Sha().String()) a.doSaveDirBlockInfo(transaction, details, dirBlockInfo.(*dbInfo.DirBlockInfo), true) break } } }