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  }