forked from TrueCloudLab/neoneo-go
core: implement (*Blockchain).VerifyWitness
`ScriptFromWitness` is no longer useful, because we support contract verification.
This commit is contained in:
parent
4e7a1f6c87
commit
7e34072519
8 changed files with 67 additions and 102 deletions
|
@ -246,7 +246,7 @@ func (s *service) validatePayload(p *Payload) bool {
|
||||||
pub := validators[p.validatorIndex]
|
pub := validators[p.validatorIndex]
|
||||||
h := pub.(*publicKey).GetScriptHash()
|
h := pub.(*publicKey).GetScriptHash()
|
||||||
|
|
||||||
return p.Verify(h)
|
return s.Chain.VerifyWitness(h, p, &p.Witness, payloadGasLimit) == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) getKeyPair(pubs []crypto.PublicKey) (int, crypto.PrivateKey, crypto.PublicKey) {
|
func (s *service) getKeyPair(pubs []crypto.PublicKey) (int, crypto.PrivateKey, crypto.PublicKey) {
|
||||||
|
|
|
@ -6,13 +6,9 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/dbft/payload"
|
"github.com/nspcc-dev/dbft/payload"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/crypto"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||||
)
|
)
|
||||||
|
@ -215,28 +211,6 @@ func (p *Payload) GetSignedPart() []byte {
|
||||||
return p.MarshalUnsigned()
|
return p.MarshalUnsigned()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify verifies payload using provided Witness.
|
|
||||||
func (p *Payload) Verify(scriptHash util.Uint160) bool {
|
|
||||||
verification, err := core.ScriptFromWitness(scriptHash, &p.Witness)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
ic := &interop.Context{Trigger: trigger.Verification, Container: p}
|
|
||||||
crypto.Register(ic)
|
|
||||||
v := ic.SpawnVM()
|
|
||||||
v.GasLimit = payloadGasLimit
|
|
||||||
v.LoadScript(verification)
|
|
||||||
v.LoadScript(p.Witness.InvocationScript)
|
|
||||||
|
|
||||||
err = v.Run()
|
|
||||||
if err != nil || v.HasFailed() || v.Estack().Len() != 1 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return v.Estack().Pop().Bool()
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeBinaryUnsigned reads payload from w excluding signature.
|
// DecodeBinaryUnsigned reads payload from w excluding signature.
|
||||||
func (p *Payload) DecodeBinaryUnsigned(r *io.BinReader) {
|
func (p *Payload) DecodeBinaryUnsigned(r *io.BinReader) {
|
||||||
p.version = r.ReadU32LE()
|
p.version = r.ReadU32LE()
|
||||||
|
|
|
@ -88,7 +88,9 @@ func TestConsensusPayload_Verify(t *testing.T) {
|
||||||
p := NewPayload(netmode.TestNet)
|
p := NewPayload(netmode.TestNet)
|
||||||
require.NoError(t, testserdes.DecodeBinary(data, p))
|
require.NoError(t, testserdes.DecodeBinary(data, p))
|
||||||
require.NoError(t, p.decodeData())
|
require.NoError(t, p.decodeData())
|
||||||
require.True(t, p.Verify(h))
|
bc := newTestChain(t)
|
||||||
|
defer bc.Close()
|
||||||
|
require.NoError(t, bc.VerifyWitness(h, p, &p.Witness, payloadGasLimit))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConsensusPayload_Serializable(t *testing.T) {
|
func TestConsensusPayload_Serializable(t *testing.T) {
|
||||||
|
@ -307,10 +309,14 @@ func TestPayload_Sign(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
priv := &privateKey{key}
|
priv := &privateKey{key}
|
||||||
|
|
||||||
p := randomPayload(t, prepareRequestType)
|
p := randomPayload(t, prepareRequestType)
|
||||||
require.False(t, p.Verify(util.Uint160{}))
|
h := priv.PublicKey().GetScriptHash()
|
||||||
|
bc := newTestChain(t)
|
||||||
|
defer bc.Close()
|
||||||
|
require.Error(t, bc.VerifyWitness(h, p, &p.Witness, payloadGasLimit))
|
||||||
require.NoError(t, p.Sign(priv))
|
require.NoError(t, p.Sign(priv))
|
||||||
require.True(t, p.Verify(p.Witness.ScriptHash()))
|
require.NoError(t, bc.VerifyWitness(h, p, &p.Witness, payloadGasLimit))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMessageType_String(t *testing.T) {
|
func TestMessageType_String(t *testing.T) {
|
||||||
|
|
|
@ -9,22 +9,23 @@ import (
|
||||||
"github.com/nspcc-dev/dbft/payload"
|
"github.com/nspcc-dev/dbft/payload"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/internal/testchain"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRecoveryMessage_Setters(t *testing.T) {
|
func TestRecoveryMessage_Setters(t *testing.T) {
|
||||||
const size = 5
|
srv := newTestService(t)
|
||||||
|
defer srv.Chain.Close()
|
||||||
privs := getKeys(t, size)
|
privs := make([]*privateKey, testchain.Size())
|
||||||
pubs := make([]crypto.PublicKey, 5)
|
pubs := make([]crypto.PublicKey, testchain.Size())
|
||||||
for i := range pubs {
|
for i := 0; i < testchain.Size(); i++ {
|
||||||
pubs[i] = &publicKey{privs[i].PublicKey()}
|
privs[i], pubs[i] = getTestValidator(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
r := &recoveryMessage{}
|
r := &recoveryMessage{}
|
||||||
p := new(Payload)
|
p := NewPayload(netmode.UnitTestNet)
|
||||||
p.message = &message{}
|
p.message = &message{}
|
||||||
p.SetType(payload.RecoveryMessageType)
|
p.SetType(payload.RecoveryMessageType)
|
||||||
p.SetPayload(r)
|
p.SetPayload(r)
|
||||||
|
@ -36,7 +37,7 @@ func TestRecoveryMessage_Setters(t *testing.T) {
|
||||||
nonce: 321,
|
nonce: 321,
|
||||||
transactionHashes: []util.Uint256{{1}},
|
transactionHashes: []util.Uint256{{1}},
|
||||||
}
|
}
|
||||||
p1 := new(Payload)
|
p1 := NewPayload(netmode.UnitTestNet)
|
||||||
p1.message = &message{}
|
p1.message = &message{}
|
||||||
p1.SetType(payload.PrepareRequestType)
|
p1.SetType(payload.PrepareRequestType)
|
||||||
p1.SetPayload(req)
|
p1.SetPayload(req)
|
||||||
|
@ -44,7 +45,7 @@ func TestRecoveryMessage_Setters(t *testing.T) {
|
||||||
require.NoError(t, p1.Sign(privs[0]))
|
require.NoError(t, p1.Sign(privs[0]))
|
||||||
|
|
||||||
t.Run("prepare response is added", func(t *testing.T) {
|
t.Run("prepare response is added", func(t *testing.T) {
|
||||||
p2 := new(Payload)
|
p2 := NewPayload(netmode.UnitTestNet)
|
||||||
p2.message = &message{}
|
p2.message = &message{}
|
||||||
p2.SetType(payload.PrepareResponseType)
|
p2.SetType(payload.PrepareResponseType)
|
||||||
p2.SetPayload(&prepareResponse{
|
p2.SetPayload(&prepareResponse{
|
||||||
|
@ -61,7 +62,7 @@ func TestRecoveryMessage_Setters(t *testing.T) {
|
||||||
require.Len(t, ps, 1)
|
require.Len(t, ps, 1)
|
||||||
require.Equal(t, p2, ps[0])
|
require.Equal(t, p2, ps[0])
|
||||||
ps0 := ps[0].(*Payload)
|
ps0 := ps[0].(*Payload)
|
||||||
require.True(t, ps0.Verify(ps0.Witness.ScriptHash()))
|
require.True(t, srv.validatePayload(ps0))
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("prepare request is added", func(t *testing.T) {
|
t.Run("prepare request is added", func(t *testing.T) {
|
||||||
|
@ -75,11 +76,11 @@ func TestRecoveryMessage_Setters(t *testing.T) {
|
||||||
require.Equal(t, p1, pr)
|
require.Equal(t, p1, pr)
|
||||||
|
|
||||||
pl := pr.(*Payload)
|
pl := pr.(*Payload)
|
||||||
require.True(t, pl.Verify(pl.Witness.ScriptHash()))
|
require.True(t, srv.validatePayload(pl))
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("change view is added", func(t *testing.T) {
|
t.Run("change view is added", func(t *testing.T) {
|
||||||
p3 := new(Payload)
|
p3 := NewPayload(netmode.UnitTestNet)
|
||||||
p3.message = &message{}
|
p3.message = &message{}
|
||||||
p3.SetType(payload.ChangeViewType)
|
p3.SetType(payload.ChangeViewType)
|
||||||
p3.SetPayload(&changeView{
|
p3.SetPayload(&changeView{
|
||||||
|
@ -96,16 +97,16 @@ func TestRecoveryMessage_Setters(t *testing.T) {
|
||||||
require.Equal(t, p3, ps[0])
|
require.Equal(t, p3, ps[0])
|
||||||
|
|
||||||
ps0 := ps[0].(*Payload)
|
ps0 := ps[0].(*Payload)
|
||||||
require.True(t, ps0.Verify(ps0.Witness.ScriptHash()))
|
require.True(t, srv.validatePayload(ps0))
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("commit is added", func(t *testing.T) {
|
t.Run("commit is added", func(t *testing.T) {
|
||||||
p4 := new(Payload)
|
p4 := NewPayload(netmode.UnitTestNet)
|
||||||
p4.message = &message{}
|
p4.message = &message{}
|
||||||
p4.SetType(payload.CommitType)
|
p4.SetType(payload.CommitType)
|
||||||
p4.SetPayload(randomMessage(t, commitType))
|
p4.SetPayload(randomMessage(t, commitType))
|
||||||
p4.SetValidatorIndex(4)
|
p4.SetValidatorIndex(3)
|
||||||
require.NoError(t, p4.Sign(privs[4]))
|
require.NoError(t, p4.Sign(privs[3]))
|
||||||
|
|
||||||
r.AddPayload(p4)
|
r.AddPayload(p4)
|
||||||
|
|
||||||
|
@ -114,7 +115,7 @@ func TestRecoveryMessage_Setters(t *testing.T) {
|
||||||
require.Equal(t, p4, ps[0])
|
require.Equal(t, p4, ps[0])
|
||||||
|
|
||||||
ps0 := ps[0].(*Payload)
|
ps0 := ps[0].(*Payload)
|
||||||
require.True(t, ps0.Verify(ps0.Witness.ScriptHash()))
|
require.True(t, srv.validatePayload(ps0))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/crypto"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
|
||||||
|
@ -27,7 +28,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
@ -1373,10 +1373,7 @@ func (bc *Blockchain) verifyStateRootWitness(r *state.MPTRoot) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
interopCtx := bc.newInteropContext(trigger.Verification, bc.dao, nil, nil)
|
return bc.VerifyWitness(b.NextConsensus, r, r.Witness, bc.contracts.Policy.GetMaxVerificationGas(bc.dao))
|
||||||
interopCtx.Container = r
|
|
||||||
return bc.verifyHashAgainstScript(b.NextConsensus, r.Witness, interopCtx, true,
|
|
||||||
bc.contracts.Policy.GetMaxVerificationGas(interopCtx.DAO))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyTx verifies whether transaction is bonafide or not relative to the
|
// VerifyTx verifies whether transaction is bonafide or not relative to the
|
||||||
|
@ -1439,22 +1436,6 @@ func (bc *Blockchain) GetTestVM(tx *transaction.Transaction) *vm.VM {
|
||||||
return vm
|
return vm
|
||||||
}
|
}
|
||||||
|
|
||||||
// ScriptFromWitness returns verification script for provided witness.
|
|
||||||
// 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
|
|
||||||
|
|
||||||
if len(verification) == 0 {
|
|
||||||
bb := io.NewBufBinWriter()
|
|
||||||
emit.AppCall(bb.BinWriter, hash)
|
|
||||||
verification = bb.Bytes()
|
|
||||||
} else if h := witness.ScriptHash(); hash != h {
|
|
||||||
return nil, ErrWitnessHashMismatch
|
|
||||||
}
|
|
||||||
|
|
||||||
return verification, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Various witness verification errors.
|
// Various witness verification errors.
|
||||||
var (
|
var (
|
||||||
ErrWitnessHashMismatch = errors.New("witness hash mismatch")
|
ErrWitnessHashMismatch = errors.New("witness hash mismatch")
|
||||||
|
@ -1463,8 +1444,8 @@ var (
|
||||||
ErrInvalidVerificationContract = errors.New("verification contract is missing `verify` method")
|
ErrInvalidVerificationContract = errors.New("verification contract is missing `verify` method")
|
||||||
)
|
)
|
||||||
|
|
||||||
// verifyHashAgainstScript verifies given hash against the given witness.
|
// initVerificationVM initializes VM for witness check.
|
||||||
func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transaction.Witness, interopCtx *interop.Context, useKeys bool, gas int64) error {
|
func initVerificationVM(ic *interop.Context, hash util.Uint160, witness *transaction.Witness, keyCache map[string]*keys.PublicKey) error {
|
||||||
var offset int
|
var offset int
|
||||||
var initMD *manifest.Method
|
var initMD *manifest.Method
|
||||||
verification := witness.VerificationScript
|
verification := witness.VerificationScript
|
||||||
|
@ -1473,7 +1454,7 @@ func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transa
|
||||||
return ErrWitnessHashMismatch
|
return ErrWitnessHashMismatch
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cs, err := interopCtx.DAO.GetContractState(hash)
|
cs, err := ic.DAO.GetContractState(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ErrUnknownVerificationContract
|
return ErrUnknownVerificationContract
|
||||||
}
|
}
|
||||||
|
@ -1486,6 +1467,28 @@ func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transa
|
||||||
initMD = cs.Manifest.ABI.GetMethod(manifest.MethodInit)
|
initMD = cs.Manifest.ABI.GetMethod(manifest.MethodInit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v := ic.VM
|
||||||
|
v.LoadScriptWithFlags(verification, smartcontract.NoneFlag)
|
||||||
|
v.Jump(v.Context(), offset)
|
||||||
|
if initMD != nil {
|
||||||
|
v.Call(v.Context(), initMD.Offset)
|
||||||
|
}
|
||||||
|
v.LoadScript(witness.InvocationScript)
|
||||||
|
if keyCache != nil {
|
||||||
|
v.SetPublicKeys(keyCache)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// VerifyWitness checks that w is a correct witness for c signed by h.
|
||||||
|
func (bc *Blockchain) VerifyWitness(h util.Uint160, c crypto.Verifiable, w *transaction.Witness, gas int64) error {
|
||||||
|
ic := bc.newInteropContext(trigger.Verification, bc.dao, nil, nil)
|
||||||
|
ic.Container = c
|
||||||
|
return bc.verifyHashAgainstScript(h, w, ic, true, gas)
|
||||||
|
}
|
||||||
|
|
||||||
|
// verifyHashAgainstScript verifies given hash against the given witness.
|
||||||
|
func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transaction.Witness, interopCtx *interop.Context, useKeys bool, gas int64) error {
|
||||||
gasPolicy := bc.contracts.Policy.GetMaxVerificationGas(interopCtx.DAO)
|
gasPolicy := bc.contracts.Policy.GetMaxVerificationGas(interopCtx.DAO)
|
||||||
if gas > gasPolicy {
|
if gas > gasPolicy {
|
||||||
gas = gasPolicy
|
gas = gasPolicy
|
||||||
|
@ -1494,19 +1497,17 @@ func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transa
|
||||||
vm := interopCtx.SpawnVM()
|
vm := interopCtx.SpawnVM()
|
||||||
vm.SetPriceGetter(getPrice)
|
vm.SetPriceGetter(getPrice)
|
||||||
vm.GasLimit = gas
|
vm.GasLimit = gas
|
||||||
vm.LoadScriptWithFlags(verification, smartcontract.NoneFlag)
|
var keyCache map[string]*keys.PublicKey
|
||||||
vm.Jump(vm.Context(), offset)
|
|
||||||
if initMD != nil {
|
|
||||||
vm.Call(vm.Context(), initMD.Offset)
|
|
||||||
}
|
|
||||||
vm.LoadScript(witness.InvocationScript)
|
|
||||||
if useKeys {
|
if useKeys {
|
||||||
bc.keyCacheLock.RLock()
|
bc.keyCacheLock.RLock()
|
||||||
if bc.keyCache[hash] != nil {
|
if bc.keyCache[hash] != nil {
|
||||||
vm.SetPublicKeys(bc.keyCache[hash])
|
keyCache = bc.keyCache[hash]
|
||||||
}
|
}
|
||||||
bc.keyCacheLock.RUnlock()
|
bc.keyCacheLock.RUnlock()
|
||||||
}
|
}
|
||||||
|
if err := initVerificationVM(interopCtx, hash, witness, keyCache); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
err := vm.Run()
|
err := vm.Run()
|
||||||
if vm.HasFailed() {
|
if vm.HasFailed() {
|
||||||
return fmt.Errorf("%w: vm execution has failed: %v", ErrVerificationFailed, err)
|
return fmt.Errorf("%w: vm execution has failed: %v", ErrVerificationFailed, err)
|
||||||
|
@ -1564,9 +1565,7 @@ func (bc *Blockchain) verifyHeaderWitnesses(currHeader, prevHeader *block.Header
|
||||||
} else {
|
} else {
|
||||||
hash = prevHeader.NextConsensus
|
hash = prevHeader.NextConsensus
|
||||||
}
|
}
|
||||||
interopCtx := bc.newInteropContext(trigger.Verification, bc.dao, nil, nil)
|
return bc.VerifyWitness(hash, currHeader, &currHeader.Script, verificationGasLimit)
|
||||||
interopCtx.Container = currHeader
|
|
||||||
return bc.verifyHashAgainstScript(hash, &currHeader.Script, interopCtx, true, verificationGasLimit)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GoverningTokenHash returns the governing token (NEO) native contract hash.
|
// GoverningTokenHash returns the governing token (NEO) native contract hash.
|
||||||
|
|
|
@ -155,27 +155,6 @@ func TestAddBadBlock(t *testing.T) {
|
||||||
require.NoError(t, bc.AddBlock(b3))
|
require.NoError(t, bc.AddBlock(b3))
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
|
tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/mempool"
|
"github.com/nspcc-dev/neo-go/pkg/core/mempool"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/crypto"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||||
|
@ -57,6 +58,7 @@ type Blockchainer interface {
|
||||||
SubscribeForNotifications(ch chan<- *state.NotificationEvent)
|
SubscribeForNotifications(ch chan<- *state.NotificationEvent)
|
||||||
SubscribeForTransactions(ch chan<- *transaction.Transaction)
|
SubscribeForTransactions(ch chan<- *transaction.Transaction)
|
||||||
VerifyTx(*transaction.Transaction) error
|
VerifyTx(*transaction.Transaction) error
|
||||||
|
VerifyWitness(util.Uint160, crypto.Verifiable, *transaction.Witness, int64) error
|
||||||
GetMemPool() *mempool.Pool
|
GetMemPool() *mempool.Pool
|
||||||
UnsubscribeFromBlocks(ch chan<- *block.Block)
|
UnsubscribeFromBlocks(ch chan<- *block.Block)
|
||||||
UnsubscribeFromExecutions(ch chan<- *state.AppExecResult)
|
UnsubscribeFromExecutions(ch chan<- *state.AppExecResult)
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/mempool"
|
"github.com/nspcc-dev/neo-go/pkg/core/mempool"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/crypto"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/network/capability"
|
"github.com/nspcc-dev/neo-go/pkg/network/capability"
|
||||||
|
@ -169,6 +170,9 @@ func (chain testChain) SubscribeForTransactions(ch chan<- *transaction.Transacti
|
||||||
func (chain testChain) VerifyTx(*transaction.Transaction) error {
|
func (chain testChain) VerifyTx(*transaction.Transaction) error {
|
||||||
panic("TODO")
|
panic("TODO")
|
||||||
}
|
}
|
||||||
|
func (testChain) VerifyWitness(util.Uint160, crypto.Verifiable, *transaction.Witness, int64) error {
|
||||||
|
panic("TODO")
|
||||||
|
}
|
||||||
|
|
||||||
func (chain testChain) UnsubscribeFromBlocks(ch chan<- *block.Block) {
|
func (chain testChain) UnsubscribeFromBlocks(ch chan<- *block.Block) {
|
||||||
panic("TODO")
|
panic("TODO")
|
||||||
|
|
Loading…
Reference in a new issue