neoneo-go/pkg/core/fee/calculate.go
Anna Shaleva 6a4e312eac core: move GetPrice from core to interop
We have additional logic for getting BaseExecFee policy value. This
logic should be moved to interop context instead of being in Policer,
because Policer is just an interface over Policy contract.

After moving this logic to interop context, we need to use it to define
BaseExecFee instead of (Policer).BaseExecFee. Thus, moving
(*Blockchain).GetPrice to (*Context).GetPrice is necessary.
2021-02-05 11:36:32 +03:00

41 lines
1.3 KiB
Go

package fee
import (
"github.com/nspcc-dev/neo-go/pkg/io"
"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/opcode"
)
// ECDSAVerifyPrice is a gas price of a single verification.
const ECDSAVerifyPrice = 1 << 15
// Calculate returns network fee for transaction
func Calculate(base int64, script []byte) (int64, int) {
var (
netFee int64
size int
)
if vm.IsSignatureContract(script) {
size += 67 + io.GetVarSize(script)
netFee += Opcode(base, opcode.PUSHDATA1, opcode.PUSHNULL, opcode.PUSHDATA1) + base*ECDSAVerifyPrice
} else if m, pubs, ok := vm.ParseMultiSigContract(script); ok {
n := len(pubs)
sizeInv := 66 * m
size += io.GetVarSize(sizeInv) + sizeInv + io.GetVarSize(script)
netFee += calculateMultisig(base, m) + calculateMultisig(base, n)
netFee += Opcode(base, opcode.PUSHNULL) + base*ECDSAVerifyPrice*int64(n)
} else {
// We can support more contract types in the future.
}
return netFee, size
}
func calculateMultisig(base int64, n int) int64 {
result := Opcode(base, opcode.PUSHDATA1) * int64(n)
bw := io.NewBufBinWriter()
emit.Int(bw.BinWriter, int64(n))
// it's a hack because coefficients of small PUSH* opcodes are equal
result += Opcode(base, opcode.Opcode(bw.Bytes()[0]))
return result
}