decred.org/dcrdex@v1.0.3/dex/networks/ltc/block_online_test.go (about) 1 // This code is available on the terms of the project LICENSE.md file, 2 // also available online at https://blueoakcouncil.org 3 4 //go:build ltclive 5 6 package ltc 7 8 import ( 9 "context" 10 "encoding/hex" 11 "encoding/json" 12 "fmt" 13 "os/user" 14 "path/filepath" 15 "strings" 16 "testing" 17 18 "decred.org/dcrdex/dex/config" 19 20 "github.com/btcsuite/btcd/btcjson" 21 "github.com/decred/dcrd/chaincfg/chainhash" // just for the array type, not its methods 22 "github.com/decred/dcrd/rpcclient/v8" 23 ) 24 25 // TestOnlineDeserializeBlock attempts to deserialize every testnet4 LTC block 26 // from 1000 blocks prior to mweb to the chain tip. 27 func TestOnlineDeserializeBlock(t *testing.T) { 28 cfg := struct { 29 RPCUser string `ini:"rpcuser"` 30 RPCPass string `ini:"rpcpassword"` 31 }{} 32 usr, _ := user.Current() 33 if err := config.ParseInto(filepath.Join(usr.HomeDir, ".litecoin", "litecoin.conf"), &cfg); err != nil { 34 t.Fatalf("config.ParseInto error: %v", err) 35 } 36 client, err := rpcclient.New(&rpcclient.ConnConfig{ 37 HTTPPostMode: true, 38 DisableTLS: true, 39 Host: "127.0.0.1:19332", // testnet4, mainnet is 9332 40 User: cfg.RPCUser, 41 Pass: cfg.RPCPass, 42 }, nil) 43 if err != nil { 44 t.Fatalf("error creating RPC client: %v", err) 45 } 46 47 msg, err := client.RawRequest(context.Background(), "getblockchaininfo", nil) 48 if err != nil { 49 t.Fatalf("getblockchaininfo: %v", err) 50 } 51 gbci := &struct { 52 Chain string `json:"chain"` 53 }{} 54 err = json.Unmarshal(msg, &gbci) 55 if err != nil { 56 t.Fatalf("Unmarshal: %v", err) 57 } 58 isTestNet := gbci.Chain == "test" 59 t.Log("Network:", gbci.Chain) 60 61 makeParams := func(args ...any) []json.RawMessage { 62 params := make([]json.RawMessage, 0, len(args)) 63 for i := range args { 64 p, err := json.Marshal(args[i]) 65 if err != nil { 66 t.Fatal(err) 67 } 68 params = append(params, p) 69 } 70 return params 71 } 72 73 getBlkStr := func(hash *chainhash.Hash) string { 74 params := makeParams(hash.String(), 0) // not verbose 75 msg, err := client.RawRequest(context.Background(), "getblock", params) 76 if err != nil { 77 t.Fatalf("RawRequest: %v", err) 78 } 79 var blkStr string 80 err = json.Unmarshal(msg, &blkStr) 81 if err != nil { 82 t.Fatalf("Unmarshal: %v", err) 83 } 84 return blkStr 85 } 86 87 getBlkVerbose := func(hash *chainhash.Hash) *btcjson.GetBlockVerboseResult { 88 params := makeParams(hash.String(), 1) // verbose 89 msg, err := client.RawRequest(context.Background(), "getblock", params) 90 if err != nil { 91 t.Fatalf("RawRequest: %v", err) 92 } 93 var res btcjson.GetBlockVerboseResult 94 err = json.Unmarshal(msg, &res) 95 if err != nil { 96 t.Fatalf("Unmarshal: %v", err) 97 } 98 return &res 99 } 100 101 // start 1000 blocks prior to mweb testnet blocks 102 // 2215586 for mainnet, 2214584 for testnet4 103 var startBlk, numBlocks int64 = 2214584, 2000 104 if isTestNet { 105 numBlocks = 12000 // testnet blocks are empty and fast 106 } 107 for iBlk := startBlk; iBlk <= startBlk+numBlocks; iBlk++ { 108 hash, err := client.GetBlockHash(context.Background(), iBlk) 109 if err != nil { 110 if strings.Contains(err.Error(), "height out of range") { 111 break 112 } 113 t.Fatal(err) // hint: 401 means unauthorized (check user/pass above) 114 } 115 blkStr := getBlkStr(hash) 116 blk, err := DeserializeBlock(hex.NewDecoder(strings.NewReader(blkStr))) 117 if err != nil { 118 t.Fatalf("Unmarshal (%d): %v", iBlk, err) 119 } 120 if iBlk%500 == 0 { 121 fmt.Println(iBlk) 122 } 123 gbv := getBlkVerbose(hash) 124 if len(blk.Transactions) != len(gbv.Tx) { 125 t.Fatalf("block %v has %d but decoded %d txns", hash, len(gbv.Tx), len(blk.Transactions)) 126 } 127 for i, tx := range blk.Transactions { 128 txid := tx.TxHash().String() 129 if txid != gbv.Tx[i] { 130 t.Errorf("got txid %v, wanted %v", txid, gbv.Tx[i]) 131 } 132 } 133 } 134 }