6a4e312eac
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.
41 lines
1.3 KiB
Go
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
|
|
}
|