github.com/trezor/blockbook@v0.4.1-0.20240328132726-e9a08582ee2c/bchain/coins/dash/dashparser_test.go (about)

     1  //go:build unittest
     2  
     3  package dash
     4  
     5  import (
     6  	"bytes"
     7  	"encoding/hex"
     8  	"fmt"
     9  	"io/ioutil"
    10  	"math/big"
    11  	"path/filepath"
    12  	"reflect"
    13  	"testing"
    14  
    15  	"github.com/trezor/blockbook/bchain"
    16  	"github.com/trezor/blockbook/bchain/coins/btc"
    17  )
    18  
    19  type testBlock struct {
    20  	size int
    21  	time int64
    22  	txs  []string
    23  }
    24  
    25  var testParseBlockTxs = map[int]testBlock{
    26  	500001: {
    27  		size: 6521,
    28  		time: 1468043164,
    29  		txs: []string{
    30  			"6d45c761892eb07b7651140aa42901b03cb501a82585fb360ff8f155d46727b0",
    31  			"5f6cbefca8a48cccd40805013e5f6c602e0d35c3511ccb7a2ae25e51dd95d38f",
    32  			"0eb37faa8b2f24c68c8e4a3009a051caded005d5f13f0dc216ff6422256f6b7b",
    33  			"2565cfacb7f8cbc73dc1053b06ca527d9798bf6bf29a778cb5924a17dd167a39",
    34  			"85f93911e8a4d8d9bbf3de009a666ed594d62aa41a34a9e3763058067e64f084",
    35  			"46712f0f32a392c71df443798e120d0f40eb93063631a992b3dedd4d4afc04e4",
    36  			"1790efaa05caad7ab546ef479041c3cb1cb9bca7b9cc7992566d2e2344701167",
    37  		},
    38  	},
    39  	// last block without special transactions, valid for bitcoin parser
    40  	1028159: {
    41  		size: 8608,
    42  		time: 1551246608,
    43  		txs: []string{
    44  			"a800f5b2dde5d48bda08d9d6fc5647c41cec902ce690a5a2be0665e6acf77c35",
    45  			"981d6668e65b70fcd97ddd68319f3c5e5163e510cc0ed479be5667bf1782f036",
    46  			"b9fd19d37ec97d038da2ccad9414ef311275d5fd3762bdec3e76f535e2295f4c",
    47  			"1b4051d02c9919ef8d482cadf6ca2002442d9436b444923cd295fe56009ec52b",
    48  			"6f1ec8472624b8e7481024ee8b228086b9b32606790e94f161589d3fe2b3a826",
    49  			"b12c512803d733f3f7afce846e18c6a46c713533cdb18a13392cbda88866523c",
    50  			"69e6d67946ed660b440c8e457933ae594ce60acdbe17ded091ce0ac6f41ed186",
    51  			"755c3b7cad9b569def3f69f897da2ee7732ee2e0a165965512680b4fe9086e12",
    52  			"63de772ff400789c2c3ad9be653817bebf92551e139d80c8e735bb0610865500",
    53  			"1566bd9bb2413c63412a13d16c7017814363f668d8b3bfe66a5478734e73f010",
    54  			"d7f441b0abca7df6530a0620661c839244bb6f26e1b4a53b783fb3acc1f5f42a",
    55  			"ec7762d0e02a87e311b128662db8ef4161dcc9d9f2831250c7366eed98fc744b",
    56  			"b977669bfc0ac3b9ca9de7512fda564a69fe49dde8a286fcb7ea99147db54b5f",
    57  		},
    58  	},
    59  	// first block with special transactions, invalid for bitcoin parser
    60  	// 1028160: {
    61  	// 	size: 2347,
    62  	// 	time: 1551246710,
    63  	// 	txs: []string{
    64  	// 		"71d6975e3b79b52baf26c3269896a34f3bedfb04561c692ffa31f64dada1f9c4",
    65  	// 		"ed732a404cdfd4e0475a7a016200b7eef191f2c9de0ffdef8a20091c0499299c",
    66  	// 		"99d0613f82ea1f928bbc98318665adbdf5b40d206bd487fe77d542e86c903f55",
    67  	// 		"05cbf334a563468d0e378c56b43fb5254ee9c0e35ca8fab5cb242ebd825ae97b",
    68  	// 		"ee91fae7be36b3b81bc60992e904e1ae91e7dffdd5751ccaef557ba62ea80a4f",
    69  	// 	},
    70  	// },
    71  }
    72  
    73  func helperLoadBlock(t *testing.T, height int) []byte {
    74  	name := fmt.Sprintf("block_dump.%d", height)
    75  	path := filepath.Join("testdata", name)
    76  
    77  	d, err := ioutil.ReadFile(path)
    78  	if err != nil {
    79  		t.Fatal(err)
    80  	}
    81  
    82  	d = bytes.TrimSpace(d)
    83  
    84  	b := make([]byte, hex.DecodedLen(len(d)))
    85  	_, err = hex.Decode(b, d)
    86  	if err != nil {
    87  		t.Fatal(err)
    88  	}
    89  
    90  	return b
    91  }
    92  
    93  func TestParseBlock(t *testing.T) {
    94  	p := NewDashParser(GetChainParams("main"), &btc.Configuration{})
    95  
    96  	for height, tb := range testParseBlockTxs {
    97  		b := helperLoadBlock(t, height)
    98  
    99  		blk, err := p.ParseBlock(b)
   100  		if err != nil {
   101  			t.Errorf("ParseBlock() error %v", err)
   102  		}
   103  
   104  		if blk.Size != tb.size {
   105  			t.Errorf("ParseBlock() block size: got %d, want %d", blk.Size, tb.size)
   106  		}
   107  
   108  		if blk.Time != tb.time {
   109  			t.Errorf("ParseBlock() block time: got %d, want %d", blk.Time, tb.time)
   110  		}
   111  
   112  		if len(blk.Txs) != len(tb.txs) {
   113  			t.Errorf("ParseBlock() number of transactions: got %d, want %d", len(blk.Txs), len(tb.txs))
   114  		}
   115  
   116  		for ti, tx := range tb.txs {
   117  			if blk.Txs[ti].Txid != tx {
   118  				t.Errorf("ParseBlock() transaction %d: got %s, want %s", ti, blk.Txs[ti].Txid, tx)
   119  			}
   120  		}
   121  	}
   122  }
   123  
   124  var (
   125  	testTx1 = bchain.Tx{
   126  		Blocktime:     1551246710,
   127  		Confirmations: 0,
   128  		Hex:           "0100000001f85264d11a747bdba77d411e5e4a3d35e3aeb5843b34a95234a2121ac65496bd000000006b483045022100dfa158fbd9773fab4f6f329c807e040af0c3a40967cbe01667169b914ed5ad960220061c5876364caa3e3c9c990ad2b4cc8b1a53d4f954dbda8434b0e67cc8348ff6012103093865e1e132b33a2a5ed01c79d2edba3473826a66cb26b8311bfa42749c2190ffffffff02ec3f8a2a010000001976a91470dcef2a22575d7a8f0779fb1d6cdd48135bd22788ac3116491d000000001976a91471348f7780e955a2a60eba17ecc4c826ebc23a9888ac00000000",
   129  		LockTime:      0,
   130  		Time:          1551246710,
   131  		Txid:          "ed732a404cdfd4e0475a7a016200b7eef191f2c9de0ffdef8a20091c0499299c",
   132  		Version:       1,
   133  		Vin: []bchain.Vin{
   134  			{
   135  				Txid: "bd9654c61a12a23452a9343b84b5aee3353d4a5e1e417da7db7b741ad16452f8",
   136  				Vout: 0,
   137  				ScriptSig: bchain.ScriptSig{
   138  					Hex: "483045022100dfa158fbd9773fab4f6f329c807e040af0c3a40967cbe01667169b914ed5ad960220061c5876364caa3e3c9c990ad2b4cc8b1a53d4f954dbda8434b0e67cc8348ff6012103093865e1e132b33a2a5ed01c79d2edba3473826a66cb26b8311bfa42749c2190",
   139  				},
   140  				Sequence: 4294967295,
   141  			},
   142  		},
   143  		Vout: []bchain.Vout{
   144  			{
   145  				N: 0,
   146  				ScriptPubKey: bchain.ScriptPubKey{
   147  					Addresses: []string{"XkycBX1ykVXXs92pAi6ZQwZPEre9kSHHKH"},
   148  					Hex:       "76a91470dcef2a22575d7a8f0779fb1d6cdd48135bd22788ac",
   149  				},
   150  				ValueSat: *big.NewInt(5008670700),
   151  			},
   152  			{
   153  				N: 1,
   154  				ScriptPubKey: bchain.ScriptPubKey{
   155  					Addresses: []string{"Xm1R9thKBm2EZKZevXsmMX4DVwQQuTohZu"},
   156  					Hex:       "76a91471348f7780e955a2a60eba17ecc4c826ebc23a9888ac",
   157  				},
   158  				ValueSat: *big.NewInt(491329073),
   159  			},
   160  		},
   161  	}
   162  	testTxPacked1 = "0a20ed732a404cdfd4e0475a7a016200b7eef191f2c9de0ffdef8a20091c0499299c12e2010100000001f85264d11a747bdba77d411e5e4a3d35e3aeb5843b34a95234a2121ac65496bd000000006b483045022100dfa158fbd9773fab4f6f329c807e040af0c3a40967cbe01667169b914ed5ad960220061c5876364caa3e3c9c990ad2b4cc8b1a53d4f954dbda8434b0e67cc8348ff6012103093865e1e132b33a2a5ed01c79d2edba3473826a66cb26b8311bfa42749c2190ffffffff02ec3f8a2a010000001976a91470dcef2a22575d7a8f0779fb1d6cdd48135bd22788ac3116491d000000001976a91471348f7780e955a2a60eba17ecc4c826ebc23a9888ac0000000018f6cad8e30528c0e03e3295011220bd9654c61a12a23452a9343b84b5aee3353d4a5e1e417da7db7b741ad16452f8226b483045022100dfa158fbd9773fab4f6f329c807e040af0c3a40967cbe01667169b914ed5ad960220061c5876364caa3e3c9c990ad2b4cc8b1a53d4f954dbda8434b0e67cc8348ff6012103093865e1e132b33a2a5ed01c79d2edba3473826a66cb26b8311bfa42749c219028ffffffff0f3a460a05012a8a3fec1a1976a91470dcef2a22575d7a8f0779fb1d6cdd48135bd22788ac2222586b7963425831796b565858733932704169365a51775a50457265396b5348484b483a470a041d49163110011a1976a91471348f7780e955a2a60eba17ecc4c826ebc23a9888ac2222586d31523974684b426d32455a4b5a657658736d4d5834445677515175546f685a754001"
   163  
   164  	testTx2 = bchain.Tx{
   165  		Blocktime:     1551246710,
   166  		Confirmations: 0,
   167  		Hex:           "03000500010000000000000000000000000000000000000000000000000000000000000000ffffffff170340b00f1291af3c09542bc8349901000000002f4e614effffffff024181f809000000001976a9146a341485a9444b35dc9cb90d24e7483de7d37e0088ac3581f809000000001976a9140d1156f6026bf975ea3553b03fb534d0959c294c88ac0000000026010040b00f000000000000000000000000000000000000000000000000000000000000000000",
   168  		LockTime:      0,
   169  		Time:          1551246710,
   170  		Txid:          "71d6975e3b79b52baf26c3269896a34f3bedfb04561c692ffa31f64dada1f9c4",
   171  		Version:       3,
   172  		Vin: []bchain.Vin{
   173  			{
   174  				Coinbase: "0340b00f1291af3c09542bc8349901000000002f4e614e",
   175  				Sequence: 4294967295,
   176  			},
   177  		},
   178  		Vout: []bchain.Vout{
   179  			{
   180  				N: 0,
   181  				ScriptPubKey: bchain.ScriptPubKey{
   182  					Addresses: []string{"XkNPrBSJtrHZUvUqb3JF4g5rMB3uzaJfEL"},
   183  					Hex:       "76a9146a341485a9444b35dc9cb90d24e7483de7d37e0088ac",
   184  				},
   185  				ValueSat: *big.NewInt(167280961),
   186  			},
   187  			{
   188  				N: 1,
   189  				ScriptPubKey: bchain.ScriptPubKey{
   190  					Addresses: []string{"XbswPXhcLqm5AN5gwcTTyiUGSP2YndWwk9"},
   191  					Hex:       "76a9140d1156f6026bf975ea3553b03fb534d0959c294c88ac",
   192  				},
   193  				ValueSat: *big.NewInt(167280949),
   194  			},
   195  		},
   196  	}
   197  
   198  	testTxPacked2 = "0a2071d6975e3b79b52baf26c3269896a34f3bedfb04561c692ffa31f64dada1f9c412b50103000500010000000000000000000000000000000000000000000000000000000000000000ffffffff170340b00f1291af3c09542bc8349901000000002f4e614effffffff024181f809000000001976a9146a341485a9444b35dc9cb90d24e7483de7d37e0088ac3581f809000000001976a9140d1156f6026bf975ea3553b03fb534d0959c294c88ac0000000026010040b00f00000000000000000000000000000000000000000000000000000000000000000018f6cad8e30528c0e03e32360a2e3033343062303066313239316166336330393534326263383334393930313030303030303030326634653631346528ffffffff0f3a450a0409f881411a1976a9146a341485a9444b35dc9cb90d24e7483de7d37e0088ac2222586b4e507242534a7472485a5576557162334a46346735724d4233757a614a66454c3a470a0409f8813510011a1976a9140d1156f6026bf975ea3553b03fb534d0959c294c88ac222258627377505868634c716d35414e35677763545479695547535032596e6457776b394003"
   199  )
   200  
   201  func TestBaseParser_ParseTxFromJson(t *testing.T) {
   202  	p := NewDashParser(GetChainParams("main"), &btc.Configuration{})
   203  	tests := []struct {
   204  		name    string
   205  		msg     string
   206  		want    *bchain.Tx
   207  		wantErr bool
   208  	}{
   209  		{
   210  			name: "normal tx",
   211  			msg:  `{"hex":"0100000001f85264d11a747bdba77d411e5e4a3d35e3aeb5843b34a95234a2121ac65496bd000000006b483045022100dfa158fbd9773fab4f6f329c807e040af0c3a40967cbe01667169b914ed5ad960220061c5876364caa3e3c9c990ad2b4cc8b1a53d4f954dbda8434b0e67cc8348ff6012103093865e1e132b33a2a5ed01c79d2edba3473826a66cb26b8311bfa42749c2190ffffffff02ec3f8a2a010000001976a91470dcef2a22575d7a8f0779fb1d6cdd48135bd22788ac3116491d000000001976a91471348f7780e955a2a60eba17ecc4c826ebc23a9888ac00000000","txid":"ed732a404cdfd4e0475a7a016200b7eef191f2c9de0ffdef8a20091c0499299c","size":226,"version":1,"type":0,"locktime":0,"vin":[{"txid":"bd9654c61a12a23452a9343b84b5aee3353d4a5e1e417da7db7b741ad16452f8","vout":0,"scriptSig":{"asm":"3045022100dfa158fbd9773fab4f6f329c807e040af0c3a40967cbe01667169b914ed5ad960220061c5876364caa3e3c9c990ad2b4cc8b1a53d4f954dbda8434b0e67cc8348ff6[ALL]03093865e1e132b33a2a5ed01c79d2edba3473826a66cb26b8311bfa42749c2190","hex":"483045022100dfa158fbd9773fab4f6f329c807e040af0c3a40967cbe01667169b914ed5ad960220061c5876364caa3e3c9c990ad2b4cc8b1a53d4f954dbda8434b0e67cc8348ff6012103093865e1e132b33a2a5ed01c79d2edba3473826a66cb26b8311bfa42749c2190"},"value":55.00000000,"valueSat":5500000000,"address":"Xgcv4bKAXaWf5sjX9KR49L98jeMwNgeXWh","sequence":4294967295}],"vout":[{"value":50.08670700,"valueSat":5008670700,"n":0,"scriptPubKey":{"asm":"OP_DUPOP_HASH16070dcef2a22575d7a8f0779fb1d6cdd48135bd227OP_EQUALVERIFYOP_CHECKSIG","hex":"76a91470dcef2a22575d7a8f0779fb1d6cdd48135bd22788ac","reqSigs":1,"type":"pubkeyhash","addresses":["XkycBX1ykVXXs92pAi6ZQwZPEre9kSHHKH"]}},{"value":4.91329073,"valueSat":491329073,"n":1,"scriptPubKey":{"asm":"OP_DUPOP_HASH16071348f7780e955a2a60eba17ecc4c826ebc23a98OP_EQUALVERIFYOP_CHECKSIG","hex":"76a91471348f7780e955a2a60eba17ecc4c826ebc23a9888ac","reqSigs":1,"type":"pubkeyhash","addresses":["Xm1R9thKBm2EZKZevXsmMX4DVwQQuTohZu"]}}],"blockhash":"000000000000002099caaf1a877911d99a5980ede9b981280eecb291afedf87b","height":1028160,"confirmations":0,"time":1551246710,"blocktime":1551246710,"instantlock":false}`,
   212  			want: &testTx1,
   213  		},
   214  		{
   215  			name: "special tx - DIP2",
   216  			msg:  `{"hex":"03000500010000000000000000000000000000000000000000000000000000000000000000ffffffff170340b00f1291af3c09542bc8349901000000002f4e614effffffff024181f809000000001976a9146a341485a9444b35dc9cb90d24e7483de7d37e0088ac3581f809000000001976a9140d1156f6026bf975ea3553b03fb534d0959c294c88ac0000000026010040b00f000000000000000000000000000000000000000000000000000000000000000000","txid":"71d6975e3b79b52baf26c3269896a34f3bedfb04561c692ffa31f64dada1f9c4","size":181,"version":3,"type":5,"locktime":0,"vin":[{"coinbase":"0340b00f1291af3c09542bc8349901000000002f4e614e","sequence":4294967295}],"vout":[{"value":1.67280961,"valueSat":167280961,"n":0,"scriptPubKey":{"asm":"OP_DUPOP_HASH1606a341485a9444b35dc9cb90d24e7483de7d37e00OP_EQUALVERIFYOP_CHECKSIG","hex":"76a9146a341485a9444b35dc9cb90d24e7483de7d37e0088ac","reqSigs":1,"type":"pubkeyhash","addresses":["XkNPrBSJtrHZUvUqb3JF4g5rMB3uzaJfEL"]}},{"value":1.67280949,"valueSat":167280949,"n":1,"scriptPubKey":{"asm":"OP_DUPOP_HASH1600d1156f6026bf975ea3553b03fb534d0959c294cOP_EQUALVERIFYOP_CHECKSIG","hex":"76a9140d1156f6026bf975ea3553b03fb534d0959c294c88ac","reqSigs":1,"type":"pubkeyhash","addresses":["XbswPXhcLqm5AN5gwcTTyiUGSP2YndWwk9"]}}],"extraPayloadSize":38,"extraPayload":"010040b00f000000000000000000000000000000000000000000000000000000000000000000","cbTx":{"version":1,"height":1028160,"merkleRootMNList":"0000000000000000000000000000000000000000000000000000000000000000"},"blockhash":"000000000000002099caaf1a877911d99a5980ede9b981280eecb291afedf87b","height":1028160,"confirmations":0,"time":1551246710,"blocktime":1551246710,"instantlock":false}`,
   217  			want: &testTx2,
   218  		},
   219  	}
   220  	for _, tt := range tests {
   221  		t.Run(tt.name, func(t *testing.T) {
   222  			got, err := p.ParseTxFromJson([]byte(tt.msg))
   223  			if (err != nil) != tt.wantErr {
   224  				t.Errorf("DashParser.ParseTxFromJson() error = %v, wantErr %v", err, tt.wantErr)
   225  				return
   226  			}
   227  			if !reflect.DeepEqual(got, tt.want) {
   228  				t.Errorf("DashParser.ParseTxFromJson() = %+v, want %+v", got, tt.want)
   229  			}
   230  		})
   231  	}
   232  }
   233  
   234  func Test_PackTx(t *testing.T) {
   235  	type args struct {
   236  		tx        bchain.Tx
   237  		height    uint32
   238  		blockTime int64
   239  		parser    *DashParser
   240  	}
   241  	tests := []struct {
   242  		name    string
   243  		args    args
   244  		want    string
   245  		wantErr bool
   246  	}{
   247  		{
   248  			name: "dash-1",
   249  			args: args{
   250  				tx:        testTx1,
   251  				height:    1028160,
   252  				blockTime: 1551246710,
   253  				parser:    NewDashParser(GetChainParams("main"), &btc.Configuration{}),
   254  			},
   255  			want:    testTxPacked1,
   256  			wantErr: false,
   257  		},
   258  		{
   259  			name: "dash-2",
   260  			args: args{
   261  				tx:        testTx2,
   262  				height:    1028160,
   263  				blockTime: 1551246710,
   264  				parser:    NewDashParser(GetChainParams("main"), &btc.Configuration{}),
   265  			},
   266  			want:    testTxPacked2,
   267  			wantErr: false,
   268  		},
   269  	}
   270  	for _, tt := range tests {
   271  		t.Run(tt.name, func(t *testing.T) {
   272  			got, err := tt.args.parser.PackTx(&tt.args.tx, tt.args.height, tt.args.blockTime)
   273  			if (err != nil) != tt.wantErr {
   274  				t.Errorf("packTx() error = %v, wantErr %v", err, tt.wantErr)
   275  				return
   276  			}
   277  			h := hex.EncodeToString(got)
   278  			if !reflect.DeepEqual(h, tt.want) {
   279  				t.Errorf("packTx() = %v, want %v", h, tt.want)
   280  			}
   281  		})
   282  	}
   283  }
   284  
   285  func Test_UnpackTx(t *testing.T) {
   286  	type args struct {
   287  		packedTx string
   288  		parser   *DashParser
   289  	}
   290  	tests := []struct {
   291  		name    string
   292  		args    args
   293  		want    *bchain.Tx
   294  		want1   uint32
   295  		wantErr bool
   296  	}{
   297  		{
   298  			name: "dash-1",
   299  			args: args{
   300  				packedTx: testTxPacked1,
   301  				parser:   NewDashParser(GetChainParams("main"), &btc.Configuration{}),
   302  			},
   303  			want:    &testTx1,
   304  			want1:   1028160,
   305  			wantErr: false,
   306  		},
   307  		{
   308  			name: "dash-2",
   309  			args: args{
   310  				packedTx: testTxPacked2,
   311  				parser:   NewDashParser(GetChainParams("main"), &btc.Configuration{}),
   312  			},
   313  			want:    &testTx2,
   314  			want1:   1028160,
   315  			wantErr: false,
   316  		},
   317  	}
   318  	for _, tt := range tests {
   319  		t.Run(tt.name, func(t *testing.T) {
   320  			b, _ := hex.DecodeString(tt.args.packedTx)
   321  			got, got1, err := tt.args.parser.UnpackTx(b)
   322  			if (err != nil) != tt.wantErr {
   323  				t.Errorf("unpackTx() error = %v, wantErr %v", err, tt.wantErr)
   324  				return
   325  			}
   326  			if !reflect.DeepEqual(got, tt.want) {
   327  				t.Errorf("unpackTx() got = %v, want %v", got, tt.want)
   328  			}
   329  			if got1 != tt.want1 {
   330  				t.Errorf("unpackTx() got1 = %v, want %v", got1, tt.want1)
   331  			}
   332  		})
   333  	}
   334  }