forked from TrueCloudLab/neoneo-go
core: add ScriptFromWitness function
Extracting verification script from witness became a common task. This commit adds such a possibility.
This commit is contained in:
parent
9cc0fca9d2
commit
714c466c2c
2 changed files with 41 additions and 8 deletions
|
@ -1372,21 +1372,30 @@ func (bc *Blockchain) GetTestVM() (*vm.VM, storage.Store) {
|
||||||
return vm, tmpStore
|
return vm, tmpStore
|
||||||
}
|
}
|
||||||
|
|
||||||
// verifyHashAgainstScript verifies given hash against the given witness.
|
// ScriptFromWitness returns verification script for provided witness.
|
||||||
func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transaction.Witness, checkedHash util.Uint256, interopCtx *interopContext, useKeys bool) error {
|
// If hash is not equal to the witness script hash, error is returned.
|
||||||
|
func ScriptFromWitness(hash util.Uint160, witness *transaction.Witness) ([]byte, error) {
|
||||||
verification := witness.VerificationScript
|
verification := witness.VerificationScript
|
||||||
|
|
||||||
if len(verification) == 0 {
|
if len(verification) == 0 {
|
||||||
bb := new(bytes.Buffer)
|
bb := new(bytes.Buffer)
|
||||||
err := vm.EmitAppCall(bb, hash, false)
|
err := vm.EmitAppCall(bb, hash, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
verification = bb.Bytes()
|
verification = bb.Bytes()
|
||||||
} else {
|
} else if h := witness.ScriptHash(); hash != h {
|
||||||
if h := witness.ScriptHash(); hash != h {
|
return nil, errors.New("witness hash mismatch")
|
||||||
return errors.New("witness hash mismatch")
|
}
|
||||||
}
|
|
||||||
|
return verification, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// verifyHashAgainstScript verifies given hash against the given witness.
|
||||||
|
func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transaction.Witness, checkedHash util.Uint256, interopCtx *interopContext, useKeys bool) error {
|
||||||
|
verification, err := ScriptFromWitness(hash, witness)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
vm := bc.spawnVMWithInterops(interopCtx)
|
vm := bc.spawnVMWithInterops(interopCtx)
|
||||||
|
@ -1396,7 +1405,7 @@ func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transa
|
||||||
if useKeys && bc.keyCache[hash] != nil {
|
if useKeys && bc.keyCache[hash] != nil {
|
||||||
vm.SetPublicKeys(bc.keyCache[hash])
|
vm.SetPublicKeys(bc.keyCache[hash])
|
||||||
}
|
}
|
||||||
err := vm.Run()
|
err = vm.Run()
|
||||||
if vm.HasFailed() {
|
if vm.HasFailed() {
|
||||||
return errors.Errorf("vm failed to execute the script with error: %s", err)
|
return errors.Errorf("vm failed to execute the script with error: %s", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,10 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/core/storage"
|
"github.com/CityOfZion/neo-go/pkg/core/storage"
|
||||||
|
"github.com/CityOfZion/neo-go/pkg/core/transaction"
|
||||||
|
"github.com/CityOfZion/neo-go/pkg/crypto/hash"
|
||||||
"github.com/CityOfZion/neo-go/pkg/io"
|
"github.com/CityOfZion/neo-go/pkg/io"
|
||||||
|
"github.com/CityOfZion/neo-go/pkg/util"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
@ -65,6 +68,27 @@ func TestAddBlock(t *testing.T) {
|
||||||
assert.Equal(t, lastBlock.Hash(), bc.CurrentHeaderHash())
|
assert.Equal(t, lastBlock.Hash(), bc.CurrentHeaderHash())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestScriptFromWitness(t *testing.T) {
|
||||||
|
witness := &transaction.Witness{}
|
||||||
|
h := util.Uint160{1, 2, 3}
|
||||||
|
|
||||||
|
res, err := ScriptFromWitness(h, witness)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, res)
|
||||||
|
|
||||||
|
witness.VerificationScript = []byte{4, 8, 15, 16, 23, 42}
|
||||||
|
h = hash.Hash160(witness.VerificationScript)
|
||||||
|
|
||||||
|
res, err = ScriptFromWitness(h, witness)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, res)
|
||||||
|
|
||||||
|
h[0] = ^h[0]
|
||||||
|
res, err = ScriptFromWitness(h, witness)
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Nil(t, res)
|
||||||
|
}
|
||||||
|
|
||||||
func TestGetHeader(t *testing.T) {
|
func TestGetHeader(t *testing.T) {
|
||||||
bc := newTestChain(t)
|
bc := newTestChain(t)
|
||||||
block := newBlock(1, newMinerTX())
|
block := newBlock(1, newMinerTX())
|
||||||
|
|
Loading…
Reference in a new issue