core: verification script must return exactly one value

C# node is quite picky as it expects there to be exactly one value returned,
but our testchain actually adds 4 signatures for multisig cases instead of 3
which makes it technically incompatible with C# node.
This commit is contained in:
Roman Khimov 2020-08-17 22:02:15 +03:00
parent 58af143f25
commit d0c29f52c9
5 changed files with 16 additions and 4 deletions

View file

@ -1490,6 +1490,9 @@ func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transa
if !resEl.Bool() { if !resEl.Bool() {
return fmt.Errorf("%w: invalid signature", ErrVerificationFailed) return fmt.Errorf("%w: invalid signature", ErrVerificationFailed)
} }
if vm.Estack().Len() != 0 {
return fmt.Errorf("%w: expected exactly one returned value", ErrVerificationFailed)
}
if useKeys { if useKeys {
bc.keyCacheLock.RLock() bc.keyCacheLock.RLock()
_, ok := bc.keyCache[hash] _, ok := bc.keyCache[hash]

View file

@ -354,6 +354,15 @@ func TestVerifyHashAgainstScript(t *testing.T) {
err := bc.verifyHashAgainstScript(hash.Hash160(verif), w, ic, false, gas) err := bc.verifyHashAgainstScript(hash.Hash160(verif), w, ic, false, gas)
require.True(t, errors.Is(err, ErrVerificationFailed)) require.True(t, errors.Is(err, ErrVerificationFailed))
}) })
t.Run("TooManyResults", func(t *testing.T) {
verif := []byte{byte(opcode.NOP)}
w := &transaction.Witness{
InvocationScript: []byte{byte(opcode.PUSH1), byte(opcode.PUSH1)},
VerificationScript: verif,
}
err := bc.verifyHashAgainstScript(hash.Hash160(verif), w, ic, false, gas)
require.True(t, errors.Is(err, ErrVerificationFailed))
})
} }
func TestHasBlock(t *testing.T) { func TestHasBlock(t *testing.T) {

View file

@ -84,7 +84,7 @@ func MultisigAddress() string {
// Sign signs data by all consensus nodes and returns invocation script. // Sign signs data by all consensus nodes and returns invocation script.
func Sign(data []byte) []byte { func Sign(data []byte) []byte {
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
for i := 0; i < Size(); i++ { for i := 0; i < 3; i++ {
pKey := PrivateKey(i) pKey := PrivateKey(i)
sig := pKey.Sign(data) sig := pKey.Sign(data)
if len(sig) != 64 { if len(sig) != 64 {

View file

@ -52,8 +52,8 @@ type rpcTestCase struct {
check func(t *testing.T, e *executor, result interface{}) check func(t *testing.T, e *executor, result interface{})
} }
const testContractHash = "5b5f77b947194ba45ff5fa1ba6e066af5636d110" const testContractHash = "93c4983afe01a75f74c1e56011bd630e9d8cc755"
const deploymentTxHash = "af0f94f6bdc5aada7abf1db19f1fcd2ea56cea596c41dc4abdfa6cd9664a7d72" const deploymentTxHash = "583cf0e49d69d8854869efc3e97ad741061da478292a7280580789351a39a1ac"
var rpcTestCases = map[string][]rpcTestCase{ var rpcTestCases = map[string][]rpcTestCase{
"getapplicationlog": { "getapplicationlog": {
@ -1027,7 +1027,7 @@ func checkNep5Balances(t *testing.T, e *executor, acc interface{}) {
}, },
{ {
Asset: e.chain.UtilityTokenHash(), Asset: e.chain.UtilityTokenHash(),
Amount: "915.61054740", Amount: "915.61059740",
LastUpdated: 6, LastUpdated: 6,
}}, }},
Address: testchain.PrivateKeyByID(0).GetScriptHash().StringLE(), Address: testchain.PrivateKeyByID(0).GetScriptHash().StringLE(),

Binary file not shown.