parent
158f0d9d9c
commit
dd05cae506
2 changed files with 56 additions and 2 deletions
|
@ -1380,6 +1380,7 @@ var (
|
|||
ErrTxSmallNetworkFee = errors.New("too small network fee")
|
||||
ErrTxTooBig = errors.New("too big transaction")
|
||||
ErrMemPoolConflict = errors.New("invalid transaction due to conflicts with the memory pool")
|
||||
ErrInvalidScript = errors.New("invalid script")
|
||||
ErrTxInvalidWitnessNum = errors.New("number of signers doesn't match witnesses")
|
||||
ErrInvalidAttribute = errors.New("invalid attribute")
|
||||
)
|
||||
|
@ -1387,6 +1388,13 @@ var (
|
|||
// verifyAndPoolTx verifies whether a transaction is bonafide or not and tries
|
||||
// to add it to the mempool given.
|
||||
func (bc *Blockchain) verifyAndPoolTx(t *transaction.Transaction, pool *mempool.Pool, feer mempool.Feer, data ...interface{}) error {
|
||||
// This code can technically be moved out of here, because it doesn't
|
||||
// really require a chain lock.
|
||||
err := vm.IsScriptCorrect(t.Script, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %v", ErrInvalidScript, err)
|
||||
}
|
||||
|
||||
height := bc.BlockHeight()
|
||||
isPartialTx := data != nil
|
||||
if t.ValidUntilBlock <= height || !isPartialTx && t.ValidUntilBlock > height+transaction.MaxValidUntilBlockIncrement {
|
||||
|
@ -1424,7 +1432,7 @@ func (bc *Blockchain) verifyAndPoolTx(t *transaction.Transaction, pool *mempool.
|
|||
return err
|
||||
}
|
||||
}
|
||||
err := bc.verifyTxWitnesses(t, nil, isPartialTx)
|
||||
err = bc.verifyTxWitnesses(t, nil, isPartialTx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1728,7 +1736,9 @@ var (
|
|||
ErrWitnessHashMismatch = errors.New("witness hash mismatch")
|
||||
ErrNativeContractWitness = errors.New("native contract witness must have empty verification script")
|
||||
ErrVerificationFailed = errors.New("signature check failed")
|
||||
ErrInvalidInvocation = errors.New("invalid invocation script")
|
||||
ErrInvalidSignature = fmt.Errorf("%w: invalid signature", ErrVerificationFailed)
|
||||
ErrInvalidVerification = errors.New("invalid verification script")
|
||||
ErrUnknownVerificationContract = errors.New("unknown verification contract")
|
||||
ErrInvalidVerificationContract = errors.New("verification contract is missing `verify` method")
|
||||
)
|
||||
|
@ -1744,6 +1754,10 @@ func (bc *Blockchain) initVerificationVM(ic *interop.Context, hash util.Uint160,
|
|||
if bc.contracts.ByHash(hash) != nil {
|
||||
return ErrNativeContractWitness
|
||||
}
|
||||
err := vm.IsScriptCorrect(witness.VerificationScript, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %v", ErrInvalidVerification, err)
|
||||
}
|
||||
v.LoadScriptWithFlags(witness.VerificationScript, callflag.ReadStates)
|
||||
} else {
|
||||
cs, err := ic.GetContract(hash)
|
||||
|
@ -1765,6 +1779,10 @@ func (bc *Blockchain) initVerificationVM(ic *interop.Context, hash util.Uint160,
|
|||
}
|
||||
}
|
||||
if len(witness.InvocationScript) != 0 {
|
||||
err := vm.IsScriptCorrect(witness.InvocationScript, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %v", ErrInvalidInvocation, err)
|
||||
}
|
||||
v.LoadScript(witness.InvocationScript)
|
||||
if isNative {
|
||||
if err := v.StepOut(); err != nil {
|
||||
|
|
|
@ -390,6 +390,42 @@ func TestVerifyTx(t *testing.T) {
|
|||
require.Equal(t, expectedNetFee, bc.FeePerByte()*int64(actualSize)+gasConsumed)
|
||||
})
|
||||
})
|
||||
t.Run("InvalidTxScript", func(t *testing.T) {
|
||||
tx := bc.newTestTx(h, testScript)
|
||||
tx.Script = append(tx.Script, 0xff)
|
||||
require.NoError(t, accs[0].SignTx(tx))
|
||||
checkErr(t, ErrInvalidScript, tx)
|
||||
})
|
||||
t.Run("InvalidVerificationScript", func(t *testing.T) {
|
||||
tx := bc.newTestTx(h, testScript)
|
||||
verif := []byte{byte(opcode.JMP), 3, 0xff, byte(opcode.PUSHT)}
|
||||
tx.Signers = append(tx.Signers, transaction.Signer{
|
||||
Account: hash.Hash160(verif),
|
||||
Scopes: transaction.Global,
|
||||
})
|
||||
tx.NetworkFee += 1000000
|
||||
require.NoError(t, accs[0].SignTx(tx))
|
||||
tx.Scripts = append(tx.Scripts, transaction.Witness{
|
||||
InvocationScript: []byte{},
|
||||
VerificationScript: verif,
|
||||
})
|
||||
checkErr(t, ErrInvalidVerification, tx)
|
||||
})
|
||||
t.Run("InvalidInvocationScript", func(t *testing.T) {
|
||||
tx := bc.newTestTx(h, testScript)
|
||||
verif := []byte{byte(opcode.PUSHT)}
|
||||
tx.Signers = append(tx.Signers, transaction.Signer{
|
||||
Account: hash.Hash160(verif),
|
||||
Scopes: transaction.Global,
|
||||
})
|
||||
tx.NetworkFee += 1000000
|
||||
require.NoError(t, accs[0].SignTx(tx))
|
||||
tx.Scripts = append(tx.Scripts, transaction.Witness{
|
||||
InvocationScript: []byte{byte(opcode.JMP), 3, 0xff},
|
||||
VerificationScript: verif,
|
||||
})
|
||||
checkErr(t, ErrInvalidInvocation, tx)
|
||||
})
|
||||
t.Run("Conflict", func(t *testing.T) {
|
||||
balance := bc.GetUtilityTokenBalance(h).Int64()
|
||||
tx := bc.newTestTx(h, testScript)
|
||||
|
@ -583,7 +619,7 @@ func TestVerifyTx(t *testing.T) {
|
|||
})
|
||||
t.Run("InvalidScript", func(t *testing.T) {
|
||||
tx := getOracleTx(t)
|
||||
tx.Script[0] = ^tx.Script[0]
|
||||
tx.Script = append(tx.Script, byte(opcode.NOP))
|
||||
require.NoError(t, oracleAcc.SignTx(tx))
|
||||
checkErr(t, ErrInvalidAttribute, tx)
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue