validate_test.go raw

   1  package blockchain
   2  
   3  import (
   4  	block2 "github.com/p9c/p9/pkg/block"
   5  	"math"
   6  	"reflect"
   7  	"testing"
   8  	"time"
   9  	
  10  	"github.com/p9c/p9/pkg/chaincfg"
  11  	"github.com/p9c/p9/pkg/chainhash"
  12  	"github.com/p9c/p9/pkg/util"
  13  	"github.com/p9c/p9/pkg/wire"
  14  )
  15  
  16  // TestSequenceLocksActive tests the SequenceLockActive function to ensure it works as expected in all possible
  17  // // combinations/scenarios.
  18  // func TestSequenceLocksActive(t *testing.T) {
  19  // 	seqLock := func(h int32, s int64) *SequenceLock {
  20  // 		return &SequenceLock{
  21  // 			Seconds:     s,
  22  // 			BlockHeight: h,
  23  // 		}
  24  // 	}
  25  // 	tests := []struct {
  26  // 		seqLock     *SequenceLock
  27  // 		blockHeight int32
  28  // 		mtp         time.Time
  29  // 		want        bool
  30  // 	}{
  31  // 		// Block based sequence lock with equal block height.
  32  // 		{seqLock: seqLock(1000, -1), blockHeight: 1001, mtp: time.Unix(9, 0), want: true},
  33  // 		// Time based sequence lock with mtp past the absolute time.
  34  // 		{seqLock: seqLock(-1, 30), blockHeight: 2, mtp: time.Unix(31, 0), want: true},
  35  // 		// Block based sequence lock with current height below seq lock block height.
  36  // 		{seqLock: seqLock(1000, -1), blockHeight: 90, mtp: time.Unix(9, 0), want: false},
  37  // 		// Time based sequence lock with current time before lock time.
  38  // 		{seqLock: seqLock(-1, 30), blockHeight: 2, mtp: time.Unix(29, 0), want: false},
  39  // 		// Block based sequence lock at the same height, so shouldn't yet be active.
  40  // 		{seqLock: seqLock(1000, -1), blockHeight: 1000, mtp: time.Unix(9, 0), want: false},
  41  // 		// Time based sequence lock with current time equal to lock time, so shouldn't yet be active.
  42  // 		{seqLock: seqLock(-1, 30), blockHeight: 2, mtp: time.Unix(30, 0), want: false},
  43  // 	}
  44  // 	t.Logf("Running %d sequence locks tests", len(tests))
  45  // 	for i, test := range tests {
  46  // 		got := SequenceLockActive(
  47  // 			test.seqLock,
  48  // 			test.blockHeight, test.mtp,
  49  // 		)
  50  // 		if got != test.want {
  51  // 			t.Fatalf(
  52  // 				"SequenceLockActive #%d got %v want %v", i,
  53  // 				got, test.want,
  54  // 			)
  55  // 		}
  56  // 	}
  57  // }
  58  
  59  // // TestCheckConnectBlockTemplate tests the CheckConnectBlockTemplate function to
  60  // // ensure it fails.
  61  // func TestCheckConnectBlockTemplate(// 	t *testing.T) {
  62  // 	// Create a new database and chain instance to run tests against.
  63  // 	chain, teardownFunc, e := chainSetup("checkconnectblocktemplate",
  64  // 		&chaincfg.MainNetParams)
  65  // 	if e != nil  {
  66  // 		t.Errorf("Failed to setup chain instance: %v", e)
  67  // 		return
  68  // 	}
  69  // 	defer teardownFunc()
  70  // 	// Since we're not dealing with the real block chain, set the coinbase
  71  // 	// maturity to 1.
  72  // 	chain.TstSetCoinbaseMaturity(1)
  73  // 	// Load up blocks such that there is a side chain.
  74  // 	// (genesis block) -> 1 -> 2 -> 3 -> 4
  75  // 	//                          \-> 3a
  76  // 	testFiles := []string{
  77  // 		"blk_0_to_4.dat.bz2",
  78  // 		"blk_3A.dat.bz2",
  79  // 	}
  80  // 	var blocks []*util.Block
  81  // 	for _, file := range testFiles {
  82  // 		blockTmp, e := loadBlocks(file)
  83  // 		if e != nil  {
  84  // 			t.Fatalf("Error loading file: %v\n", e)
  85  // 		}
  86  // 		blocks = append(blocks, blockTmp...)
  87  // 	}
  88  // 	for i := 1; i <= 3; i++ {
  89  // 		isMainChain, _, e = chain.ProcessBlock(
  90  // 			blocks[i], BFNone, blocks[i].Height())
  91  // 		if e != nil  {
  92  // 			t.Fatalf("CheckConnectBlockTemplate: Received unexpected error "+
  93  // 				"processing block %d: %v", i, e)
  94  // 		}
  95  // 		if !isMainChain {
  96  // 			t.Fatalf("CheckConnectBlockTemplate: Expected block %d to connect "+
  97  // 				"to main chain", i)
  98  // 		}
  99  // 	}
 100  // 	// Block 3 should fail to connect since it's already inserted.
 101  // 	e = chain.CheckConnectBlockTemplate(blocks[3])
 102  // 	if e ==  nil {
 103  // 		t.Fatal("CheckConnectBlockTemplate: Did not received expected error " +
 104  // 			"on block 3")
 105  // 	}
 106  // 	// Block 4 should connect successfully to tip of chain.
 107  // 	e = chain.CheckConnectBlockTemplate(blocks[4])
 108  // 	if e != nil  {
 109  // 		t.Fatalf("CheckConnectBlockTemplate: Received unexpected error on "+
 110  // 			"block 4: %v", e)
 111  // 	}
 112  // 	// Block 3a should fail to connect since does not podbuild on chain tip.
 113  // 	e = chain.CheckConnectBlockTemplate(blocks[5])
 114  // 	if e ==  nil {
 115  // 		t.Fatal("CheckConnectBlockTemplate: Did not received expected error " +
 116  // 			"on block 3a")
 117  // 	}
 118  // 	// Block 4 should connect even if proof of work is invalid.
 119  // 	invalidPowBlock := *blocks[4].Block()
 120  // 	invalidPowBlock.Header.Nonce++
 121  // 	e = chain.CheckConnectBlockTemplate(util.NewBlock(&invalidPowBlock))
 122  // 	if e != nil  {
 123  // 		t.Fatalf("CheckConnectBlockTemplate: Received unexpected error on "+
 124  // 			"block 4 with bad nonce: %v", e)
 125  // 	}
 126  // 	// Invalid block building on chain tip should fail to connect.
 127  // 	invalidBlock := *blocks[4].Block()
 128  // 	invalidBlock.Header.Bits--
 129  // 	e = chain.CheckConnectBlockTemplate(util.NewBlock(&invalidBlock))
 130  // 	if e ==  nil {
 131  // 		t.Fatal("CheckConnectBlockTemplate: Did not received expected error " +
 132  // 			"on block 4 with invalid difficulty bits")
 133  // 	}
 134  // }
 135  
 136  // TestCheckBlockSanity tests the CheckBlockSanity function to ensure it works as expected.
 137  func TestCheckBlockSanity(t *testing.T) {
 138  	powLimit := chaincfg.MainNetParams.PowLimit
 139  	block := block2.NewBlock(&Block100000)
 140  	timeSource := NewMedianTime()
 141  	e := CheckBlockSanity(
 142  		block,
 143  		powLimit,
 144  		timeSource,
 145  		false,
 146  		1,
 147  		block.WireBlock().Header.Timestamp.Truncate(time.Second).Add(-time.Second),
 148  	)
 149  	if e != nil {
 150  		t.Errorf("CheckBlockSanity: %v", e)
 151  	}
 152  	// Ensure a block that has a timestamp with a precision higher than one second fails.
 153  	timestamp := block.WireBlock().Header.Timestamp
 154  	block.WireBlock().Header.Timestamp = timestamp.Add(time.Nanosecond)
 155  	e = CheckBlockSanity(
 156  		block,
 157  		powLimit,
 158  		timeSource,
 159  		false,
 160  		1,
 161  		block.WireBlock().Header.Timestamp.Truncate(time.Second).Add(-time.Second),
 162  	)
 163  	if e == nil {
 164  		t.Errorf("CheckBlockSanity: error is nil when it shouldn't be")
 165  	}
 166  }
 167  
 168  // TestCheckSerializedHeight tests the checkSerializedHeight function with various serialized heights and also does
 169  // negative tests to ensure errors and handled properly.
 170  func TestCheckSerializedHeight(t *testing.T) {
 171  	// Create an empty coinbase template to be used in the tests below.
 172  	coinbaseOutpoint := wire.NewOutPoint(&chainhash.Hash{}, math.MaxUint32)
 173  	coinbaseTx := wire.NewMsgTx(1)
 174  	coinbaseTx.AddTxIn(wire.NewTxIn(coinbaseOutpoint, nil, nil))
 175  	// Expected rule errors.
 176  	missingHeightError := RuleError{
 177  		ErrorCode: ErrMissingCoinbaseHeight,
 178  	}
 179  	badHeightError := RuleError{
 180  		ErrorCode: ErrBadCoinbaseHeight,
 181  	}
 182  	tests := []struct {
 183  		sigScript  []byte // Serialized data
 184  		wantHeight int32  // Expected height
 185  		e          error  // Expected error type
 186  	}{
 187  		// No serialized height length.
 188  		{[]byte{}, 0, missingHeightError},
 189  		// Serialized height length with no height bytes.
 190  		{[]byte{0x02}, 0, missingHeightError},
 191  		// Serialized height length with too few height bytes.
 192  		{[]byte{0x02, 0x4a}, 0, missingHeightError},
 193  		// Serialized height that needs 2 bytes to encode.
 194  		{[]byte{0x02, 0x4a, 0x52}, 21066, nil},
 195  		// Serialized height that needs 2 bytes to encode, but backwards
 196  		// endianness.
 197  		{[]byte{0x02, 0x4a, 0x52}, 19026, badHeightError},
 198  		// Serialized height that needs 3 bytes to encode.
 199  		{[]byte{0x03, 0x40, 0x0d, 0x03}, 200000, nil},
 200  		// Serialized height that needs 3 bytes to encode, but backwards
 201  		// endianness.
 202  		{[]byte{0x03, 0x40, 0x0d, 0x03}, 1074594560, badHeightError},
 203  	}
 204  	t.Logf("Running %d tests", len(tests))
 205  	for i, test := range tests {
 206  		msgTx := coinbaseTx.Copy()
 207  		msgTx.TxIn[0].SignatureScript = test.sigScript
 208  		tx := util.NewTx(msgTx)
 209  		e := checkSerializedHeight(tx, test.wantHeight)
 210  		if reflect.TypeOf(e) != reflect.TypeOf(test.e) {
 211  			t.Errorf(
 212  				"checkSerializedHeight #%d wrong error type "+
 213  					"got: %v <%T>, want: %T", i, e, e, test.e,
 214  			)
 215  			continue
 216  		}
 217  		if rerr, ok := e.(RuleError); ok {
 218  			trerr := test.e.(RuleError)
 219  			if rerr.ErrorCode != trerr.ErrorCode {
 220  				t.Errorf(
 221  					"checkSerializedHeight #%d wrong "+
 222  						"error code got: %v, want: %v", i,
 223  					rerr.ErrorCode, trerr.ErrorCode,
 224  				)
 225  				continue
 226  			}
 227  		}
 228  	}
 229  }
 230  
 231  // Block100000 defines block 100,000 of the block chain. It is used to test Block operations.
 232  var Block100000 = wire.Block{
 233  	Header: wire.BlockHeader{
 234  		Version: 1,
 235  		PrevBlock: chainhash.Hash(
 236  			[32]byte{
 237  				// Make go vet happy.
 238  				0x50, 0x12, 0x01, 0x19, 0x17, 0x2a, 0x61, 0x04,
 239  				0x21, 0xa6, 0xc3, 0x01, 0x1d, 0xd3, 0x30, 0xd9,
 240  				0xdf, 0x07, 0xb6, 0x36, 0x16, 0xc2, 0xcc, 0x1f,
 241  				0x1c, 0xd0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
 242  			},
 243  		), // 000000000002d01c1fccc21636b607dfd930d31d01c3a62104612a1719011250
 244  		MerkleRoot: chainhash.Hash(
 245  			[32]byte{
 246  				// Make go vet happy.
 247  				0x66, 0x57, 0xa9, 0x25, 0x2a, 0xac, 0xd5, 0xc0,
 248  				0xb2, 0x94, 0x09, 0x96, 0xec, 0xff, 0x95, 0x22,
 249  				0x28, 0xc3, 0x06, 0x7c, 0xc3, 0x8d, 0x48, 0x85,
 250  				0xef, 0xb5, 0xa4, 0xac, 0x42, 0x47, 0xe9, 0xf3,
 251  			},
 252  		),                                   // f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766
 253  		Timestamp: time.Unix(1293623863, 0), // 2010-12-29 11:57:43 +0000 UTC
 254  		Bits:      0x1b04864c,               // 453281356
 255  		Nonce:     0x10572b0f,               // 274148111
 256  	},
 257  	Transactions: []*wire.MsgTx{
 258  		{
 259  			Version: 1,
 260  			TxIn: []*wire.TxIn{
 261  				{
 262  					PreviousOutPoint: wire.OutPoint{
 263  						Hash:  chainhash.Hash{},
 264  						Index: 0xffffffff,
 265  					},
 266  					SignatureScript: []byte{
 267  						0x04, 0x4c, 0x86, 0x04, 0x1b, 0x02, 0x06, 0x02,
 268  					},
 269  					Sequence: 0xffffffff,
 270  				},
 271  			},
 272  			TxOut: []*wire.TxOut{
 273  				{
 274  					Value: 0x12a05f200, // 5000000000
 275  					PkScript: []byte{
 276  						0x41, // OP_DATA_65
 277  						0x04, 0x1b, 0x0e, 0x8c, 0x25, 0x67, 0xc1, 0x25,
 278  						0x36, 0xaa, 0x13, 0x35, 0x7b, 0x79, 0xa0, 0x73,
 279  						0xdc, 0x44, 0x44, 0xac, 0xb8, 0x3c, 0x4e, 0xc7,
 280  						0xa0, 0xe2, 0xf9, 0x9d, 0xd7, 0x45, 0x75, 0x16,
 281  						0xc5, 0x81, 0x72, 0x42, 0xda, 0x79, 0x69, 0x24,
 282  						0xca, 0x4e, 0x99, 0x94, 0x7d, 0x08, 0x7f, 0xed,
 283  						0xf9, 0xce, 0x46, 0x7c, 0xb9, 0xf7, 0xc6, 0x28,
 284  						0x70, 0x78, 0xf8, 0x01, 0xdf, 0x27, 0x6f, 0xdf,
 285  						0x84, // 65-byte signature
 286  						0xac, // OP_CHECKSIG
 287  					},
 288  				},
 289  			},
 290  			LockTime: 0,
 291  		},
 292  		{
 293  			Version: 1,
 294  			TxIn: []*wire.TxIn{
 295  				{
 296  					PreviousOutPoint: wire.OutPoint{
 297  						Hash: chainhash.Hash(
 298  							[32]byte{
 299  								// Make go vet happy.
 300  								0x03, 0x2e, 0x38, 0xe9, 0xc0, 0xa8, 0x4c, 0x60,
 301  								0x46, 0xd6, 0x87, 0xd1, 0x05, 0x56, 0xdc, 0xac,
 302  								0xc4, 0x1d, 0x27, 0x5e, 0xc5, 0x5f, 0xc0, 0x07,
 303  								0x79, 0xac, 0x88, 0xfd, 0xf3, 0x57, 0xa1, 0x87,
 304  							},
 305  						), // 87a157f3fd88ac7907c05fc55e271dc4acdc5605d187d646604ca8c0e9382e03
 306  						Index: 0,
 307  					},
 308  					SignatureScript: []byte{
 309  						0x49, // OP_DATA_73
 310  						0x30, 0x46, 0x02, 0x21, 0x00, 0xc3, 0x52, 0xd3,
 311  						0xdd, 0x99, 0x3a, 0x98, 0x1b, 0xeb, 0xa4, 0xa6,
 312  						0x3a, 0xd1, 0x5c, 0x20, 0x92, 0x75, 0xca, 0x94,
 313  						0x70, 0xab, 0xfc, 0xd5, 0x7d, 0xa9, 0x3b, 0x58,
 314  						0xe4, 0xeb, 0x5d, 0xce, 0x82, 0x02, 0x21, 0x00,
 315  						0x84, 0x07, 0x92, 0xbc, 0x1f, 0x45, 0x60, 0x62,
 316  						0x81, 0x9f, 0x15, 0xd3, 0x3e, 0xe7, 0x05, 0x5c,
 317  						0xf7, 0xb5, 0xee, 0x1a, 0xf1, 0xeb, 0xcc, 0x60,
 318  						0x28, 0xd9, 0xcd, 0xb1, 0xc3, 0xaf, 0x77, 0x48,
 319  						0x01, // 73-byte signature
 320  						0x41, // OP_DATA_65
 321  						0x04, 0xf4, 0x6d, 0xb5, 0xe9, 0xd6, 0x1a, 0x9d,
 322  						0xc2, 0x7b, 0x8d, 0x64, 0xad, 0x23, 0xe7, 0x38,
 323  						0x3a, 0x4e, 0x6c, 0xa1, 0x64, 0x59, 0x3c, 0x25,
 324  						0x27, 0xc0, 0x38, 0xc0, 0x85, 0x7e, 0xb6, 0x7e,
 325  						0xe8, 0xe8, 0x25, 0xdc, 0xa6, 0x50, 0x46, 0xb8,
 326  						0x2c, 0x93, 0x31, 0x58, 0x6c, 0x82, 0xe0, 0xfd,
 327  						0x1f, 0x63, 0x3f, 0x25, 0xf8, 0x7c, 0x16, 0x1b,
 328  						0xc6, 0xf8, 0xa6, 0x30, 0x12, 0x1d, 0xf2, 0xb3,
 329  						0xd3, // 65-byte pubkey
 330  					},
 331  					Sequence: 0xffffffff,
 332  				},
 333  			},
 334  			TxOut: []*wire.TxOut{
 335  				{
 336  					Value: 0x2123e300, // 556000000
 337  					PkScript: []byte{
 338  						0x76, // OP_DUP
 339  						0xa9, // OP_HASH160
 340  						0x14, // OP_DATA_20
 341  						0xc3, 0x98, 0xef, 0xa9, 0xc3, 0x92, 0xba, 0x60,
 342  						0x13, 0xc5, 0xe0, 0x4e, 0xe7, 0x29, 0x75, 0x5e,
 343  						0xf7, 0xf5, 0x8b, 0x32,
 344  						0x88, // OP_EQUALVERIFY
 345  						0xac, // OP_CHECKSIG
 346  					},
 347  				},
 348  				{
 349  					Value: 0x108e20f00, // 4444000000
 350  					PkScript: []byte{
 351  						0x76, // OP_DUP
 352  						0xa9, // OP_HASH160
 353  						0x14, // OP_DATA_20
 354  						0x94, 0x8c, 0x76, 0x5a, 0x69, 0x14, 0xd4, 0x3f,
 355  						0x2a, 0x7a, 0xc1, 0x77, 0xda, 0x2c, 0x2f, 0x6b,
 356  						0x52, 0xde, 0x3d, 0x7c,
 357  						0x88, // OP_EQUALVERIFY
 358  						0xac, // OP_CHECKSIG
 359  					},
 360  				},
 361  			},
 362  			LockTime: 0,
 363  		},
 364  		{
 365  			Version: 1,
 366  			TxIn: []*wire.TxIn{
 367  				{
 368  					PreviousOutPoint: wire.OutPoint{
 369  						Hash: chainhash.Hash(
 370  							[32]byte{
 371  								// Make go vet happy.
 372  								0xc3, 0x3e, 0xbf, 0xf2, 0xa7, 0x09, 0xf1, 0x3d,
 373  								0x9f, 0x9a, 0x75, 0x69, 0xab, 0x16, 0xa3, 0x27,
 374  								0x86, 0xaf, 0x7d, 0x7e, 0x2d, 0xe0, 0x92, 0x65,
 375  								0xe4, 0x1c, 0x61, 0xd0, 0x78, 0x29, 0x4e, 0xcf,
 376  							},
 377  						), // cf4e2978d0611ce46592e02d7e7daf8627a316ab69759a9f3df109a7f2bf3ec3
 378  						Index: 1,
 379  					},
 380  					SignatureScript: []byte{
 381  						0x47, // OP_DATA_71
 382  						0x30, 0x44, 0x02, 0x20, 0x03, 0x2d, 0x30, 0xdf,
 383  						0x5e, 0xe6, 0xf5, 0x7f, 0xa4, 0x6c, 0xdd, 0xb5,
 384  						0xeb, 0x8d, 0x0d, 0x9f, 0xe8, 0xde, 0x6b, 0x34,
 385  						0x2d, 0x27, 0x94, 0x2a, 0xe9, 0x0a, 0x32, 0x31,
 386  						0xe0, 0xba, 0x33, 0x3e, 0x02, 0x20, 0x3d, 0xee,
 387  						0xe8, 0x06, 0x0f, 0xdc, 0x70, 0x23, 0x0a, 0x7f,
 388  						0x5b, 0x4a, 0xd7, 0xd7, 0xbc, 0x3e, 0x62, 0x8c,
 389  						0xbe, 0x21, 0x9a, 0x88, 0x6b, 0x84, 0x26, 0x9e,
 390  						0xae, 0xb8, 0x1e, 0x26, 0xb4, 0xfe, 0x01,
 391  						0x41, // OP_DATA_65
 392  						0x04, 0xae, 0x31, 0xc3, 0x1b, 0xf9, 0x12, 0x78,
 393  						0xd9, 0x9b, 0x83, 0x77, 0xa3, 0x5b, 0xbc, 0xe5,
 394  						0xb2, 0x7d, 0x9f, 0xff, 0x15, 0x45, 0x68, 0x39,
 395  						0xe9, 0x19, 0x45, 0x3f, 0xc7, 0xb3, 0xf7, 0x21,
 396  						0xf0, 0xba, 0x40, 0x3f, 0xf9, 0x6c, 0x9d, 0xee,
 397  						0xb6, 0x80, 0xe5, 0xfd, 0x34, 0x1c, 0x0f, 0xc3,
 398  						0xa7, 0xb9, 0x0d, 0xa4, 0x63, 0x1e, 0xe3, 0x95,
 399  						0x60, 0x63, 0x9d, 0xb4, 0x62, 0xe9, 0xcb, 0x85,
 400  						0x0f, // 65-byte pubkey
 401  					},
 402  					Sequence: 0xffffffff,
 403  				},
 404  			},
 405  			TxOut: []*wire.TxOut{
 406  				{
 407  					Value: 0xf4240, // 1000000
 408  					PkScript: []byte{
 409  						0x76, // OP_DUP
 410  						0xa9, // OP_HASH160
 411  						0x14, // OP_DATA_20
 412  						0xb0, 0xdc, 0xbf, 0x97, 0xea, 0xbf, 0x44, 0x04,
 413  						0xe3, 0x1d, 0x95, 0x24, 0x77, 0xce, 0x82, 0x2d,
 414  						0xad, 0xbe, 0x7e, 0x10,
 415  						0x88, // OP_EQUALVERIFY
 416  						0xac, // OP_CHECKSIG
 417  					},
 418  				},
 419  				{
 420  					Value: 0x11d260c0, // 299000000
 421  					PkScript: []byte{
 422  						0x76, // OP_DUP
 423  						0xa9, // OP_HASH160
 424  						0x14, // OP_DATA_20
 425  						0x6b, 0x12, 0x81, 0xee, 0xc2, 0x5a, 0xb4, 0xe1,
 426  						0xe0, 0x79, 0x3f, 0xf4, 0xe0, 0x8a, 0xb1, 0xab,
 427  						0xb3, 0x40, 0x9c, 0xd9,
 428  						0x88, // OP_EQUALVERIFY
 429  						0xac, // OP_CHECKSIG
 430  					},
 431  				},
 432  			},
 433  			LockTime: 0,
 434  		},
 435  		{
 436  			Version: 1,
 437  			TxIn: []*wire.TxIn{
 438  				{
 439  					PreviousOutPoint: wire.OutPoint{
 440  						Hash: chainhash.Hash(
 441  							[32]byte{
 442  								// Make go vet happy.
 443  								0x0b, 0x60, 0x72, 0xb3, 0x86, 0xd4, 0xa7, 0x73,
 444  								0x23, 0x52, 0x37, 0xf6, 0x4c, 0x11, 0x26, 0xac,
 445  								0x3b, 0x24, 0x0c, 0x84, 0xb9, 0x17, 0xa3, 0x90,
 446  								0x9b, 0xa1, 0xc4, 0x3d, 0xed, 0x5f, 0x51, 0xf4,
 447  							},
 448  						), // f4515fed3dc4a19b90a317b9840c243bac26114cf637522373a7d486b372600b
 449  						Index: 0,
 450  					},
 451  					SignatureScript: []byte{
 452  						0x49, // OP_DATA_73
 453  						0x30, 0x46, 0x02, 0x21, 0x00, 0xbb, 0x1a, 0xd2,
 454  						0x6d, 0xf9, 0x30, 0xa5, 0x1c, 0xce, 0x11, 0x0c,
 455  						0xf4, 0x4f, 0x7a, 0x48, 0xc3, 0xc5, 0x61, 0xfd,
 456  						0x97, 0x75, 0x00, 0xb1, 0xae, 0x5d, 0x6b, 0x6f,
 457  						0xd1, 0x3d, 0x0b, 0x3f, 0x4a, 0x02, 0x21, 0x00,
 458  						0xc5, 0xb4, 0x29, 0x51, 0xac, 0xed, 0xff, 0x14,
 459  						0xab, 0xba, 0x27, 0x36, 0xfd, 0x57, 0x4b, 0xdb,
 460  						0x46, 0x5f, 0x3e, 0x6f, 0x8d, 0xa1, 0x2e, 0x2c,
 461  						0x53, 0x03, 0x95, 0x4a, 0xca, 0x7f, 0x78, 0xf3,
 462  						0x01, // 73-byte signature
 463  						0x41, // OP_DATA_65
 464  						0x04, 0xa7, 0x13, 0x5b, 0xfe, 0x82, 0x4c, 0x97,
 465  						0xec, 0xc0, 0x1e, 0xc7, 0xd7, 0xe3, 0x36, 0x18,
 466  						0x5c, 0x81, 0xe2, 0xaa, 0x2c, 0x41, 0xab, 0x17,
 467  						0x54, 0x07, 0xc0, 0x94, 0x84, 0xce, 0x96, 0x94,
 468  						0xb4, 0x49, 0x53, 0xfc, 0xb7, 0x51, 0x20, 0x65,
 469  						0x64, 0xa9, 0xc2, 0x4d, 0xd0, 0x94, 0xd4, 0x2f,
 470  						0xdb, 0xfd, 0xd5, 0xaa, 0xd3, 0xe0, 0x63, 0xce,
 471  						0x6a, 0xf4, 0xcf, 0xaa, 0xea, 0x4e, 0xa1, 0x4f,
 472  						0xbb, // 65-byte pubkey
 473  					},
 474  					Sequence: 0xffffffff,
 475  				},
 476  			},
 477  			TxOut: []*wire.TxOut{
 478  				{
 479  					Value: 0xf4240, // 1000000
 480  					PkScript: []byte{
 481  						0x76, // OP_DUP
 482  						0xa9, // OP_HASH160
 483  						0x14, // OP_DATA_20
 484  						0x39, 0xaa, 0x3d, 0x56, 0x9e, 0x06, 0xa1, 0xd7,
 485  						0x92, 0x6d, 0xc4, 0xbe, 0x11, 0x93, 0xc9, 0x9b,
 486  						0xf2, 0xeb, 0x9e, 0xe0,
 487  						0x88, // OP_EQUALVERIFY
 488  						0xac, // OP_CHECKSIG
 489  					},
 490  				},
 491  			},
 492  			LockTime: 0,
 493  		},
 494  	},
 495  }
 496