Skip to content

Commit

Permalink
Merge pull request #459 from onflow/tarak/fix-random
Browse files Browse the repository at this point in the history
Fix Cadence's unsafe random
  • Loading branch information
tarakby authored Aug 9, 2023
2 parents bfc2fcc + 84eb57b commit bcf6545
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 0 deletions.
14 changes: 14 additions & 0 deletions emulator/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down Expand Up @@ -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 {
Expand Down
21 changes: 21 additions & 0 deletions emulator/script_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
35 changes: 35 additions & 0 deletions emulator/transaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

0 comments on commit bcf6545

Please sign in to comment.