forked from TrueCloudLab/neoneo-go
vm: leave single CHECKMULTISIG implementation
Remove sequential implementation and benchmarks. They will be still present in commit history.
This commit is contained in:
parent
02a5e036fc
commit
2a86149c82
2 changed files with 1 additions and 126 deletions
34
pkg/vm/vm.go
34
pkg/vm/vm.go
|
@ -84,8 +84,6 @@ type VM struct {
|
|||
|
||||
// Public keys cache.
|
||||
keys map[string]*keys.PublicKey
|
||||
|
||||
checkMultisig func(*VM, [][]byte, [][]byte) bool
|
||||
}
|
||||
|
||||
// New returns a new VM object ready to load .avm bytecode scripts.
|
||||
|
@ -1223,13 +1221,7 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
|
|||
panic("VM is not set up properly for signature checks")
|
||||
}
|
||||
|
||||
var sigok bool
|
||||
if v.checkMultisig == nil {
|
||||
sigok = checkMultisigPar(v, pkeys, sigs)
|
||||
} else {
|
||||
sigok = v.checkMultisig(v, pkeys, sigs)
|
||||
}
|
||||
|
||||
sigok := checkMultisigPar(v, pkeys, sigs)
|
||||
v.estack.PushVal(sigok)
|
||||
|
||||
case opcode.NEWMAP:
|
||||
|
@ -1523,30 +1515,6 @@ func checkMultisig1(v *VM, pkeys [][]byte, sig []byte) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func checkMultisigSeq(v *VM, pkeys [][]byte, sigs [][]byte) bool {
|
||||
// j counts keys and i counts signatures.
|
||||
j := 0
|
||||
for i := 0; j < len(pkeys) && i < len(sigs); {
|
||||
pkey := v.bytesToPublicKey(pkeys[j])
|
||||
|
||||
// We only move to the next signature if the check was
|
||||
// successful, but if it's not maybe the next key will
|
||||
// fit, so we always move to the next key.
|
||||
if pkey.Verify(sigs[i], v.checkhash) {
|
||||
i++
|
||||
}
|
||||
j++
|
||||
|
||||
// When there are more signatures left to check than
|
||||
// there are keys the check won't successed for sure.
|
||||
if len(sigs)-i > len(pkeys)-j {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func cloneIfStruct(item StackItem) StackItem {
|
||||
switch it := item.(type) {
|
||||
case *StructItem:
|
||||
|
|
|
@ -2790,99 +2790,6 @@ func TestCHECKMULTISIGBad(t *testing.T) {
|
|||
t.Run("3_2 duplicate sig", func(t *testing.T) { testCHECKMULTISIGBad(t, 3, nil, []int{0, 0}) })
|
||||
}
|
||||
|
||||
func benchCHECKMULTISIG(b *testing.B, size int, is [][]int, check func(*VM, [][]byte, [][]byte) bool) {
|
||||
prog := makeProgram(opcode.CHECKMULTISIG)
|
||||
msg := []byte("NEO - An Open Network For Smart Economy")
|
||||
h := hash.Sha256(msg).BytesBE()
|
||||
|
||||
pubs, sigs, keyMap, err := initCHECKMULTISIG(msg, size)
|
||||
if err != nil {
|
||||
b.Fatalf("error on initialize: %v", err)
|
||||
}
|
||||
|
||||
sigsStack := make([][]StackItem, 0, len(is))
|
||||
for i := range is {
|
||||
sigsStack = append(sigsStack, subSlice(sigs, is[i]))
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
b.ReportAllocs()
|
||||
for i := 0; i < b.N; i++ {
|
||||
for j := range sigsStack {
|
||||
vm := load(prog)
|
||||
vm.SetCheckedHash(h)
|
||||
vm.SetPublicKeys(keyMap)
|
||||
vm.checkMultisig = check
|
||||
vm.estack.PushVal(sigsStack[j])
|
||||
vm.estack.PushVal(pubs)
|
||||
_ = vm.Run()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCHECKMULTISIG(b *testing.B) {
|
||||
fs := []struct {
|
||||
name string
|
||||
f func(*VM, [][]byte, [][]byte) bool
|
||||
}{
|
||||
{"seq", checkMultisigSeq},
|
||||
{"par", checkMultisigPar},
|
||||
}
|
||||
|
||||
b.Run("4_3 start", func(b *testing.B) {
|
||||
for i := range fs {
|
||||
b.Run(fs[i].name, func(b *testing.B) {
|
||||
benchCHECKMULTISIG(b, 4, [][]int{{0, 1, 2}}, fs[i].f)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("4_3 all", func(b *testing.B) {
|
||||
for i := range fs {
|
||||
b.Run(fs[i].name, func(b *testing.B) {
|
||||
benchCHECKMULTISIG(b, 4, combinations(4, 3), fs[i].f)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("7_5 start", func(b *testing.B) {
|
||||
for i := range fs {
|
||||
b.Run(fs[i].name, func(b *testing.B) {
|
||||
benchCHECKMULTISIG(b, 7, [][]int{{0, 1, 2, 3, 4}}, fs[i].f)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("7_5 all", func(b *testing.B) {
|
||||
for i := range fs {
|
||||
b.Run(fs[i].name, func(b *testing.B) {
|
||||
benchCHECKMULTISIG(b, 7, combinations(7, 5), fs[i].f)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func combinations(n, k int) [][]int {
|
||||
if n < k {
|
||||
return nil
|
||||
} else if k == 0 {
|
||||
return [][]int{{}}
|
||||
} else if n == k {
|
||||
res := make([]int, k)
|
||||
for i := 0; i < k; i++ {
|
||||
res[i] = i
|
||||
}
|
||||
return [][]int{res}
|
||||
}
|
||||
|
||||
result := combinations(n-1, k)
|
||||
for _, c := range combinations(n-1, k-1) {
|
||||
result = append(result, append(c, n-1))
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func TestSWAPGood(t *testing.T) {
|
||||
prog := makeProgram(opcode.SWAP)
|
||||
vm := load(prog)
|
||||
|
|
Loading…
Reference in a new issue