github.com/dashpay/godash@v0.0.0-20160726055534-e038a21e0e3d/txscript/engine_test.go (about)

     1  // Copyright (c) 2013-2015 The btcsuite developers
     2  // Copyright (c) 2016 The Dash developers
     3  // Use of this source code is governed by an ISC
     4  // license that can be found in the LICENSE file.
     5  
     6  package txscript_test
     7  
     8  import (
     9  	"testing"
    10  
    11  	"github.com/dashpay/godash/txscript"
    12  	"github.com/dashpay/godash/wire"
    13  )
    14  
    15  // TestBadPC sets the pc to a deliberately bad result then confirms that Step()
    16  // and Disasm fail correctly.
    17  func TestBadPC(t *testing.T) {
    18  	t.Parallel()
    19  
    20  	type pcTest struct {
    21  		script, off int
    22  	}
    23  	pcTests := []pcTest{
    24  		{
    25  			script: 2,
    26  			off:    0,
    27  		},
    28  		{
    29  			script: 0,
    30  			off:    2,
    31  		},
    32  	}
    33  	// tx with almost empty scripts.
    34  	tx := &wire.MsgTx{
    35  		Version: 1,
    36  		TxIn: []*wire.TxIn{
    37  			{
    38  				PreviousOutPoint: wire.OutPoint{
    39  					Hash: wire.ShaHash([32]byte{
    40  						0xc9, 0x97, 0xa5, 0xe5,
    41  						0x6e, 0x10, 0x41, 0x02,
    42  						0xfa, 0x20, 0x9c, 0x6a,
    43  						0x85, 0x2d, 0xd9, 0x06,
    44  						0x60, 0xa2, 0x0b, 0x2d,
    45  						0x9c, 0x35, 0x24, 0x23,
    46  						0xed, 0xce, 0x25, 0x85,
    47  						0x7f, 0xcd, 0x37, 0x04,
    48  					}),
    49  					Index: 0,
    50  				},
    51  				SignatureScript: []uint8{txscript.OP_NOP},
    52  				Sequence:        4294967295,
    53  			},
    54  		},
    55  		TxOut: []*wire.TxOut{
    56  			{
    57  				Value:    1000000000,
    58  				PkScript: nil,
    59  			},
    60  		},
    61  		LockTime: 0,
    62  	}
    63  	pkScript := []byte{txscript.OP_NOP}
    64  
    65  	for _, test := range pcTests {
    66  		vm, err := txscript.NewEngine(pkScript, tx, 0, 0, nil)
    67  		if err != nil {
    68  			t.Errorf("Failed to create script: %v", err)
    69  		}
    70  
    71  		// set to after all scripts
    72  		vm.TstSetPC(test.script, test.off)
    73  
    74  		_, err = vm.Step()
    75  		if err == nil {
    76  			t.Errorf("Step with invalid pc (%v) succeeds!", test)
    77  			continue
    78  		}
    79  
    80  		_, err = vm.DisasmPC()
    81  		if err == nil {
    82  			t.Errorf("DisasmPC with invalid pc (%v) succeeds!",
    83  				test)
    84  		}
    85  	}
    86  }
    87  
    88  // TestCheckErrorCondition tests the execute early test in CheckErrorCondition()
    89  // since most code paths are tested elsewhere.
    90  func TestCheckErrorCondition(t *testing.T) {
    91  	t.Parallel()
    92  
    93  	// tx with almost empty scripts.
    94  	tx := &wire.MsgTx{
    95  		Version: 1,
    96  		TxIn: []*wire.TxIn{
    97  			{
    98  				PreviousOutPoint: wire.OutPoint{
    99  					Hash: wire.ShaHash([32]byte{
   100  						0xc9, 0x97, 0xa5, 0xe5,
   101  						0x6e, 0x10, 0x41, 0x02,
   102  						0xfa, 0x20, 0x9c, 0x6a,
   103  						0x85, 0x2d, 0xd9, 0x06,
   104  						0x60, 0xa2, 0x0b, 0x2d,
   105  						0x9c, 0x35, 0x24, 0x23,
   106  						0xed, 0xce, 0x25, 0x85,
   107  						0x7f, 0xcd, 0x37, 0x04,
   108  					}),
   109  					Index: 0,
   110  				},
   111  				SignatureScript: []uint8{},
   112  				Sequence:        4294967295,
   113  			},
   114  		},
   115  		TxOut: []*wire.TxOut{
   116  			{
   117  				Value:    1000000000,
   118  				PkScript: nil,
   119  			},
   120  		},
   121  		LockTime: 0,
   122  	}
   123  	pkScript := []byte{
   124  		txscript.OP_NOP,
   125  		txscript.OP_NOP,
   126  		txscript.OP_NOP,
   127  		txscript.OP_NOP,
   128  		txscript.OP_NOP,
   129  		txscript.OP_NOP,
   130  		txscript.OP_NOP,
   131  		txscript.OP_NOP,
   132  		txscript.OP_NOP,
   133  		txscript.OP_NOP,
   134  		txscript.OP_TRUE,
   135  	}
   136  
   137  	vm, err := txscript.NewEngine(pkScript, tx, 0, 0, nil)
   138  	if err != nil {
   139  		t.Errorf("failed to create script: %v", err)
   140  	}
   141  
   142  	for i := 0; i < len(pkScript)-1; i++ {
   143  		done, err := vm.Step()
   144  		if err != nil {
   145  			t.Errorf("failed to step %dth time: %v", i, err)
   146  			return
   147  		}
   148  		if done {
   149  			t.Errorf("finshed early on %dth time", i)
   150  			return
   151  		}
   152  
   153  		err = vm.CheckErrorCondition(false)
   154  		if err != txscript.ErrStackScriptUnfinished {
   155  			t.Errorf("got unexepected error %v on %dth iteration",
   156  				err, i)
   157  			return
   158  		}
   159  	}
   160  	done, err := vm.Step()
   161  	if err != nil {
   162  		t.Errorf("final step failed %v", err)
   163  		return
   164  	}
   165  	if !done {
   166  		t.Errorf("final step isn't done!")
   167  		return
   168  	}
   169  
   170  	err = vm.CheckErrorCondition(false)
   171  	if err != nil {
   172  		t.Errorf("unexpected error %v on final check", err)
   173  	}
   174  }
   175  
   176  // TestInvalidFlagCombinations ensures the script engine returns the expected
   177  // error when disallowed flag combinations are specified.
   178  func TestInvalidFlagCombinations(t *testing.T) {
   179  	t.Parallel()
   180  
   181  	tests := []txscript.ScriptFlags{
   182  		txscript.ScriptVerifyCleanStack,
   183  	}
   184  
   185  	// tx with almost empty scripts.
   186  	tx := &wire.MsgTx{
   187  		Version: 1,
   188  		TxIn: []*wire.TxIn{
   189  			{
   190  				PreviousOutPoint: wire.OutPoint{
   191  					Hash: wire.ShaHash([32]byte{
   192  						0xc9, 0x97, 0xa5, 0xe5,
   193  						0x6e, 0x10, 0x41, 0x02,
   194  						0xfa, 0x20, 0x9c, 0x6a,
   195  						0x85, 0x2d, 0xd9, 0x06,
   196  						0x60, 0xa2, 0x0b, 0x2d,
   197  						0x9c, 0x35, 0x24, 0x23,
   198  						0xed, 0xce, 0x25, 0x85,
   199  						0x7f, 0xcd, 0x37, 0x04,
   200  					}),
   201  					Index: 0,
   202  				},
   203  				SignatureScript: []uint8{txscript.OP_NOP},
   204  				Sequence:        4294967295,
   205  			},
   206  		},
   207  		TxOut: []*wire.TxOut{
   208  			{
   209  				Value:    1000000000,
   210  				PkScript: nil,
   211  			},
   212  		},
   213  		LockTime: 0,
   214  	}
   215  	pkScript := []byte{txscript.OP_NOP}
   216  
   217  	for i, test := range tests {
   218  		_, err := txscript.NewEngine(pkScript, tx, 0, test, nil)
   219  		if err != txscript.ErrInvalidFlags {
   220  			t.Fatalf("TestInvalidFlagCombinations #%d unexpected "+
   221  				"error: %v", i, err)
   222  		}
   223  	}
   224  }
   225  
   226  // TestCheckPubKeyEncoding ensures the internal checkPubKeyEncoding function
   227  // works as expected.
   228  func TestCheckPubKeyEncoding(t *testing.T) {
   229  	t.Parallel()
   230  
   231  	tests := []struct {
   232  		name    string
   233  		key     []byte
   234  		isValid bool
   235  	}{
   236  		{
   237  			name: "uncompressed ok",
   238  			key: decodeHex("0411db93e1dcdb8a016b49840f8c53bc1eb68" +
   239  				"a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf" +
   240  				"9744464f82e160bfa9b8b64f9d4c03f999b8643f656b" +
   241  				"412a3"),
   242  			isValid: true,
   243  		},
   244  		{
   245  			name: "compressed ok",
   246  			key: decodeHex("02ce0b14fb842b1ba549fdd675c98075f12e9" +
   247  				"c510f8ef52bd021a9a1f4809d3b4d"),
   248  			isValid: true,
   249  		},
   250  		{
   251  			name: "compressed ok",
   252  			key: decodeHex("032689c7c2dab13309fb143e0e8fe39634252" +
   253  				"1887e976690b6b47f5b2a4b7d448e"),
   254  			isValid: true,
   255  		},
   256  		{
   257  			name: "hybrid",
   258  			key: decodeHex("0679be667ef9dcbbac55a06295ce870b07029" +
   259  				"bfcdb2dce28d959f2815b16f81798483ada7726a3c46" +
   260  				"55da4fbfc0e1108a8fd17b448a68554199c47d08ffb1" +
   261  				"0d4b8"),
   262  			isValid: false,
   263  		},
   264  		{
   265  			name:    "empty",
   266  			key:     nil,
   267  			isValid: false,
   268  		},
   269  	}
   270  
   271  	flags := txscript.ScriptVerifyStrictEncoding
   272  	for _, test := range tests {
   273  		err := txscript.TstCheckPubKeyEncoding(test.key, flags)
   274  		if err != nil && test.isValid {
   275  			t.Errorf("checkSignatureEncoding test '%s' failed "+
   276  				"when it should have succeeded: %v", test.name,
   277  				err)
   278  		} else if err == nil && !test.isValid {
   279  			t.Errorf("checkSignatureEncooding test '%s' succeeded "+
   280  				"when it should have failed", test.name)
   281  		}
   282  	}
   283  
   284  }
   285  
   286  // TestCheckSignatureEncoding ensures the internal checkSignatureEncoding
   287  // function works as expected.
   288  func TestCheckSignatureEncoding(t *testing.T) {
   289  	t.Parallel()
   290  
   291  	tests := []struct {
   292  		name    string
   293  		sig     []byte
   294  		isValid bool
   295  	}{
   296  		{
   297  			name: "valid signature",
   298  			sig: decodeHex("304402204e45e16932b8af514961a1d3a1a25" +
   299  				"fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
   300  				"2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
   301  				"82221a8768d1d09"),
   302  			isValid: true,
   303  		},
   304  		{
   305  			name:    "empty.",
   306  			sig:     nil,
   307  			isValid: false,
   308  		},
   309  		{
   310  			name: "bad magic",
   311  			sig: decodeHex("314402204e45e16932b8af514961a1d3a1a25" +
   312  				"fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
   313  				"2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
   314  				"82221a8768d1d09"),
   315  			isValid: false,
   316  		},
   317  		{
   318  			name: "bad 1st int marker magic",
   319  			sig: decodeHex("304403204e45e16932b8af514961a1d3a1a25" +
   320  				"fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
   321  				"2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
   322  				"82221a8768d1d09"),
   323  			isValid: false,
   324  		},
   325  		{
   326  			name: "bad 2nd int marker",
   327  			sig: decodeHex("304402204e45e16932b8af514961a1d3a1a25" +
   328  				"fdf3f4f7732e9d624c6c61548ab5fb8cd41032018152" +
   329  				"2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
   330  				"82221a8768d1d09"),
   331  			isValid: false,
   332  		},
   333  		{
   334  			name: "short len",
   335  			sig: decodeHex("304302204e45e16932b8af514961a1d3a1a25" +
   336  				"fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
   337  				"2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
   338  				"82221a8768d1d09"),
   339  			isValid: false,
   340  		},
   341  		{
   342  			name: "long len",
   343  			sig: decodeHex("304502204e45e16932b8af514961a1d3a1a25" +
   344  				"fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
   345  				"2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
   346  				"82221a8768d1d09"),
   347  			isValid: false,
   348  		},
   349  		{
   350  			name: "long X",
   351  			sig: decodeHex("304402424e45e16932b8af514961a1d3a1a25" +
   352  				"fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
   353  				"2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
   354  				"82221a8768d1d09"),
   355  			isValid: false,
   356  		},
   357  		{
   358  			name: "long Y",
   359  			sig: decodeHex("304402204e45e16932b8af514961a1d3a1a25" +
   360  				"fdf3f4f7732e9d624c6c61548ab5fb8cd41022118152" +
   361  				"2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
   362  				"82221a8768d1d09"),
   363  			isValid: false,
   364  		},
   365  		{
   366  			name: "short Y",
   367  			sig: decodeHex("304402204e45e16932b8af514961a1d3a1a25" +
   368  				"fdf3f4f7732e9d624c6c61548ab5fb8cd41021918152" +
   369  				"2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
   370  				"82221a8768d1d09"),
   371  			isValid: false,
   372  		},
   373  		{
   374  			name: "trailing crap",
   375  			sig: decodeHex("304402204e45e16932b8af514961a1d3a1a25" +
   376  				"fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
   377  				"2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
   378  				"82221a8768d1d0901"),
   379  			isValid: false,
   380  		},
   381  		{
   382  			name: "X == N ",
   383  			sig: decodeHex("30440220fffffffffffffffffffffffffffff" +
   384  				"ffebaaedce6af48a03bbfd25e8cd0364141022018152" +
   385  				"2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
   386  				"82221a8768d1d09"),
   387  			isValid: false,
   388  		},
   389  		{
   390  			name: "X == N ",
   391  			sig: decodeHex("30440220fffffffffffffffffffffffffffff" +
   392  				"ffebaaedce6af48a03bbfd25e8cd0364142022018152" +
   393  				"2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
   394  				"82221a8768d1d09"),
   395  			isValid: false,
   396  		},
   397  		{
   398  			name: "Y == N",
   399  			sig: decodeHex("304402204e45e16932b8af514961a1d3a1a25" +
   400  				"fdf3f4f7732e9d624c6c61548ab5fb8cd410220fffff" +
   401  				"ffffffffffffffffffffffffffebaaedce6af48a03bb" +
   402  				"fd25e8cd0364141"),
   403  			isValid: false,
   404  		},
   405  		{
   406  			name: "Y > N",
   407  			sig: decodeHex("304402204e45e16932b8af514961a1d3a1a25" +
   408  				"fdf3f4f7732e9d624c6c61548ab5fb8cd410220fffff" +
   409  				"ffffffffffffffffffffffffffebaaedce6af48a03bb" +
   410  				"fd25e8cd0364142"),
   411  			isValid: false,
   412  		},
   413  		{
   414  			name: "0 len X",
   415  			sig: decodeHex("302402000220181522ec8eca07de4860a4acd" +
   416  				"d12909d831cc56cbbac4622082221a8768d1d09"),
   417  			isValid: false,
   418  		},
   419  		{
   420  			name: "0 len Y",
   421  			sig: decodeHex("302402204e45e16932b8af514961a1d3a1a25" +
   422  				"fdf3f4f7732e9d624c6c61548ab5fb8cd410200"),
   423  			isValid: false,
   424  		},
   425  		{
   426  			name: "extra R padding",
   427  			sig: decodeHex("30450221004e45e16932b8af514961a1d3a1a" +
   428  				"25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181" +
   429  				"522ec8eca07de4860a4acdd12909d831cc56cbbac462" +
   430  				"2082221a8768d1d09"),
   431  			isValid: false,
   432  		},
   433  		{
   434  			name: "extra S padding",
   435  			sig: decodeHex("304502204e45e16932b8af514961a1d3a1a25" +
   436  				"fdf3f4f7732e9d624c6c61548ab5fb8cd41022100181" +
   437  				"522ec8eca07de4860a4acdd12909d831cc56cbbac462" +
   438  				"2082221a8768d1d09"),
   439  			isValid: false,
   440  		},
   441  	}
   442  
   443  	flags := txscript.ScriptVerifyStrictEncoding
   444  	for _, test := range tests {
   445  		err := txscript.TstCheckSignatureEncoding(test.sig, flags)
   446  		if err != nil && test.isValid {
   447  			t.Errorf("checkSignatureEncoding test '%s' failed "+
   448  				"when it should have succeeded: %v", test.name,
   449  				err)
   450  		} else if err == nil && !test.isValid {
   451  			t.Errorf("checkSignatureEncooding test '%s' succeeded "+
   452  				"when it should have failed", test.name)
   453  		}
   454  	}
   455  }