mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2025-02-17 05:47:38 +00:00
core: adjust System.Runtime.GetRandom
1. Make seed dependant on the GetRandom invocations counter. 2. Adjust syscall price.
This commit is contained in:
parent
c6666c52bc
commit
c4ad434f20
4 changed files with 51 additions and 30 deletions
|
@ -45,26 +45,27 @@ type Ledger interface {
|
||||||
|
|
||||||
// Context represents context in which interops are executed.
|
// Context represents context in which interops are executed.
|
||||||
type Context struct {
|
type Context struct {
|
||||||
Chain Ledger
|
Chain Ledger
|
||||||
Container hash.Hashable
|
Container hash.Hashable
|
||||||
Network uint32
|
Network uint32
|
||||||
Hardforks map[string]uint32
|
Hardforks map[string]uint32
|
||||||
Natives []Contract
|
Natives []Contract
|
||||||
Trigger trigger.Type
|
Trigger trigger.Type
|
||||||
Block *block.Block
|
Block *block.Block
|
||||||
NonceData [16]byte
|
NonceData [16]byte
|
||||||
Tx *transaction.Transaction
|
Tx *transaction.Transaction
|
||||||
DAO *dao.Simple
|
DAO *dao.Simple
|
||||||
Notifications []state.NotificationEvent
|
Notifications []state.NotificationEvent
|
||||||
Log *zap.Logger
|
Log *zap.Logger
|
||||||
VM *vm.VM
|
VM *vm.VM
|
||||||
Functions []Function
|
Functions []Function
|
||||||
Invocations map[util.Uint160]int
|
Invocations map[util.Uint160]int
|
||||||
cancelFuncs []context.CancelFunc
|
cancelFuncs []context.CancelFunc
|
||||||
getContract func(*dao.Simple, util.Uint160) (*state.Contract, error)
|
getContract func(*dao.Simple, util.Uint160) (*state.Contract, error)
|
||||||
baseExecFee int64
|
baseExecFee int64
|
||||||
baseStorageFee int64
|
baseStorageFee int64
|
||||||
signers []transaction.Signer
|
GetRandomCounter uint32
|
||||||
|
signers []transaction.Signer
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewContext returns new interop context.
|
// NewContext returns new interop context.
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/config"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||||
"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/encoding/address"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||||
|
@ -88,9 +89,26 @@ func GetNetwork(ic *interop.Context) error {
|
||||||
|
|
||||||
// GetRandom returns pseudo-random number which depends on block nonce and transaction hash.
|
// GetRandom returns pseudo-random number which depends on block nonce and transaction hash.
|
||||||
func GetRandom(ic *interop.Context) error {
|
func GetRandom(ic *interop.Context) error {
|
||||||
res := murmur128(ic.NonceData[:], ic.Network)
|
var (
|
||||||
|
price int64
|
||||||
|
seed = ic.Network
|
||||||
|
)
|
||||||
|
isHF := ic.IsHardforkEnabled(config.HF2712FixSyscallFees)
|
||||||
|
if isHF {
|
||||||
|
price = 1 << 13
|
||||||
|
seed += ic.GetRandomCounter
|
||||||
|
ic.GetRandomCounter++
|
||||||
|
} else {
|
||||||
|
price = 1 << 4
|
||||||
|
}
|
||||||
|
res := murmur128(ic.NonceData[:], seed)
|
||||||
|
if !isHF {
|
||||||
|
copy(ic.NonceData[:], res)
|
||||||
|
}
|
||||||
|
if !ic.VM.AddGas(ic.BaseExecFee() * price) {
|
||||||
|
return errors.New("gas limit exceeded")
|
||||||
|
}
|
||||||
ic.VM.Estack().PushItem(stackitem.NewBigInteger(bigint.FromBytesUnsigned(res)))
|
ic.VM.Estack().PushItem(stackitem.NewBigInteger(bigint.FromBytesUnsigned(res)))
|
||||||
copy(ic.NonceData[:], res)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,25 +46,26 @@ func TestRuntimeGetRandomCompatibility(t *testing.T) {
|
||||||
b := getSharpTestGenesis(t)
|
b := getSharpTestGenesis(t)
|
||||||
tx := getSharpTestTx(util.Uint160{})
|
tx := getSharpTestTx(util.Uint160{})
|
||||||
ic := bc.newInteropContext(trigger.Application, bc.dao.GetWrapped(), b, tx)
|
ic := bc.newInteropContext(trigger.Application, bc.dao.GetWrapped(), b, tx)
|
||||||
ic.Network = 5195086 // Old mainnet magic used by C# tests.
|
ic.Network = 860833102 // Old mainnet magic used by C# tests.
|
||||||
|
|
||||||
ic.VM = vm.New()
|
ic.VM = vm.New()
|
||||||
ic.VM.LoadScript([]byte{0x01})
|
ic.VM.LoadScript([]byte{0x01})
|
||||||
|
ic.VM.GasLimit = 1100_00000000
|
||||||
|
|
||||||
require.NoError(t, runtime.GetRandom(ic))
|
require.NoError(t, runtime.GetRandom(ic))
|
||||||
require.Equal(t, "225932872514876835587448704843370203748", ic.VM.Estack().Pop().BigInt().String())
|
require.Equal(t, "271339657438512451304577787170704246350", ic.VM.Estack().Pop().BigInt().String())
|
||||||
|
|
||||||
require.NoError(t, runtime.GetRandom(ic))
|
require.NoError(t, runtime.GetRandom(ic))
|
||||||
require.Equal(t, "190129535548110356450238097068474508661", ic.VM.Estack().Pop().BigInt().String())
|
require.Equal(t, "98548189559099075644778613728143131367", ic.VM.Estack().Pop().BigInt().String())
|
||||||
|
|
||||||
require.NoError(t, runtime.GetRandom(ic))
|
require.NoError(t, runtime.GetRandom(ic))
|
||||||
require.Equal(t, "48930406787011198493485648810190184269", ic.VM.Estack().Pop().BigInt().String())
|
require.Equal(t, "247654688993873392544380234598471205121", ic.VM.Estack().Pop().BigInt().String())
|
||||||
|
|
||||||
require.NoError(t, runtime.GetRandom(ic))
|
require.NoError(t, runtime.GetRandom(ic))
|
||||||
require.Equal(t, "66199389469641263539889463157823839112", ic.VM.Estack().Pop().BigInt().String())
|
require.Equal(t, "291082758879475329976578097236212073607", ic.VM.Estack().Pop().BigInt().String())
|
||||||
|
|
||||||
require.NoError(t, runtime.GetRandom(ic))
|
require.NoError(t, runtime.GetRandom(ic))
|
||||||
require.Equal(t, "217172703763162599519098299724476526911", ic.VM.Estack().Pop().BigInt().String())
|
require.Equal(t, "247152297361212656635216876565962360375", ic.VM.Estack().Pop().BigInt().String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSharpTestTx(sender util.Uint160) *transaction.Transaction {
|
func getSharpTestTx(sender util.Uint160) *transaction.Transaction {
|
||||||
|
@ -74,7 +75,8 @@ func getSharpTestTx(sender util.Uint160) *transaction.Transaction {
|
||||||
Account: sender,
|
Account: sender,
|
||||||
Scopes: transaction.CalledByEntry,
|
Scopes: transaction.CalledByEntry,
|
||||||
})
|
})
|
||||||
tx.Scripts = append(tx.Scripts, transaction.Witness{})
|
tx.Attributes = []transaction.Attribute{}
|
||||||
|
tx.Scripts = append(tx.Scripts, transaction.Witness{InvocationScript: []byte{}, VerificationScript: []byte{}})
|
||||||
return tx
|
return tx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ var systemInterops = []interop.Function{
|
||||||
{Name: interopnames.SystemRuntimeGetInvocationCounter, Func: runtime.GetInvocationCounter, Price: 1 << 4},
|
{Name: interopnames.SystemRuntimeGetInvocationCounter, Func: runtime.GetInvocationCounter, Price: 1 << 4},
|
||||||
{Name: interopnames.SystemRuntimeGetNetwork, Func: runtime.GetNetwork, Price: 1 << 3},
|
{Name: interopnames.SystemRuntimeGetNetwork, Func: runtime.GetNetwork, Price: 1 << 3},
|
||||||
{Name: interopnames.SystemRuntimeGetNotifications, Func: runtime.GetNotifications, Price: 1 << 12, ParamCount: 1},
|
{Name: interopnames.SystemRuntimeGetNotifications, Func: runtime.GetNotifications, Price: 1 << 12, ParamCount: 1},
|
||||||
{Name: interopnames.SystemRuntimeGetRandom, Func: runtime.GetRandom, Price: 1 << 4},
|
{Name: interopnames.SystemRuntimeGetRandom, Func: runtime.GetRandom, Price: 0},
|
||||||
{Name: interopnames.SystemRuntimeGetScriptContainer, Func: engineGetScriptContainer, Price: 1 << 3},
|
{Name: interopnames.SystemRuntimeGetScriptContainer, Func: engineGetScriptContainer, Price: 1 << 3},
|
||||||
{Name: interopnames.SystemRuntimeGetTime, Func: runtime.GetTime, Price: 1 << 3, RequiredFlags: callflag.ReadStates},
|
{Name: interopnames.SystemRuntimeGetTime, Func: runtime.GetTime, Price: 1 << 3, RequiredFlags: callflag.ReadStates},
|
||||||
{Name: interopnames.SystemRuntimeGetTrigger, Func: runtime.GetTrigger, Price: 1 << 3},
|
{Name: interopnames.SystemRuntimeGetTrigger, Func: runtime.GetTrigger, Price: 1 << 3},
|
||||||
|
|
Loading…
Add table
Reference in a new issue