github.com/piotrnar/gocoin@v0.0.0-20240512203912-faa0448c5e96/client/usif/textui/consensus/consensus_windows.go (about) 1 // +build windows 2 3 // On Windows OS copy this file to gocoin\client\usif\textui to enable consensus checking 4 // Make sure you have proper "libbitcoinconsensus-0.dll" in a folder where OS can find it. 5 6 package textui 7 8 import ( 9 "encoding/hex" 10 "fmt" 11 "github.com/piotrnar/gocoin/client/common" 12 "github.com/piotrnar/gocoin/lib/btc" 13 "github.com/piotrnar/gocoin/lib/script" 14 "sync" 15 "sync/atomic" 16 "syscall" 17 "unsafe" 18 ) 19 20 const ( 21 DllName = "libbitcoinconsensus-0.dll" 22 ) 23 24 /* 25 EXPORT_SYMBOL int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, 26 const unsigned char *txTo , unsigned int txToLen, 27 unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err); 28 29 EXPORT_SYMBOL int bitcoinconsensus_verify_script_with_amount(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, int64_t amount, 30 const unsigned char *txTo , unsigned int txToLen, 31 unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err); 32 33 EXPORT_SYMBOL unsigned int bitcoinconsensus_version(); 34 } 35 */ 36 37 var ( 38 bitcoinconsensus_verify_script_with_amount *syscall.Proc 39 bitcoinconsensus_version *syscall.Proc 40 41 ConsensusChecks uint64 42 ConsensusExpErr uint64 43 ConsensusErrors uint64 44 45 mut sync.Mutex 46 ) 47 48 func check_consensus(pkScr []byte, amount uint64, i int, tx *btc.Tx, ver_flags uint32, result bool) { 49 var tmp []byte 50 if len(pkScr) != 0 { 51 tmp = make([]byte, len(pkScr)) 52 copy(tmp, pkScr) 53 } 54 tx_raw := tx.Raw 55 if tx_raw == nil { 56 tx_raw = tx.Serialize() 57 } 58 go func(pkScr []byte, txTo []byte, i int, ver_flags uint32, result bool) { 59 var pkscr_ptr, pkscr_len uintptr // default to 0/null 60 if pkScr != nil { 61 pkscr_ptr = uintptr(unsafe.Pointer(&pkScr[0])) 62 pkscr_len = uintptr(len(pkScr)) 63 } 64 r1, _, _ := syscall.Syscall9(bitcoinconsensus_verify_script_with_amount.Addr(), 8, 65 pkscr_ptr, pkscr_len, uintptr(amount), 66 uintptr(unsafe.Pointer(&txTo[0])), uintptr(len(txTo)), 67 uintptr(i), uintptr(ver_flags), 0, 0) 68 69 res := r1 == 1 70 atomic.AddUint64(&ConsensusChecks, 1) 71 if !result { 72 atomic.AddUint64(&ConsensusExpErr, 1) 73 } 74 if res != result { 75 atomic.AddUint64(&ConsensusErrors, 1) 76 common.CountSafe("TxConsensusERR") 77 mut.Lock() 78 println("Compare to consensus failed!") 79 println("Gocoin:", result, " ConsLIB:", res) 80 println("pkScr", hex.EncodeToString(pkScr)) 81 println("txTo", hex.EncodeToString(txTo)) 82 println("amount:", amount, " input_idx:", i, " ver_flags:", ver_flags) 83 println() 84 mut.Unlock() 85 } 86 }(tmp, tx_raw, i, ver_flags, result) 87 } 88 89 func verify_script_with_amount(pkScr []byte, amount uint64, i int, tx *btc.Tx, ver_flags uint32) (result bool) { 90 var pkscr_ptr, pkscr_len uintptr // default to 0/null 91 txTo := tx.Raw 92 if txTo == nil { 93 txTo = tx.Serialize() 94 } 95 if pkScr != nil { 96 pkscr_ptr = uintptr(unsafe.Pointer(&pkScr[0])) 97 pkscr_len = uintptr(len(pkScr)) 98 } 99 r1, _, _ := syscall.Syscall9(bitcoinconsensus_verify_script_with_amount.Addr(), 8, 100 pkscr_ptr, pkscr_len, uintptr(amount), 101 uintptr(unsafe.Pointer(&txTo[0])), uintptr(len(txTo)), 102 uintptr(i), uintptr(ver_flags), 0, 0) 103 104 result = (r1 == 1) 105 return 106 } 107 108 func consensus_stats(s string) { 109 fmt.Println("Consensus Checks:", atomic.LoadUint64(&ConsensusChecks)) 110 fmt.Println("Consensus ExpErr:", atomic.LoadUint64(&ConsensusExpErr)) 111 fmt.Println("Consensus Errors:", atomic.LoadUint64(&ConsensusErrors)) 112 } 113 114 func init() { 115 dll, er := syscall.LoadDLL(DllName) 116 if er != nil { 117 //common.Log.Println(er.Error()) 118 common.Log.Println("Not using", DllName, "to cross-check consensus rules") 119 return 120 } 121 bitcoinconsensus_verify_script_with_amount, er = dll.FindProc("bitcoinconsensus_verify_script_with_amount") 122 if er == nil { 123 bitcoinconsensus_version, er = dll.FindProc("bitcoinconsensus_version") 124 } 125 if er != nil { 126 common.Log.Println(er.Error()) 127 common.Log.Println(DllName, "is probably too old. Use one of bitcoin-core 0.13.1 or later") 128 common.Log.Println("WARNING: Consensus cross-checking disabled") 129 return 130 } 131 r1, _, _ := syscall.Syscall(bitcoinconsensus_version.Addr(), 0, 0, 0, 0) 132 common.Log.Println("Using", DllName, "version", r1, "to cross-check consensus rules") 133 script.VerifyConsensus = check_consensus 134 newUi("cons", false, consensus_stats, "See statistics of the consensus cross-checks") 135 }