github.com/deso-protocol/core@v1.2.9/scripts/mempool/mempool_dumper.go (about) 1 package main 2 3 import ( 4 "bufio" 5 "encoding/hex" 6 "flag" 7 "fmt" 8 "github.com/btcsuite/btcd/addrmgr" 9 "log" 10 "net" 11 "os" 12 "strings" 13 "time" 14 15 "github.com/davecgh/go-spew/spew" 16 "github.com/deso-protocol/core/lib" 17 "github.com/golang/glog" 18 ) 19 20 var ( 21 flagNode = flag.String( 22 "node", "", 23 "When dumping, should be pointed at a JSON API. E.g.: "+ 24 "https://api.bitclout.com. When loading, should "+ 25 "be pointed at a protocol port. E.g.: 127.0.0.1:17000") 26 27 flagCommand = flag.String( 28 "command", "", 29 "Must be dump or load. When dump is specified, txns "+ 30 "are downloaded from the JSON API node and raw txn hex "+ 31 "is printed. When load is specified, txns are read from "+ 32 "stdin and injected into the protocol node specified.") 33 34 flagDiffNode = flag.String( 35 "diff_node", "", 36 "A node to diff against. When set, "+ 37 "this should be a protocol port and --node must be a JSON port.") 38 ) 39 40 func main() { 41 flag.Parse() 42 43 // Set up logging. 44 log.Println("To log output on commandline, run with -alsologtostderr") 45 glog.CopyStandardLogTo("INFO") 46 47 if *flagNode == "" { 48 panic("--node is required and must be a " + 49 "JSON API when dumping or a protocol port when loading") 50 } 51 52 // Set up the to node as a peer 53 netAddrss, err := lib.IPToNetAddr(*flagNode, addrmgr.New("", net.LookupIP), &lib.DeSoMainnetParams) 54 if err != nil { 55 panic(err) 56 } 57 58 netAddr2 := net.TCPAddr{ 59 IP: netAddrss.IP, 60 Port: int(netAddrss.Port), 61 } 62 conn, err := net.DialTimeout(netAddr2.Network(), netAddr2.String(), lib.DeSoMainnetParams.DialTimeout) 63 if err != nil { 64 panic(err) 65 } 66 67 messagesFromPeer := make(chan *lib.ServerMessage) 68 peer := lib.NewPeer(conn, true, netAddrss, true, 69 10000, 0, &lib.DeSoMainnetParams, 70 messagesFromPeer, nil, nil) 71 time.Sleep(1 * time.Second) 72 if err := peer.NegotiateVersion(lib.DeSoMainnetParams.VersionNegotiationTimeout); err != nil { 73 panic(err) 74 } 75 76 // As a test, send a GetHeaders request and see if we get it back 77 if *flagCommand == "get_headers" { 78 time.Sleep(1 * time.Second) 79 peer.WriteDeSoMessage(&lib.MsgDeSoGetHeaders{ 80 StopHash: lib.MustDecodeHexBlockHash("0000000000000000000000000000000000000000000000000000000000000000"), 81 BlockLocator: []*lib.BlockHash{ 82 lib.MustDecodeHexBlockHash("0000000000f70d7a6dce5502eddb40772fc4b6b1e54e809b21bd38c6bd447e05"), 83 lib.MustDecodeHexBlockHash("0000000000c49db46a5ba1a9d35dfd870c791ea6b695c49e522fe9a7c0f308e8"), 84 lib.MustDecodeHexBlockHash("0000000000597c8ebfe3122c2aa003b6dc0fd67e97e6b4cae437517dd2f500a4"), 85 lib.MustDecodeHexBlockHash("0000000000da97c2b70bbd5af7d707ff7772ac7064e4946b1aebf5b863902723"), 86 lib.MustDecodeHexBlockHash("000000000083a5ef8c0df071362668f1b1bd764f02ef4aeebf25a9f54f721189"), 87 lib.MustDecodeHexBlockHash("0000000000f0636590f0d1a1d163edac52611269c56cf1601a27c182af2b7752"), 88 lib.MustDecodeHexBlockHash("0000000000fd9249bd4f89e12e74b3107e11694b1b5dadf61af08f1218943861"), 89 lib.MustDecodeHexBlockHash("00000000006ad067641de4bd55218fbf2b3b260054a2d8a1a2ca0843199f89ea"), 90 lib.MustDecodeHexBlockHash("0000000000e0f41c722d853639b1f9aefd7ac7613f249e6f71c41349b4e03ff3"), 91 lib.MustDecodeHexBlockHash("0000000000b0add5db4833d26406625925c5ef4d3097bbee67037723a3f8e391"), 92 lib.MustDecodeHexBlockHash("00000000001662747a5f03db9d6551a72250cc32747597b004bf95f328bae57e"), 93 lib.MustDecodeHexBlockHash("0000000000d6267bca36f88efa9e6947bbe36149d378fd9464e72db48dc22dca"), 94 lib.MustDecodeHexBlockHash("00000000006f422c0bd7f4154cb3a6173e2e7cf2fc10c63ca75c1aeeb9b1d563"), 95 lib.MustDecodeHexBlockHash("00000000007da3b19ddcf04c57b3c936ec1dcaa6c21214c33aa256afced22aca"), 96 lib.MustDecodeHexBlockHash("00000000003802f3a2fc4fa3775780d704486b65b9ed56b67f6d4c3335a7b9b5"), 97 lib.MustDecodeHexBlockHash("00000000009552ebd611e4f9d8c2cb4f08d8f17da2b739979604a2a0743d433d"), 98 lib.MustDecodeHexBlockHash("0000000000060c2df58fca53b083dc0b6879a49aa69e5c9c6d12ec7e6e8c8890"), 99 lib.MustDecodeHexBlockHash("0000000000032f0ab25daa56eab3000dda92ce52a128ca57e8cb17bb8c1e2ced"), 100 lib.MustDecodeHexBlockHash("00000000007b2444f17f8fcf216c52f32d4c0e374c4598957443c20209e7e39b"), 101 lib.MustDecodeHexBlockHash("00000000008df3db9dda88e1f2dada964e28e0c05030861eaf351a875cf154bb"), 102 lib.MustDecodeHexBlockHash("00000000006bff73eea66c748c089fe384b76fddf24b0830abad8343e2c53813"), 103 lib.MustDecodeHexBlockHash("0000000000830059a9eb948f3ed3996ff93efb642d09a71744327ceafe9e10ea"), 104 lib.MustDecodeHexBlockHash("0000000000a5da7ccb9a3e6824dedc31ed112cdd22cc2ca9d1e98992deb97225"), 105 lib.MustDecodeHexBlockHash("000000004a9facc6804cb39cdf5f1c2360dc372d4e532dccd5c3489671eacd29"), 106 lib.MustDecodeHexBlockHash("5567c45b7b83b604f9ff5cb5e88dfc9ad7d5a1dd5818dd19e6d02466f47cbd62"), 107 }, 108 }) 109 110 log.Println("Sent GetHeaders message. Waiting for response") 111 112 // There should be a single inv that comes back 113 for { 114 msg, err := peer.ReadDeSoMessage() 115 if err != nil { 116 panic(err) 117 } 118 fmt.Println(msg.GetMsgType()) 119 } 120 } else if *flagCommand == "dump" { 121 time.Sleep(1 * time.Second) 122 peer.WriteDeSoMessage(&lib.MsgDeSoMempool{}) 123 log.Println("Sent Mempool message. Waiting for big inv") 124 125 // There should be a single inv that comes back 126 for { 127 msg, err := peer.ReadDeSoMessage() 128 if err != nil { 129 panic(err) 130 } 131 if msg.GetMsgType() == lib.MsgTypeInv { 132 invMsg := msg.(*lib.MsgDeSoInv) 133 if len(invMsg.InvList) == 0 { 134 log.Println("Ignoringing empty INV") 135 continue 136 } 137 if invMsg.InvList[0].Type == lib.InvTypeBlock { 138 log.Println("Ignoring BLOCK INV") 139 continue 140 } 141 log.Println("Processing inv of size ", len(invMsg.InvList)) 142 hashesToRequest := []*lib.BlockHash{} 143 for _, inv := range invMsg.InvList { 144 if inv.Type == lib.InvTypeTx { 145 hashesToRequest = append(hashesToRequest, &inv.Hash) 146 } 147 } 148 149 // Now we have all the hashes, request the txn. 150 getTxns := &lib.MsgDeSoGetTransactions{} 151 getTxns.HashList = hashesToRequest 152 153 // Fetch all the txns back from the node 154 peer.WriteDeSoMessage(getTxns) 155 time.Sleep(100 * time.Millisecond) 156 157 } else if msg.GetMsgType() == lib.MsgTypeTransactionBundle { 158 txBundle := msg.(*lib.MsgDeSoTransactionBundle) 159 log.Println("Processing txn bundle of size ", len(txBundle.Transactions)) 160 for _, tx := range txBundle.Transactions { 161 bb, _ := tx.ToBytes(false /*preSignature*/) 162 fmt.Printf("%v,%v,%v\n", tx.TxnMeta.GetTxnType(), tx.Hash(), hex.EncodeToString(bb)) 163 } 164 165 time.Sleep(1) 166 peer.Disconnect() 167 break 168 } 169 } 170 } else if *flagCommand == "load" { 171 scanner := bufio.NewScanner(os.Stdin) 172 buf := make([]byte, 0, 64*1024) 173 scanner.Buffer(buf, 250*1024*1024) 174 txnBundle := &lib.MsgDeSoTransactionBundle{} 175 getTxnMsg := &lib.MsgDeSoGetTransactions{} 176 for scanner.Scan() { 177 txnHex := scanner.Text() 178 179 parts := strings.Split(txnHex, ",") 180 if len(parts) != 1 { 181 txnHex = parts[2] 182 } 183 184 bb, err := hex.DecodeString(txnHex) 185 if err != nil { 186 panic(err) 187 } 188 txn := &lib.MsgDeSoTxn{} 189 if err := txn.FromBytes(bb); err != nil { 190 glog.Error(err) 191 continue 192 } 193 194 txnBundle.Transactions = append(txnBundle.Transactions, txn) 195 196 getTxnMsg.HashList = append(getTxnMsg.HashList, txn.Hash()) 197 } 198 if err := scanner.Err(); err != nil { 199 panic(err) 200 } 201 202 fmt.Println(len(txnBundle.Transactions)) 203 204 // Write all the messages to the node 205 peer.WriteDeSoMessage(txnBundle) 206 207 // Fetch all the txns back from the node 208 peer.WriteDeSoMessage(getTxnMsg) 209 210 for { 211 msg, err := peer.ReadDeSoMessage() 212 if err != nil { 213 panic(err) 214 } 215 txnsFound := make(map[lib.BlockHash]*lib.MsgDeSoTxn) 216 if msg.GetMsgType() == lib.MsgTypeTransactionBundle { 217 for _, txn := range msg.(*lib.MsgDeSoTransactionBundle).Transactions { 218 txnsFound[*txn.Hash()] = txn 219 } 220 221 summary := make(map[lib.TxnType]int64) 222 for _, txn := range txnBundle.Transactions { 223 if _, exists := txnsFound[*txn.Hash()]; !exists { 224 glog.Infof("NOT LOADED: %v %v", txn.TxnMeta.GetTxnType(), txn.Hash()) 225 bb, err := txn.ToBytes(false) 226 if err != nil { 227 panic(err) 228 } 229 glog.V(1).Infof("TXN HEX: %v", hex.EncodeToString(bb)) 230 glog.V(2).Infof("DETAILS: %v", spew.Sdump(txn)) 231 232 val, _ := summary[txn.TxnMeta.GetTxnType()] 233 summary[txn.TxnMeta.GetTxnType()] = val + 1 234 } 235 } 236 glog.Info("Summary of missing txns: ", spew.Sdump(summary)) 237 break 238 } 239 } 240 241 peer.Disconnect() 242 243 } else { 244 fmt.Println("Command must be 'dump' or 'load'") 245 os.Exit(0) 246 } 247 }