diff --git a/emulator/blockchain.go b/emulator/blockchain.go index 231b9e0c..717d0f40 100644 --- a/emulator/blockchain.go +++ b/emulator/blockchain.go @@ -530,6 +530,19 @@ func (h CadenceHook) Run(_ *zerolog.Event, level zerolog.Level, msg string) { } } +// `dummyEntropyProvider“ implements `environment.EntropyProvider` +// which provides a source of entropy to fvm context (required for Cadence's randomness). +type dummyEntropyProvider struct{} + +var dummySource = make([]byte, 32) + +func (gen *dummyEntropyProvider) RandomSource() ([]byte, error) { + return dummySource, nil +} + +// make sure `dummyEntropyProvider“ implements `environment.EntropyProvider` +var _ environment.EntropyProvider = (*dummyEntropyProvider)(nil) + func configureFVM(blockchain *Blockchain, conf config, blocks *blocks) (*fvm.VirtualMachine, fvm.Context, error) { vm := fvm.NewVirtualMachine() @@ -566,6 +579,7 @@ func configureFVM(blockchain *Blockchain, conf config, blocks *blocks) (*fvm.Vir fvm.WithAccountStorageLimit(conf.StorageLimitEnabled), fvm.WithTransactionFeesEnabled(conf.TransactionFeesEnabled), fvm.WithReusableCadenceRuntimePool(customRuntimePool), + fvm.WithEntropyProvider(&dummyEntropyProvider{}), } if !conf.TransactionValidationEnabled { diff --git a/emulator/script_test.go b/emulator/script_test.go index 1e39eb19..8b278aa5 100644 --- a/emulator/script_test.go +++ b/emulator/script_test.go @@ -244,3 +244,24 @@ func TestScriptExecutionLimit(t *testing.T) { require.NoError(t, result.Error) }) } + +// TestScriptWithCadenceRandom checks Cadence's random function works +// within a script +func TestScriptWithCadenceRandom(t *testing.T) { + + const code = ` + pub fun main() { + assert(unsafeRandom() >= 0) + } + ` + + const limit = 200 + b, err := emulator.New( + emulator.WithScriptGasLimit(limit), + ) + require.NoError(t, err) + + result, err := b.ExecuteScript([]byte(code), nil) + require.NoError(t, err) + require.NoError(t, result.Error) +} diff --git a/emulator/transaction_test.go b/emulator/transaction_test.go index 669027ae..f641e4a1 100644 --- a/emulator/transaction_test.go +++ b/emulator/transaction_test.go @@ -2116,3 +2116,38 @@ func TestRollbackTransaction(t *testing.T) { IncrementHelper(t, b, adapter, counterAddress, addTwoScript, 2) } + +// TestTransactionWithCadenceRandom checks Cadence's random function works +// within a transaction +func TestTransactionWithCadenceRandom(t *testing.T) { + b, adapter := setupTransactionTests(t) + + code := ` + transaction { + prepare() { + assert(unsafeRandom() >= 0) + } + } + ` + callRandomTx := flowsdk.NewTransaction(). + SetGasLimit(flowgo.DefaultMaxTransactionGasLimit). + SetScript([]byte(code)). + SetProposalKey(b.ServiceKey().Address, b.ServiceKey().Index, b.ServiceKey().SequenceNumber). + SetPayer(b.ServiceKey().Address) + + signer, err := b.ServiceKey().Signer() + require.NoError(t, err) + + err = callRandomTx.SignEnvelope(b.ServiceKey().Address, b.ServiceKey().Index, signer) + require.NoError(t, err) + + err = adapter.SendTransaction(context.Background(), *callRandomTx) + assert.NoError(t, err) + + result, err := b.ExecuteNextTransaction() + assert.NoError(t, err) + AssertTransactionSucceeded(t, result) + + _, err = b.CommitBlock() + assert.NoError(t, err) +}