forked from TrueCloudLab/neoneo-go
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.
|
||||
type Context struct {
|
||||
Chain Ledger
|
||||
Container hash.Hashable
|
||||
Network uint32
|
||||
Hardforks map[string]uint32
|
||||
Natives []Contract
|
||||
Trigger trigger.Type
|
||||
Block *block.Block
|
||||
NonceData [16]byte
|
||||
Tx *transaction.Transaction
|
||||
DAO *dao.Simple
|
||||
Notifications []state.NotificationEvent
|
||||
Log *zap.Logger
|
||||
VM *vm.VM
|
||||
Functions []Function
|
||||
Invocations map[util.Uint160]int
|
||||
cancelFuncs []context.CancelFunc
|
||||
getContract func(*dao.Simple, util.Uint160) (*state.Contract, error)
|
||||
baseExecFee int64
|
||||
baseStorageFee int64
|
||||
signers []transaction.Signer
|
||||
Chain Ledger
|
||||
Container hash.Hashable
|
||||
Network uint32
|
||||
Hardforks map[string]uint32
|
||||
Natives []Contract
|
||||
Trigger trigger.Type
|
||||
Block *block.Block
|
||||
NonceData [16]byte
|
||||
Tx *transaction.Transaction
|
||||
DAO *dao.Simple
|
||||
Notifications []state.NotificationEvent
|
||||
Log *zap.Logger
|
||||
VM *vm.VM
|
||||
Functions []Function
|
||||
Invocations map[util.Uint160]int
|
||||
cancelFuncs []context.CancelFunc
|
||||
getContract func(*dao.Simple, util.Uint160) (*state.Contract, error)
|
||||
baseExecFee int64
|
||||
baseStorageFee int64
|
||||
GetRandomCounter uint32
|
||||
signers []transaction.Signer
|
||||
}
|
||||
|
||||
// NewContext returns new interop context.
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"errors"
|
||||
"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/state"
|
||||
"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.
|
||||
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)))
|
||||
copy(ic.NonceData[:], res)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -46,25 +46,26 @@ func TestRuntimeGetRandomCompatibility(t *testing.T) {
|
|||
b := getSharpTestGenesis(t)
|
||||
tx := getSharpTestTx(util.Uint160{})
|
||||
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.LoadScript([]byte{0x01})
|
||||
ic.VM.GasLimit = 1100_00000000
|
||||
|
||||
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.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.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.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.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 {
|
||||
|
@ -74,7 +75,8 @@ func getSharpTestTx(sender util.Uint160) *transaction.Transaction {
|
|||
Account: sender,
|
||||
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
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ var systemInterops = []interop.Function{
|
|||
{Name: interopnames.SystemRuntimeGetInvocationCounter, Func: runtime.GetInvocationCounter, Price: 1 << 4},
|
||||
{Name: interopnames.SystemRuntimeGetNetwork, Func: runtime.GetNetwork, Price: 1 << 3},
|
||||
{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.SystemRuntimeGetTime, Func: runtime.GetTime, Price: 1 << 3, RequiredFlags: callflag.ReadStates},
|
||||
{Name: interopnames.SystemRuntimeGetTrigger, Func: runtime.GetTrigger, Price: 1 << 3},
|
||||
|
|
Loading…
Reference in a new issue