Skip to content

Commit bcf6545

Browse files
authored
Merge pull request #459 from onflow/tarak/fix-random
Fix Cadence's unsafe random
2 parents bfc2fcc + 84eb57b commit bcf6545

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed

emulator/blockchain.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,19 @@ func (h CadenceHook) Run(_ *zerolog.Event, level zerolog.Level, msg string) {
530530
}
531531
}
532532

533+
// `dummyEntropyProvider“ implements `environment.EntropyProvider`
534+
// which provides a source of entropy to fvm context (required for Cadence's randomness).
535+
type dummyEntropyProvider struct{}
536+
537+
var dummySource = make([]byte, 32)
538+
539+
func (gen *dummyEntropyProvider) RandomSource() ([]byte, error) {
540+
return dummySource, nil
541+
}
542+
543+
// make sure `dummyEntropyProvider“ implements `environment.EntropyProvider`
544+
var _ environment.EntropyProvider = (*dummyEntropyProvider)(nil)
545+
533546
func configureFVM(blockchain *Blockchain, conf config, blocks *blocks) (*fvm.VirtualMachine, fvm.Context, error) {
534547
vm := fvm.NewVirtualMachine()
535548

@@ -566,6 +579,7 @@ func configureFVM(blockchain *Blockchain, conf config, blocks *blocks) (*fvm.Vir
566579
fvm.WithAccountStorageLimit(conf.StorageLimitEnabled),
567580
fvm.WithTransactionFeesEnabled(conf.TransactionFeesEnabled),
568581
fvm.WithReusableCadenceRuntimePool(customRuntimePool),
582+
fvm.WithEntropyProvider(&dummyEntropyProvider{}),
569583
}
570584

571585
if !conf.TransactionValidationEnabled {

emulator/script_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,3 +244,24 @@ func TestScriptExecutionLimit(t *testing.T) {
244244
require.NoError(t, result.Error)
245245
})
246246
}
247+
248+
// TestScriptWithCadenceRandom checks Cadence's random function works
249+
// within a script
250+
func TestScriptWithCadenceRandom(t *testing.T) {
251+
252+
const code = `
253+
pub fun main() {
254+
assert(unsafeRandom() >= 0)
255+
}
256+
`
257+
258+
const limit = 200
259+
b, err := emulator.New(
260+
emulator.WithScriptGasLimit(limit),
261+
)
262+
require.NoError(t, err)
263+
264+
result, err := b.ExecuteScript([]byte(code), nil)
265+
require.NoError(t, err)
266+
require.NoError(t, result.Error)
267+
}

emulator/transaction_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2116,3 +2116,38 @@ func TestRollbackTransaction(t *testing.T) {
21162116
IncrementHelper(t, b, adapter, counterAddress, addTwoScript, 2)
21172117

21182118
}
2119+
2120+
// TestTransactionWithCadenceRandom checks Cadence's random function works
2121+
// within a transaction
2122+
func TestTransactionWithCadenceRandom(t *testing.T) {
2123+
b, adapter := setupTransactionTests(t)
2124+
2125+
code := `
2126+
transaction {
2127+
prepare() {
2128+
assert(unsafeRandom() >= 0)
2129+
}
2130+
}
2131+
`
2132+
callRandomTx := flowsdk.NewTransaction().
2133+
SetGasLimit(flowgo.DefaultMaxTransactionGasLimit).
2134+
SetScript([]byte(code)).
2135+
SetProposalKey(b.ServiceKey().Address, b.ServiceKey().Index, b.ServiceKey().SequenceNumber).
2136+
SetPayer(b.ServiceKey().Address)
2137+
2138+
signer, err := b.ServiceKey().Signer()
2139+
require.NoError(t, err)
2140+
2141+
err = callRandomTx.SignEnvelope(b.ServiceKey().Address, b.ServiceKey().Index, signer)
2142+
require.NoError(t, err)
2143+
2144+
err = adapter.SendTransaction(context.Background(), *callRandomTx)
2145+
assert.NoError(t, err)
2146+
2147+
result, err := b.ExecuteNextTransaction()
2148+
assert.NoError(t, err)
2149+
AssertTransactionSucceeded(t, result)
2150+
2151+
_, err = b.CommitBlock()
2152+
assert.NoError(t, err)
2153+
}

0 commit comments

Comments
 (0)