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