Skip to content

Commit

Permalink
Merge pull request #6169 from onflow/gregor/random-source-size
Browse files Browse the repository at this point in the history
[EVM] Extend random source size
  • Loading branch information
ramtinms authored Jul 5, 2024
2 parents ab87266 + 30b5831 commit b292e24
Show file tree
Hide file tree
Showing 8 changed files with 32 additions and 24 deletions.
6 changes: 3 additions & 3 deletions fvm/environment/history_random_source_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func NewRandomSourceHistoryProvider(
return NewForbiddenRandomSourceHistoryProvider()
}

const randomSourceHistoryLen = 32
const RandomSourceHistoryLength = 32

func (b *historySourceProvider) RandomSourceHistory() ([]byte, error) {
defer b.tracer.StartExtensiveTracingChildSpan(
Expand All @@ -104,7 +104,7 @@ func (b *historySourceProvider) RandomSourceHistory() ([]byte, error) {
"get random source for block randomSource failed: %w", err))
}

// A method that derives `randomSourceHistoryLen` bytes from `source` must:
// A method that derives `RandomSourceHistoryLength` bytes from `source` must:
// - extract and expand the entropy in `source`
// - output must be independent than the expanded bytes used for Cadence's `random` function
//
Expand All @@ -118,7 +118,7 @@ func (b *historySourceProvider) RandomSourceHistory() ([]byte, error) {
return nil, fmt.Errorf("failed to create a PRG from source: %w", err)
}

historySource := make([]byte, randomSourceHistoryLen)
historySource := make([]byte, RandomSourceHistoryLength)
csprg.Read(historySource)

return historySource, nil
Expand Down
9 changes: 6 additions & 3 deletions fvm/evm/evm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/onflow/flow-go/engine/execution/testutil"
"github.com/onflow/flow-go/fvm"
"github.com/onflow/flow-go/fvm/crypto"
"github.com/onflow/flow-go/fvm/environment"
envMock "github.com/onflow/flow-go/fvm/environment/mock"
"github.com/onflow/flow-go/fvm/evm"
"github.com/onflow/flow-go/fvm/evm/emulator"
Expand Down Expand Up @@ -2098,7 +2099,8 @@ func TestCadenceArch(t *testing.T) {
testAccount *EOATestAccount,
) {
entropy := []byte{13, 37}
source := []byte{91, 161, 206, 171, 100, 17, 141, 44} // coresponding out to the above entropy
// coresponding out to the above entropy
source := []byte{0x5b, 0xa1, 0xce, 0xab, 0x64, 0x11, 0x8d, 0x2c, 0xd8, 0xae, 0x8c, 0xbb, 0xf7, 0x50, 0x5e, 0xf5, 0xdf, 0xad, 0xfc, 0xf7, 0x2d, 0x3a, 0x46, 0x78, 0xd5, 0xe5, 0x1d, 0xb7, 0xf2, 0xb8, 0xe5, 0xd6}

// we must record a new heartbeat with a fixed block, we manually execute a transaction to do so,
// since doing this automatically would require a block computer and whole execution setup
Expand Down Expand Up @@ -2175,9 +2177,10 @@ func TestCadenceArch(t *testing.T) {
require.NoError(t, err)
require.NoError(t, output.Err)

res := make([]byte, 8)
res := make([]byte, environment.RandomSourceHistoryLength)
vals := output.Value.(cadence.Array).Values
vals = vals[len(vals)-8:] // only last 8 bytes is the value
require.Len(t, vals, environment.RandomSourceHistoryLength)

for i := range res {
res[i] = byte(vals[i].(cadence.UInt8))
}
Expand Down
12 changes: 6 additions & 6 deletions fvm/evm/handler/precompiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ func blockHeightProvider(backend types.Backend) func() (uint64, error) {

const RandomSourceTypeValueFieldName = "value"

func randomSourceProvider(contractAddress flow.Address, backend types.Backend) func(uint64) (uint64, error) {
return func(blockHeight uint64) (uint64, error) {
func randomSourceProvider(contractAddress flow.Address, backend types.Backend) func(uint64) ([]byte, error) {
return func(blockHeight uint64) ([]byte, error) {
value, err := backend.Invoke(
environment.ContractFunctionSpec{
AddressFromChain: func(_ flow.Chain) flow.Address {
Expand All @@ -63,21 +63,21 @@ func randomSourceProvider(contractAddress flow.Address, backend types.Backend) f
if types.IsAFatalError(err) || types.IsABackendError(err) {
panic(err)
}
return 0, err
return nil, err
}

data, ok := value.(cadence.Struct)
if !ok {
return 0, fmt.Errorf("invalid output data received from getRandomSource")
return nil, fmt.Errorf("invalid output data received from getRandomSource")
}

cadenceArray := cadence.SearchFieldByName(data, RandomSourceTypeValueFieldName).(cadence.Array)
source := make([]byte, 8)
source := make([]byte, environment.RandomSourceHistoryLength)
for i := range source {
source[i] = byte(cadenceArray.Values[i].(cadence.UInt8))
}

return binary.BigEndian.Uint64(source), nil
return source, nil
}
}

Expand Down
8 changes: 4 additions & 4 deletions fvm/evm/precompiles/arch.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func ArchContract(
address types.Address,
heightProvider func() (uint64, error),
proofVer func(*types.COAOwnershipProofInContext) (bool, error),
randomSourceProvider func(uint64) (uint64, error),
randomSourceProvider func(uint64) ([]byte, error),
revertibleRandomGenerator func() (uint64, error),
) types.PrecompiledContract {
return MultiFunctionPrecompiledContract(
Expand Down Expand Up @@ -139,7 +139,7 @@ func (f *proofVerifier) Run(input []byte) ([]byte, error) {
var _ Function = &randomnessSource{}

type randomnessSource struct {
randomSourceProvider func(uint64) (uint64, error)
randomSourceProvider func(uint64) ([]byte, error)
}

func (r *randomnessSource) FunctionSelector() FunctionSelector {
Expand All @@ -160,8 +160,8 @@ func (r *randomnessSource) Run(input []byte) ([]byte, error) {
return nil, err
}

buf := make([]byte, EncodedUint64Size)
err = EncodeUint64(rand, buf, 0)
buf := make([]byte, EncodedBytes32Size)
err = EncodeBytes32(rand, buf, 0)
if err != nil {
return nil, err
}
Expand Down
11 changes: 8 additions & 3 deletions fvm/evm/precompiles/arch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/stretchr/testify/require"

"github.com/onflow/flow-go/fvm/environment"
"github.com/onflow/flow-go/fvm/evm/precompiles"
"github.com/onflow/flow-go/fvm/evm/testutils"
"github.com/onflow/flow-go/fvm/evm/types"
Expand Down Expand Up @@ -41,12 +42,15 @@ func TestArchContract(t *testing.T) {

t.Run("test get random source", func(t *testing.T) {
address := testutils.RandomAddress(t)
rand := uint64(1337)
rand := make([]byte, environment.RandomSourceHistoryLength)
err := precompiles.EncodeBytes32([]byte{13, 23}, rand, 0)
require.NoError(t, err)

pc := precompiles.ArchContract(
address,
nil,
nil,
func(u uint64) (uint64, error) {
func(u uint64) ([]byte, error) {
return rand, nil
},
nil,
Expand All @@ -61,9 +65,10 @@ func TestArchContract(t *testing.T) {
require.Equal(t, precompiles.RandomSourceGas, pc.RequiredGas(input))

ret, err := pc.Run(input)
require.Len(t, ret, environment.RandomSourceHistoryLength)
require.NoError(t, err)

resultRand, err := precompiles.ReadUint64(ret, 0)
resultRand, err := precompiles.ReadBytes32(ret, 0)
require.NoError(t, err)
require.Equal(t, rand, resultRand)
})
Expand Down
4 changes: 2 additions & 2 deletions fvm/evm/testutils/contracts/test.sol
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ contract Storage {
revert MyCustomError(5, "Value is too low");
}

function verifyArchCallToRandomSource(uint64 height) public view returns (uint64) {
function verifyArchCallToRandomSource(uint64 height) public view returns (bytes32) {
(bool ok, bytes memory data) = cadenceArch.staticcall(abi.encodeWithSignature("getRandomSource(uint64)", height));
require(ok, "unsuccessful call to arch ");
uint64 output = abi.decode(data, (uint64));
bytes32 output = abi.decode(data, (bytes32));
return output;
}

Expand Down
4 changes: 2 additions & 2 deletions fvm/evm/testutils/contracts/test_abi.json
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,9 @@
"name": "verifyArchCallToRandomSource",
"outputs": [
{
"internalType": "uint64",
"internalType": "bytes32",
"name": "",
"type": "uint64"
"type": "bytes32"
}
],
"stateMutability": "view",
Expand Down
2 changes: 1 addition & 1 deletion fvm/evm/testutils/contracts/test_bytes.hex

Large diffs are not rendered by default.

0 comments on commit b292e24

Please sign in to comment.