From af4c50000c3f7d95f84f63c81f6144f8b00dff60 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 17 Apr 2024 17:39:46 +0200 Subject: [PATCH 01/20] add revertible random provider --- fvm/evm/handler/precompiles.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/fvm/evm/handler/precompiles.go b/fvm/evm/handler/precompiles.go index 9b21ad58648..0ff52c999bb 100644 --- a/fvm/evm/handler/precompiles.go +++ b/fvm/evm/handler/precompiles.go @@ -36,6 +36,16 @@ func blockHeightProvider(backend types.Backend) func() (uint64, error) { } } +func revertibleRandomnessProvider(backend types.Backend) ([]byte, error) { + rand := make([]byte, 128) + err := backend.ReadRandom(rand) + if err != nil { + return nil, err + } + + return rand, nil +} + func coaOwnershipProofValidator(contractAddress flow.Address, backend types.Backend) func(proof *types.COAOwnershipProofInContext) (bool, error) { return func(proof *types.COAOwnershipProofInContext) (bool, error) { value, err := backend.Invoke( From c1485213018bb5266ee9668d014a6402803e39ce Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 17 Apr 2024 17:40:16 +0200 Subject: [PATCH 02/20] add provider on init arch --- fvm/evm/precompiles/arch.go | 1 + 1 file changed, 1 insertion(+) diff --git a/fvm/evm/precompiles/arch.go b/fvm/evm/precompiles/arch.go index a396a192e84..d5fd32dc04b 100644 --- a/fvm/evm/precompiles/arch.go +++ b/fvm/evm/precompiles/arch.go @@ -31,6 +31,7 @@ func ArchContract( address types.Address, heightProvider func() (uint64, error), proofVer func(*types.COAOwnershipProofInContext) (bool, error), + revertibleRandomProvider func() ([]byte, error), ) types.Precompile { return MultiFunctionPrecompileContract( address, From ce27096c623ae72d1a5d2240631594aab2af0967 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 17 Apr 2024 17:45:49 +0200 Subject: [PATCH 03/20] define revertible random func --- fvm/evm/precompiles/arch.go | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/fvm/evm/precompiles/arch.go b/fvm/evm/precompiles/arch.go index d5fd32dc04b..2ba5722636b 100644 --- a/fvm/evm/precompiles/arch.go +++ b/fvm/evm/precompiles/arch.go @@ -14,6 +14,8 @@ var ( []string{"address", "bytes32", "bytes"}, ) + RevertibleRandomFuncSig = ComputeFunctionSelector("revertibleRandom", nil) + // FlowBlockHeightFixedGas is set to match the `number` opCode (0x43) FlowBlockHeightFixedGas = uint64(2) // ProofVerifierBaseGas covers the cost of decoding, checking capability the resource @@ -22,6 +24,13 @@ var ( // ProofVerifierGasMultiplerPerSignature is set to match `ECRECOVER` // but we might increase this in the future ProofVerifierGasMultiplerPerSignature = uint64(3_000) + + // RevertibleRandomGas covers the cost of calculating a revertible random bytes + RevertibleRandomGas = uint64(1_000) // todo define + + // errUnexpectedInput is returned when the function that doesn't expect an input + // argument, receives one + errUnexpectedInput = fmt.Errorf("unexpected input is provided") ) // ArchContract return a procompile for the Cadence Arch contract @@ -58,7 +67,7 @@ func (c *flowBlockHeight) ComputeGas(input []byte) uint64 { func (c *flowBlockHeight) Run(input []byte) ([]byte, error) { if len(input) > 0 { - return nil, fmt.Errorf("unexpected input is provided") + return nil, errUnexpectedInput } bh, err := c.flowBlockHeightLookUp() if err != nil { @@ -119,6 +128,28 @@ func (f *proofVerifier) Run(input []byte) ([]byte, error) { return buffer, EncodeBool(verified, buffer, 0) } +var _ Function = &revertibleRandomness{} + +type revertibleRandomness struct { + revertibleRandomnessProvider func() ([]byte, error) +} + +func (r *revertibleRandomness) FunctionSelector() FunctionSelector { + return RevertibleRandomFuncSig +} + +func (r *revertibleRandomness) ComputeGas(input []byte) uint64 { + return RevertibleRandomGas +} + +func (r *revertibleRandomness) Run(input []byte) ([]byte, error) { + if len(input) > 0 { + return nil, errUnexpectedInput + } + + return r.revertibleRandomnessProvider() +} + func DecodeABIEncodedProof(input []byte) (*types.COAOwnershipProofInContext, error) { index := 0 caller, err := ReadAddress(input, index) From b6f2be1e0407952c8aa167a64cfe56c99d759c46 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 17 Apr 2024 17:48:30 +0200 Subject: [PATCH 04/20] add random provider --- fvm/evm/handler/precompiles.go | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/fvm/evm/handler/precompiles.go b/fvm/evm/handler/precompiles.go index 0ff52c999bb..8b8e8cee131 100644 --- a/fvm/evm/handler/precompiles.go +++ b/fvm/evm/handler/precompiles.go @@ -22,6 +22,7 @@ func preparePrecompiles( archAddress, blockHeightProvider(backend), coaOwnershipProofValidator(evmContractAddress, backend), + revertibleRandomnessProvider(backend), ) return []types.Precompile{archContract} } @@ -36,14 +37,16 @@ func blockHeightProvider(backend types.Backend) func() (uint64, error) { } } -func revertibleRandomnessProvider(backend types.Backend) ([]byte, error) { - rand := make([]byte, 128) - err := backend.ReadRandom(rand) - if err != nil { - return nil, err - } +func revertibleRandomnessProvider(backend types.Backend) func() ([]byte, error) { + return func() ([]byte, error) { + rand := make([]byte, 128) + err := backend.ReadRandom(rand) + if err != nil { + return nil, err + } - return rand, nil + return rand, nil + } } func coaOwnershipProofValidator(contractAddress flow.Address, backend types.Backend) func(proof *types.COAOwnershipProofInContext) (bool, error) { From 24430f6465189e8e859cce28287cf00740d4466e Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 17 Apr 2024 17:52:01 +0200 Subject: [PATCH 05/20] fix tests --- fvm/evm/precompiles/arch_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fvm/evm/precompiles/arch_test.go b/fvm/evm/precompiles/arch_test.go index 33613e20265..e890f294654 100644 --- a/fvm/evm/precompiles/arch_test.go +++ b/fvm/evm/precompiles/arch_test.go @@ -21,6 +21,7 @@ func TestArchContract(t *testing.T) { return height, nil }, nil, + nil, ) input := precompiles.FlowBlockHeightFuncSig.Bytes() @@ -46,6 +47,7 @@ func TestArchContract(t *testing.T) { require.Equal(t, proof, p) return true, nil }, + nil, ) abiEncodedData, err := precompiles.ABIEncodeProof(proof) From 91687f5bff89b89f9efbfe2def4b8b0afe646e2d Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Thu, 18 Apr 2024 12:45:50 +0200 Subject: [PATCH 06/20] add revertible rand func --- fvm/evm/precompiles/arch.go | 1 + 1 file changed, 1 insertion(+) diff --git a/fvm/evm/precompiles/arch.go b/fvm/evm/precompiles/arch.go index 2ba5722636b..e5c78e21809 100644 --- a/fvm/evm/precompiles/arch.go +++ b/fvm/evm/precompiles/arch.go @@ -47,6 +47,7 @@ func ArchContract( []Function{ &flowBlockHeight{heightProvider}, &proofVerifier{proofVer}, + &revertibleRandomness{revertibleRandomProvider}, }, ) } From 4dcd3b4225ab79ef5e4d1ded8e003791b5bf9b07 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Thu, 18 Apr 2024 13:47:40 +0200 Subject: [PATCH 07/20] add revertible random call --- fvm/evm/testutils/contracts/test.sol | 7 +++++++ fvm/evm/testutils/contracts/test_abi.json | 13 +++++++++++++ fvm/evm/testutils/contracts/test_bytes.hex | 2 +- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/fvm/evm/testutils/contracts/test.sol b/fvm/evm/testutils/contracts/test.sol index ef35445274f..2f08731e067 100644 --- a/fvm/evm/testutils/contracts/test.sol +++ b/fvm/evm/testutils/contracts/test.sol @@ -48,6 +48,13 @@ contract Storage { selfdestruct(payable(msg.sender)); } + function verifyArchCallToRevertibleRandom() public view returns (uint64) { + (bool ok, bytes memory data) = cadenceArch.staticcall(abi.encodeWithSignature("revertibleRandom()")); + require(ok, "unsuccessful call to arch "); + uint64 output = abi.decode(data, (uint64)); + return output; + } + function verifyArchCallToFlowBlockHeight(uint64 expected) public view returns (uint64){ (bool ok, bytes memory data) = cadenceArch.staticcall(abi.encodeWithSignature("flowBlockHeight()")); require(ok, "unsuccessful call to arch "); diff --git a/fvm/evm/testutils/contracts/test_abi.json b/fvm/evm/testutils/contracts/test_abi.json index d0d9fef9fbd..b816a1f2888 100644 --- a/fvm/evm/testutils/contracts/test_abi.json +++ b/fvm/evm/testutils/contracts/test_abi.json @@ -153,6 +153,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "verifyArchCallToRevertibleRandom", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { diff --git a/fvm/evm/testutils/contracts/test_bytes.hex b/fvm/evm/testutils/contracts/test_bytes.hex index 1194ffe0f8d..ff59e1e1a0a 100644 --- a/fvm/evm/testutils/contracts/test_bytes.hex +++ b/fvm/evm/testutils/contracts/test_bytes.hex @@ -1 +1 @@ -6080604052610d43806100115f395ff3fe608060405234801561000f575f80fd5b50600436106100b2575f3560e01c80636057361d1161006f5780636057361d1461017a578063828dd0481461019657806383197ef0146101c657806385df51fd146101d0578063adc879e914610200578063d0d250bd1461021e576100b2565b80632e64cec1146100b657806348b15166146100d45780634cbefa6a146100f257806352e240241461010e57806357e871e71461013e5780635ec01e4d1461015c575b5f80fd5b6100be61023c565b6040516100cb9190610616565b60405180910390f35b6100dc610244565b6040516100e99190610616565b60405180910390f35b61010c6004803603810190610107919061066a565b61024b565b005b610128600480360381019061012391906106d2565b610254565b604051610135919061070c565b60405180910390f35b610146610401565b6040516101539190610616565b60405180910390f35b610164610408565b6040516101719190610616565b60405180910390f35b610194600480360381019061018f919061066a565b61040f565b005b6101b060048036038101906101ab9190610923565b610418565b6040516101bd91906109b2565b60405180910390f35b6101ce6105c7565b005b6101ea60048036038101906101e5919061066a565b6105e0565b6040516101f791906109da565b60405180910390f35b6102086105ea565b6040516102159190610616565b60405180910390f35b6102266105f1565b6040516102339190610a02565b60405180910390f35b5f8054905090565b5f42905090565b805f8190555f80fd5b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f53e87d66000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516103079190610a87565b5f60405180830381855afa9150503d805f811461033f576040519150601f19603f3d011682016040523d82523d5f602084013e610344565b606091505b509150915081610389576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161038090610af7565b60405180910390fd5b5f8180602001905181019061039e9190610b29565b90508067ffffffffffffffff168567ffffffffffffffff16146103f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ed90610bc4565b60405180910390fd5b809350505050919050565b5f43905090565b5f44905090565b805f8190555050565b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff1686868660405160240161045093929190610c2a565b6040516020818303038152906040527f5ee837e7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516104da9190610a87565b5f60405180830381855afa9150503d805f8114610512576040519150601f19603f3d011682016040523d82523d5f602084013e610517565b606091505b50915091508161055c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161055390610cb0565b60405180910390fd5b5f818060200190518101906105719190610ce2565b9050801515881515146105b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b090610bc4565b60405180910390fd5b809350505050949350505050565b3373ffffffffffffffffffffffffffffffffffffffff16ff5b5f81409050919050565b5f46905090565b6801000000000000000181565b5f819050919050565b610610816105fe565b82525050565b5f6020820190506106295f830184610607565b92915050565b5f604051905090565b5f80fd5b5f80fd5b610649816105fe565b8114610653575f80fd5b50565b5f8135905061066481610640565b92915050565b5f6020828403121561067f5761067e610638565b5b5f61068c84828501610656565b91505092915050565b5f67ffffffffffffffff82169050919050565b6106b181610695565b81146106bb575f80fd5b50565b5f813590506106cc816106a8565b92915050565b5f602082840312156106e7576106e6610638565b5b5f6106f4848285016106be565b91505092915050565b61070681610695565b82525050565b5f60208201905061071f5f8301846106fd565b92915050565b5f8115159050919050565b61073981610725565b8114610743575f80fd5b50565b5f8135905061075481610730565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6107838261075a565b9050919050565b61079381610779565b811461079d575f80fd5b50565b5f813590506107ae8161078a565b92915050565b5f819050919050565b6107c6816107b4565b81146107d0575f80fd5b50565b5f813590506107e1816107bd565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610835826107ef565b810181811067ffffffffffffffff82111715610854576108536107ff565b5b80604052505050565b5f61086661062f565b9050610872828261082c565b919050565b5f67ffffffffffffffff821115610891576108906107ff565b5b61089a826107ef565b9050602081019050919050565b828183375f83830152505050565b5f6108c76108c284610877565b61085d565b9050828152602081018484840111156108e3576108e26107eb565b5b6108ee8482856108a7565b509392505050565b5f82601f83011261090a576109096107e7565b5b813561091a8482602086016108b5565b91505092915050565b5f805f806080858703121561093b5761093a610638565b5b5f61094887828801610746565b9450506020610959878288016107a0565b935050604061096a878288016107d3565b925050606085013567ffffffffffffffff81111561098b5761098a61063c565b5b610997878288016108f6565b91505092959194509250565b6109ac81610725565b82525050565b5f6020820190506109c55f8301846109a3565b92915050565b6109d4816107b4565b82525050565b5f6020820190506109ed5f8301846109cb565b92915050565b6109fc81610779565b82525050565b5f602082019050610a155f8301846109f3565b92915050565b5f81519050919050565b5f81905092915050565b5f5b83811015610a4c578082015181840152602081019050610a31565b5f8484015250505050565b5f610a6182610a1b565b610a6b8185610a25565b9350610a7b818560208601610a2f565b80840191505092915050565b5f610a928284610a57565b915081905092915050565b5f82825260208201905092915050565b7f756e7375636365737366756c2063616c6c20746f2061726368200000000000005f82015250565b5f610ae1601a83610a9d565b9150610aec82610aad565b602082019050919050565b5f6020820190508181035f830152610b0e81610ad5565b9050919050565b5f81519050610b23816106a8565b92915050565b5f60208284031215610b3e57610b3d610638565b5b5f610b4b84828501610b15565b91505092915050565b7f6f757470757420646f65736e74206d61746368207468652065787065637465645f8201527f2076616c75650000000000000000000000000000000000000000000000000000602082015250565b5f610bae602683610a9d565b9150610bb982610b54565b604082019050919050565b5f6020820190508181035f830152610bdb81610ba2565b9050919050565b5f82825260208201905092915050565b5f610bfc82610a1b565b610c068185610be2565b9350610c16818560208601610a2f565b610c1f816107ef565b840191505092915050565b5f606082019050610c3d5f8301866109f3565b610c4a60208301856109cb565b8181036040830152610c5c8184610bf2565b9050949350505050565b7f756e7375636365737366756c2063616c6c20746f2061726368000000000000005f82015250565b5f610c9a601983610a9d565b9150610ca582610c66565b602082019050919050565b5f6020820190508181035f830152610cc781610c8e565b9050919050565b5f81519050610cdc81610730565b92915050565b5f60208284031215610cf757610cf6610638565b5b5f610d0484828501610cce565b9150509291505056fea2646970667358221220999b40bd5ac8934676e6fb864603dcd7a9b88f1f98dd05290a76aed17dc2989164736f6c63430008180033 +6080604052610eb7806100115f395ff3fe608060405234801561000f575f80fd5b50600436106100cd575f3560e01c80636057361d1161008a57806385df51fd1161006457806385df51fd146101eb578063adc879e91461021b578063b2821c8f14610239578063d0d250bd14610257576100cd565b80636057361d14610195578063828dd048146101b157806383197ef0146101e1576100cd565b80632e64cec1146100d157806348b15166146100ef5780634cbefa6a1461010d57806352e240241461012957806357e871e7146101595780635ec01e4d14610177575b5f80fd5b6100d9610275565b6040516100e691906107a4565b60405180910390f35b6100f761027d565b60405161010491906107a4565b60405180910390f35b610127600480360381019061012291906107f8565b610284565b005b610143600480360381019061013e9190610860565b61028d565b604051610150919061089a565b60405180910390f35b61016161043a565b60405161016e91906107a4565b60405180910390f35b61017f610441565b60405161018c91906107a4565b60405180910390f35b6101af60048036038101906101aa91906107f8565b610448565b005b6101cb60048036038101906101c69190610ab1565b610451565b6040516101d89190610b40565b60405180910390f35b6101e9610600565b005b610205600480360381019061020091906107f8565b610619565b6040516102129190610b68565b60405180910390f35b610223610623565b60405161023091906107a4565b60405180910390f35b61024161062a565b60405161024e919061089a565b60405180910390f35b61025f61077f565b60405161026c9190610b90565b60405180910390f35b5f8054905090565b5f42905090565b805f8190555f80fd5b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f53e87d66000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516103409190610bfb565b5f60405180830381855afa9150503d805f8114610378576040519150601f19603f3d011682016040523d82523d5f602084013e61037d565b606091505b5091509150816103c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103b990610c6b565b60405180910390fd5b5f818060200190518101906103d79190610c9d565b90508067ffffffffffffffff168567ffffffffffffffff161461042f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042690610d38565b60405180910390fd5b809350505050919050565b5f43905090565b5f44905090565b805f8190555050565b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff1686868660405160240161048993929190610d9e565b6040516020818303038152906040527f5ee837e7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516105139190610bfb565b5f60405180830381855afa9150503d805f811461054b576040519150601f19603f3d011682016040523d82523d5f602084013e610550565b606091505b509150915081610595576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058c90610e24565b60405180910390fd5b5f818060200190518101906105aa9190610e56565b9050801515881515146105f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e990610d38565b60405180910390fd5b809350505050949350505050565b3373ffffffffffffffffffffffffffffffffffffffff16ff5b5f81409050919050565b5f46905090565b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f705fab20000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516106dd9190610bfb565b5f60405180830381855afa9150503d805f8114610715576040519150601f19603f3d011682016040523d82523d5f602084013e61071a565b606091505b50915091508161075f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161075690610c6b565b60405180910390fd5b5f818060200190518101906107749190610c9d565b905080935050505090565b6801000000000000000181565b5f819050919050565b61079e8161078c565b82525050565b5f6020820190506107b75f830184610795565b92915050565b5f604051905090565b5f80fd5b5f80fd5b6107d78161078c565b81146107e1575f80fd5b50565b5f813590506107f2816107ce565b92915050565b5f6020828403121561080d5761080c6107c6565b5b5f61081a848285016107e4565b91505092915050565b5f67ffffffffffffffff82169050919050565b61083f81610823565b8114610849575f80fd5b50565b5f8135905061085a81610836565b92915050565b5f60208284031215610875576108746107c6565b5b5f6108828482850161084c565b91505092915050565b61089481610823565b82525050565b5f6020820190506108ad5f83018461088b565b92915050565b5f8115159050919050565b6108c7816108b3565b81146108d1575f80fd5b50565b5f813590506108e2816108be565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610911826108e8565b9050919050565b61092181610907565b811461092b575f80fd5b50565b5f8135905061093c81610918565b92915050565b5f819050919050565b61095481610942565b811461095e575f80fd5b50565b5f8135905061096f8161094b565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6109c38261097d565b810181811067ffffffffffffffff821117156109e2576109e161098d565b5b80604052505050565b5f6109f46107bd565b9050610a0082826109ba565b919050565b5f67ffffffffffffffff821115610a1f57610a1e61098d565b5b610a288261097d565b9050602081019050919050565b828183375f83830152505050565b5f610a55610a5084610a05565b6109eb565b905082815260208101848484011115610a7157610a70610979565b5b610a7c848285610a35565b509392505050565b5f82601f830112610a9857610a97610975565b5b8135610aa8848260208601610a43565b91505092915050565b5f805f8060808587031215610ac957610ac86107c6565b5b5f610ad6878288016108d4565b9450506020610ae78782880161092e565b9350506040610af887828801610961565b925050606085013567ffffffffffffffff811115610b1957610b186107ca565b5b610b2587828801610a84565b91505092959194509250565b610b3a816108b3565b82525050565b5f602082019050610b535f830184610b31565b92915050565b610b6281610942565b82525050565b5f602082019050610b7b5f830184610b59565b92915050565b610b8a81610907565b82525050565b5f602082019050610ba35f830184610b81565b92915050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f610bd582610ba9565b610bdf8185610bb3565b9350610bef818560208601610bbd565b80840191505092915050565b5f610c068284610bcb565b915081905092915050565b5f82825260208201905092915050565b7f756e7375636365737366756c2063616c6c20746f2061726368200000000000005f82015250565b5f610c55601a83610c11565b9150610c6082610c21565b602082019050919050565b5f6020820190508181035f830152610c8281610c49565b9050919050565b5f81519050610c9781610836565b92915050565b5f60208284031215610cb257610cb16107c6565b5b5f610cbf84828501610c89565b91505092915050565b7f6f757470757420646f65736e74206d61746368207468652065787065637465645f8201527f2076616c75650000000000000000000000000000000000000000000000000000602082015250565b5f610d22602683610c11565b9150610d2d82610cc8565b604082019050919050565b5f6020820190508181035f830152610d4f81610d16565b9050919050565b5f82825260208201905092915050565b5f610d7082610ba9565b610d7a8185610d56565b9350610d8a818560208601610bbd565b610d938161097d565b840191505092915050565b5f606082019050610db15f830186610b81565b610dbe6020830185610b59565b8181036040830152610dd08184610d66565b9050949350505050565b7f756e7375636365737366756c2063616c6c20746f2061726368000000000000005f82015250565b5f610e0e601983610c11565b9150610e1982610dda565b602082019050919050565b5f6020820190508181035f830152610e3b81610e02565b9050919050565b5f81519050610e50816108be565b92915050565b5f60208284031215610e6b57610e6a6107c6565b5b5f610e7884828501610e42565b9150509291505056fea264697066735822122091cd483397ef05f5e4feca5224a5c5482241f3de262f1381ad8a37d82779508164736f6c63430008190033 \ No newline at end of file From 75b33745504a4048aa8aa4fccc2c495b3d781f24 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Thu, 18 Apr 2024 13:53:29 +0200 Subject: [PATCH 08/20] encode the value and change to uint64 --- fvm/evm/handler/precompiles.go | 11 ++++++----- fvm/evm/precompiles/arch.go | 12 +++++++++--- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/fvm/evm/handler/precompiles.go b/fvm/evm/handler/precompiles.go index 8b8e8cee131..1887f8f8fa1 100644 --- a/fvm/evm/handler/precompiles.go +++ b/fvm/evm/handler/precompiles.go @@ -1,6 +1,7 @@ package handler import ( + "encoding/binary" "fmt" "github.com/onflow/cadence" @@ -37,15 +38,15 @@ func blockHeightProvider(backend types.Backend) func() (uint64, error) { } } -func revertibleRandomnessProvider(backend types.Backend) func() ([]byte, error) { - return func() ([]byte, error) { - rand := make([]byte, 128) +func revertibleRandomnessProvider(backend types.Backend) func() (uint64, error) { + return func() (uint64, error) { + rand := make([]byte, 8) err := backend.ReadRandom(rand) if err != nil { - return nil, err + return 0, err } - return rand, nil + return binary.BigEndian.Uint64(rand), nil } } diff --git a/fvm/evm/precompiles/arch.go b/fvm/evm/precompiles/arch.go index e5c78e21809..1a505b5957c 100644 --- a/fvm/evm/precompiles/arch.go +++ b/fvm/evm/precompiles/arch.go @@ -40,7 +40,7 @@ func ArchContract( address types.Address, heightProvider func() (uint64, error), proofVer func(*types.COAOwnershipProofInContext) (bool, error), - revertibleRandomProvider func() ([]byte, error), + revertibleRandomProvider func() (uint64, error), ) types.Precompile { return MultiFunctionPrecompileContract( address, @@ -132,7 +132,7 @@ func (f *proofVerifier) Run(input []byte) ([]byte, error) { var _ Function = &revertibleRandomness{} type revertibleRandomness struct { - revertibleRandomnessProvider func() ([]byte, error) + revertibleRandomnessProvider func() (uint64, error) } func (r *revertibleRandomness) FunctionSelector() FunctionSelector { @@ -148,7 +148,13 @@ func (r *revertibleRandomness) Run(input []byte) ([]byte, error) { return nil, errUnexpectedInput } - return r.revertibleRandomnessProvider() + rand, err := r.revertibleRandomnessProvider() + if err != nil { + return nil, err + } + + buffer := make([]byte, EncodedUint64Size) + return buffer, EncodeUint64(rand, buffer, 0) } func DecodeABIEncodedProof(input []byte) (*types.COAOwnershipProofInContext, error) { From 320f1e72be213940cd0f0c51eb42bcdf9515a072 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Thu, 18 Apr 2024 13:53:51 +0200 Subject: [PATCH 09/20] update store contract --- fvm/evm/testutils/contracts/test_bytes.hex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fvm/evm/testutils/contracts/test_bytes.hex b/fvm/evm/testutils/contracts/test_bytes.hex index ff59e1e1a0a..5986456cf17 100644 --- a/fvm/evm/testutils/contracts/test_bytes.hex +++ b/fvm/evm/testutils/contracts/test_bytes.hex @@ -1 +1 @@ -6080604052610eb7806100115f395ff3fe608060405234801561000f575f80fd5b50600436106100cd575f3560e01c80636057361d1161008a57806385df51fd1161006457806385df51fd146101eb578063adc879e91461021b578063b2821c8f14610239578063d0d250bd14610257576100cd565b80636057361d14610195578063828dd048146101b157806383197ef0146101e1576100cd565b80632e64cec1146100d157806348b15166146100ef5780634cbefa6a1461010d57806352e240241461012957806357e871e7146101595780635ec01e4d14610177575b5f80fd5b6100d9610275565b6040516100e691906107a4565b60405180910390f35b6100f761027d565b60405161010491906107a4565b60405180910390f35b610127600480360381019061012291906107f8565b610284565b005b610143600480360381019061013e9190610860565b61028d565b604051610150919061089a565b60405180910390f35b61016161043a565b60405161016e91906107a4565b60405180910390f35b61017f610441565b60405161018c91906107a4565b60405180910390f35b6101af60048036038101906101aa91906107f8565b610448565b005b6101cb60048036038101906101c69190610ab1565b610451565b6040516101d89190610b40565b60405180910390f35b6101e9610600565b005b610205600480360381019061020091906107f8565b610619565b6040516102129190610b68565b60405180910390f35b610223610623565b60405161023091906107a4565b60405180910390f35b61024161062a565b60405161024e919061089a565b60405180910390f35b61025f61077f565b60405161026c9190610b90565b60405180910390f35b5f8054905090565b5f42905090565b805f8190555f80fd5b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f53e87d66000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516103409190610bfb565b5f60405180830381855afa9150503d805f8114610378576040519150601f19603f3d011682016040523d82523d5f602084013e61037d565b606091505b5091509150816103c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103b990610c6b565b60405180910390fd5b5f818060200190518101906103d79190610c9d565b90508067ffffffffffffffff168567ffffffffffffffff161461042f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042690610d38565b60405180910390fd5b809350505050919050565b5f43905090565b5f44905090565b805f8190555050565b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff1686868660405160240161048993929190610d9e565b6040516020818303038152906040527f5ee837e7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516105139190610bfb565b5f60405180830381855afa9150503d805f811461054b576040519150601f19603f3d011682016040523d82523d5f602084013e610550565b606091505b509150915081610595576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058c90610e24565b60405180910390fd5b5f818060200190518101906105aa9190610e56565b9050801515881515146105f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e990610d38565b60405180910390fd5b809350505050949350505050565b3373ffffffffffffffffffffffffffffffffffffffff16ff5b5f81409050919050565b5f46905090565b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f705fab20000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516106dd9190610bfb565b5f60405180830381855afa9150503d805f8114610715576040519150601f19603f3d011682016040523d82523d5f602084013e61071a565b606091505b50915091508161075f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161075690610c6b565b60405180910390fd5b5f818060200190518101906107749190610c9d565b905080935050505090565b6801000000000000000181565b5f819050919050565b61079e8161078c565b82525050565b5f6020820190506107b75f830184610795565b92915050565b5f604051905090565b5f80fd5b5f80fd5b6107d78161078c565b81146107e1575f80fd5b50565b5f813590506107f2816107ce565b92915050565b5f6020828403121561080d5761080c6107c6565b5b5f61081a848285016107e4565b91505092915050565b5f67ffffffffffffffff82169050919050565b61083f81610823565b8114610849575f80fd5b50565b5f8135905061085a81610836565b92915050565b5f60208284031215610875576108746107c6565b5b5f6108828482850161084c565b91505092915050565b61089481610823565b82525050565b5f6020820190506108ad5f83018461088b565b92915050565b5f8115159050919050565b6108c7816108b3565b81146108d1575f80fd5b50565b5f813590506108e2816108be565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610911826108e8565b9050919050565b61092181610907565b811461092b575f80fd5b50565b5f8135905061093c81610918565b92915050565b5f819050919050565b61095481610942565b811461095e575f80fd5b50565b5f8135905061096f8161094b565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6109c38261097d565b810181811067ffffffffffffffff821117156109e2576109e161098d565b5b80604052505050565b5f6109f46107bd565b9050610a0082826109ba565b919050565b5f67ffffffffffffffff821115610a1f57610a1e61098d565b5b610a288261097d565b9050602081019050919050565b828183375f83830152505050565b5f610a55610a5084610a05565b6109eb565b905082815260208101848484011115610a7157610a70610979565b5b610a7c848285610a35565b509392505050565b5f82601f830112610a9857610a97610975565b5b8135610aa8848260208601610a43565b91505092915050565b5f805f8060808587031215610ac957610ac86107c6565b5b5f610ad6878288016108d4565b9450506020610ae78782880161092e565b9350506040610af887828801610961565b925050606085013567ffffffffffffffff811115610b1957610b186107ca565b5b610b2587828801610a84565b91505092959194509250565b610b3a816108b3565b82525050565b5f602082019050610b535f830184610b31565b92915050565b610b6281610942565b82525050565b5f602082019050610b7b5f830184610b59565b92915050565b610b8a81610907565b82525050565b5f602082019050610ba35f830184610b81565b92915050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f610bd582610ba9565b610bdf8185610bb3565b9350610bef818560208601610bbd565b80840191505092915050565b5f610c068284610bcb565b915081905092915050565b5f82825260208201905092915050565b7f756e7375636365737366756c2063616c6c20746f2061726368200000000000005f82015250565b5f610c55601a83610c11565b9150610c6082610c21565b602082019050919050565b5f6020820190508181035f830152610c8281610c49565b9050919050565b5f81519050610c9781610836565b92915050565b5f60208284031215610cb257610cb16107c6565b5b5f610cbf84828501610c89565b91505092915050565b7f6f757470757420646f65736e74206d61746368207468652065787065637465645f8201527f2076616c75650000000000000000000000000000000000000000000000000000602082015250565b5f610d22602683610c11565b9150610d2d82610cc8565b604082019050919050565b5f6020820190508181035f830152610d4f81610d16565b9050919050565b5f82825260208201905092915050565b5f610d7082610ba9565b610d7a8185610d56565b9350610d8a818560208601610bbd565b610d938161097d565b840191505092915050565b5f606082019050610db15f830186610b81565b610dbe6020830185610b59565b8181036040830152610dd08184610d66565b9050949350505050565b7f756e7375636365737366756c2063616c6c20746f2061726368000000000000005f82015250565b5f610e0e601983610c11565b9150610e1982610dda565b602082019050919050565b5f6020820190508181035f830152610e3b81610e02565b9050919050565b5f81519050610e50816108be565b92915050565b5f60208284031215610e6b57610e6a6107c6565b5b5f610e7884828501610e42565b9150509291505056fea264697066735822122091cd483397ef05f5e4feca5224a5c5482241f3de262f1381ad8a37d82779508164736f6c63430008190033 \ No newline at end of file +6080604052610eb7806100115f395ff3fe608060405234801561000f575f80fd5b50600436106100cd575f3560e01c80636057361d1161008a57806385df51fd1161006457806385df51fd146101eb578063adc879e91461021b578063b2821c8f14610239578063d0d250bd14610257576100cd565b80636057361d14610195578063828dd048146101b157806383197ef0146101e1576100cd565b80632e64cec1146100d157806348b15166146100ef5780634cbefa6a1461010d57806352e240241461012957806357e871e7146101595780635ec01e4d14610177575b5f80fd5b6100d9610275565b6040516100e691906107a4565b60405180910390f35b6100f761027d565b60405161010491906107a4565b60405180910390f35b610127600480360381019061012291906107f8565b610284565b005b610143600480360381019061013e9190610860565b61028d565b604051610150919061089a565b60405180910390f35b61016161043a565b60405161016e91906107a4565b60405180910390f35b61017f610441565b60405161018c91906107a4565b60405180910390f35b6101af60048036038101906101aa91906107f8565b610448565b005b6101cb60048036038101906101c69190610ab1565b610451565b6040516101d89190610b40565b60405180910390f35b6101e9610600565b005b610205600480360381019061020091906107f8565b610619565b6040516102129190610b68565b60405180910390f35b610223610623565b60405161023091906107a4565b60405180910390f35b61024161062a565b60405161024e919061089a565b60405180910390f35b61025f61077f565b60405161026c9190610b90565b60405180910390f35b5f8054905090565b5f42905090565b805f8190555f80fd5b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f53e87d66000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516103409190610bfb565b5f60405180830381855afa9150503d805f8114610378576040519150601f19603f3d011682016040523d82523d5f602084013e61037d565b606091505b5091509150816103c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103b990610c6b565b60405180910390fd5b5f818060200190518101906103d79190610c9d565b90508067ffffffffffffffff168567ffffffffffffffff161461042f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042690610d38565b60405180910390fd5b809350505050919050565b5f43905090565b5f44905090565b805f8190555050565b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff1686868660405160240161048993929190610d9e565b6040516020818303038152906040527f5ee837e7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516105139190610bfb565b5f60405180830381855afa9150503d805f811461054b576040519150601f19603f3d011682016040523d82523d5f602084013e610550565b606091505b509150915081610595576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058c90610e24565b60405180910390fd5b5f818060200190518101906105aa9190610e56565b9050801515881515146105f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e990610d38565b60405180910390fd5b809350505050949350505050565b3373ffffffffffffffffffffffffffffffffffffffff16ff5b5f81409050919050565b5f46905090565b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f705fab20000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516106dd9190610bfb565b5f60405180830381855afa9150503d805f8114610715576040519150601f19603f3d011682016040523d82523d5f602084013e61071a565b606091505b50915091508161075f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161075690610c6b565b60405180910390fd5b5f818060200190518101906107749190610c9d565b905080935050505090565b6801000000000000000181565b5f819050919050565b61079e8161078c565b82525050565b5f6020820190506107b75f830184610795565b92915050565b5f604051905090565b5f80fd5b5f80fd5b6107d78161078c565b81146107e1575f80fd5b50565b5f813590506107f2816107ce565b92915050565b5f6020828403121561080d5761080c6107c6565b5b5f61081a848285016107e4565b91505092915050565b5f67ffffffffffffffff82169050919050565b61083f81610823565b8114610849575f80fd5b50565b5f8135905061085a81610836565b92915050565b5f60208284031215610875576108746107c6565b5b5f6108828482850161084c565b91505092915050565b61089481610823565b82525050565b5f6020820190506108ad5f83018461088b565b92915050565b5f8115159050919050565b6108c7816108b3565b81146108d1575f80fd5b50565b5f813590506108e2816108be565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610911826108e8565b9050919050565b61092181610907565b811461092b575f80fd5b50565b5f8135905061093c81610918565b92915050565b5f819050919050565b61095481610942565b811461095e575f80fd5b50565b5f8135905061096f8161094b565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6109c38261097d565b810181811067ffffffffffffffff821117156109e2576109e161098d565b5b80604052505050565b5f6109f46107bd565b9050610a0082826109ba565b919050565b5f67ffffffffffffffff821115610a1f57610a1e61098d565b5b610a288261097d565b9050602081019050919050565b828183375f83830152505050565b5f610a55610a5084610a05565b6109eb565b905082815260208101848484011115610a7157610a70610979565b5b610a7c848285610a35565b509392505050565b5f82601f830112610a9857610a97610975565b5b8135610aa8848260208601610a43565b91505092915050565b5f805f8060808587031215610ac957610ac86107c6565b5b5f610ad6878288016108d4565b9450506020610ae78782880161092e565b9350506040610af887828801610961565b925050606085013567ffffffffffffffff811115610b1957610b186107ca565b5b610b2587828801610a84565b91505092959194509250565b610b3a816108b3565b82525050565b5f602082019050610b535f830184610b31565b92915050565b610b6281610942565b82525050565b5f602082019050610b7b5f830184610b59565b92915050565b610b8a81610907565b82525050565b5f602082019050610ba35f830184610b81565b92915050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f610bd582610ba9565b610bdf8185610bb3565b9350610bef818560208601610bbd565b80840191505092915050565b5f610c068284610bcb565b915081905092915050565b5f82825260208201905092915050565b7f756e7375636365737366756c2063616c6c20746f2061726368200000000000005f82015250565b5f610c55601a83610c11565b9150610c6082610c21565b602082019050919050565b5f6020820190508181035f830152610c8281610c49565b9050919050565b5f81519050610c9781610836565b92915050565b5f60208284031215610cb257610cb16107c6565b5b5f610cbf84828501610c89565b91505092915050565b7f6f757470757420646f65736e74206d61746368207468652065787065637465645f8201527f2076616c75650000000000000000000000000000000000000000000000000000602082015250565b5f610d22602683610c11565b9150610d2d82610cc8565b604082019050919050565b5f6020820190508181035f830152610d4f81610d16565b9050919050565b5f82825260208201905092915050565b5f610d7082610ba9565b610d7a8185610d56565b9350610d8a818560208601610bbd565b610d938161097d565b840191505092915050565b5f606082019050610db15f830186610b81565b610dbe6020830185610b59565b8181036040830152610dd08184610d66565b9050949350505050565b7f756e7375636365737366756c2063616c6c20746f2061726368000000000000005f82015250565b5f610e0e601983610c11565b9150610e1982610dda565b602082019050919050565b5f6020820190508181035f830152610e3b81610e02565b9050919050565b5f81519050610e50816108be565b92915050565b5f60208284031215610e6b57610e6a6107c6565b5b5f610e7884828501610e42565b9150509291505056fea2646970667358221220fbe1036541f0d1c7c0972c464634e6355f1e1eefe6589943976d2426e122b2ab64736f6c63430008190033 \ No newline at end of file From 86196d782dbd44ec116618b694ce6bda8f92f4ff Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Thu, 18 Apr 2024 14:05:21 +0200 Subject: [PATCH 10/20] check for non-zero --- fvm/evm/testutils/contracts/test_bytes.hex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fvm/evm/testutils/contracts/test_bytes.hex b/fvm/evm/testutils/contracts/test_bytes.hex index 5986456cf17..e6c7991cee8 100644 --- a/fvm/evm/testutils/contracts/test_bytes.hex +++ b/fvm/evm/testutils/contracts/test_bytes.hex @@ -1 +1 @@ -6080604052610eb7806100115f395ff3fe608060405234801561000f575f80fd5b50600436106100cd575f3560e01c80636057361d1161008a57806385df51fd1161006457806385df51fd146101eb578063adc879e91461021b578063b2821c8f14610239578063d0d250bd14610257576100cd565b80636057361d14610195578063828dd048146101b157806383197ef0146101e1576100cd565b80632e64cec1146100d157806348b15166146100ef5780634cbefa6a1461010d57806352e240241461012957806357e871e7146101595780635ec01e4d14610177575b5f80fd5b6100d9610275565b6040516100e691906107a4565b60405180910390f35b6100f761027d565b60405161010491906107a4565b60405180910390f35b610127600480360381019061012291906107f8565b610284565b005b610143600480360381019061013e9190610860565b61028d565b604051610150919061089a565b60405180910390f35b61016161043a565b60405161016e91906107a4565b60405180910390f35b61017f610441565b60405161018c91906107a4565b60405180910390f35b6101af60048036038101906101aa91906107f8565b610448565b005b6101cb60048036038101906101c69190610ab1565b610451565b6040516101d89190610b40565b60405180910390f35b6101e9610600565b005b610205600480360381019061020091906107f8565b610619565b6040516102129190610b68565b60405180910390f35b610223610623565b60405161023091906107a4565b60405180910390f35b61024161062a565b60405161024e919061089a565b60405180910390f35b61025f61077f565b60405161026c9190610b90565b60405180910390f35b5f8054905090565b5f42905090565b805f8190555f80fd5b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f53e87d66000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516103409190610bfb565b5f60405180830381855afa9150503d805f8114610378576040519150601f19603f3d011682016040523d82523d5f602084013e61037d565b606091505b5091509150816103c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103b990610c6b565b60405180910390fd5b5f818060200190518101906103d79190610c9d565b90508067ffffffffffffffff168567ffffffffffffffff161461042f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042690610d38565b60405180910390fd5b809350505050919050565b5f43905090565b5f44905090565b805f8190555050565b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff1686868660405160240161048993929190610d9e565b6040516020818303038152906040527f5ee837e7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516105139190610bfb565b5f60405180830381855afa9150503d805f811461054b576040519150601f19603f3d011682016040523d82523d5f602084013e610550565b606091505b509150915081610595576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058c90610e24565b60405180910390fd5b5f818060200190518101906105aa9190610e56565b9050801515881515146105f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e990610d38565b60405180910390fd5b809350505050949350505050565b3373ffffffffffffffffffffffffffffffffffffffff16ff5b5f81409050919050565b5f46905090565b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f705fab20000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516106dd9190610bfb565b5f60405180830381855afa9150503d805f8114610715576040519150601f19603f3d011682016040523d82523d5f602084013e61071a565b606091505b50915091508161075f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161075690610c6b565b60405180910390fd5b5f818060200190518101906107749190610c9d565b905080935050505090565b6801000000000000000181565b5f819050919050565b61079e8161078c565b82525050565b5f6020820190506107b75f830184610795565b92915050565b5f604051905090565b5f80fd5b5f80fd5b6107d78161078c565b81146107e1575f80fd5b50565b5f813590506107f2816107ce565b92915050565b5f6020828403121561080d5761080c6107c6565b5b5f61081a848285016107e4565b91505092915050565b5f67ffffffffffffffff82169050919050565b61083f81610823565b8114610849575f80fd5b50565b5f8135905061085a81610836565b92915050565b5f60208284031215610875576108746107c6565b5b5f6108828482850161084c565b91505092915050565b61089481610823565b82525050565b5f6020820190506108ad5f83018461088b565b92915050565b5f8115159050919050565b6108c7816108b3565b81146108d1575f80fd5b50565b5f813590506108e2816108be565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610911826108e8565b9050919050565b61092181610907565b811461092b575f80fd5b50565b5f8135905061093c81610918565b92915050565b5f819050919050565b61095481610942565b811461095e575f80fd5b50565b5f8135905061096f8161094b565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6109c38261097d565b810181811067ffffffffffffffff821117156109e2576109e161098d565b5b80604052505050565b5f6109f46107bd565b9050610a0082826109ba565b919050565b5f67ffffffffffffffff821115610a1f57610a1e61098d565b5b610a288261097d565b9050602081019050919050565b828183375f83830152505050565b5f610a55610a5084610a05565b6109eb565b905082815260208101848484011115610a7157610a70610979565b5b610a7c848285610a35565b509392505050565b5f82601f830112610a9857610a97610975565b5b8135610aa8848260208601610a43565b91505092915050565b5f805f8060808587031215610ac957610ac86107c6565b5b5f610ad6878288016108d4565b9450506020610ae78782880161092e565b9350506040610af887828801610961565b925050606085013567ffffffffffffffff811115610b1957610b186107ca565b5b610b2587828801610a84565b91505092959194509250565b610b3a816108b3565b82525050565b5f602082019050610b535f830184610b31565b92915050565b610b6281610942565b82525050565b5f602082019050610b7b5f830184610b59565b92915050565b610b8a81610907565b82525050565b5f602082019050610ba35f830184610b81565b92915050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f610bd582610ba9565b610bdf8185610bb3565b9350610bef818560208601610bbd565b80840191505092915050565b5f610c068284610bcb565b915081905092915050565b5f82825260208201905092915050565b7f756e7375636365737366756c2063616c6c20746f2061726368200000000000005f82015250565b5f610c55601a83610c11565b9150610c6082610c21565b602082019050919050565b5f6020820190508181035f830152610c8281610c49565b9050919050565b5f81519050610c9781610836565b92915050565b5f60208284031215610cb257610cb16107c6565b5b5f610cbf84828501610c89565b91505092915050565b7f6f757470757420646f65736e74206d61746368207468652065787065637465645f8201527f2076616c75650000000000000000000000000000000000000000000000000000602082015250565b5f610d22602683610c11565b9150610d2d82610cc8565b604082019050919050565b5f6020820190508181035f830152610d4f81610d16565b9050919050565b5f82825260208201905092915050565b5f610d7082610ba9565b610d7a8185610d56565b9350610d8a818560208601610bbd565b610d938161097d565b840191505092915050565b5f606082019050610db15f830186610b81565b610dbe6020830185610b59565b8181036040830152610dd08184610d66565b9050949350505050565b7f756e7375636365737366756c2063616c6c20746f2061726368000000000000005f82015250565b5f610e0e601983610c11565b9150610e1982610dda565b602082019050919050565b5f6020820190508181035f830152610e3b81610e02565b9050919050565b5f81519050610e50816108be565b92915050565b5f60208284031215610e6b57610e6a6107c6565b5b5f610e7884828501610e42565b9150509291505056fea2646970667358221220fbe1036541f0d1c7c0972c464634e6355f1e1eefe6589943976d2426e122b2ab64736f6c63430008190033 \ No newline at end of file +6080604052610f6b806100115f395ff3fe608060405234801561000f575f80fd5b50600436106100cd575f3560e01c80636057361d1161008a57806385df51fd1161006457806385df51fd146101eb578063adc879e91461021b578063b2821c8f14610239578063d0d250bd14610257576100cd565b80636057361d14610195578063828dd048146101b157806383197ef0146101e1576100cd565b80632e64cec1146100d157806348b15166146100ef5780634cbefa6a1461010d57806352e240241461012957806357e871e7146101595780635ec01e4d14610177575b5f80fd5b6100d9610275565b6040516100e691906107f0565b60405180910390f35b6100f761027d565b60405161010491906107f0565b60405180910390f35b61012760048036038101906101229190610844565b610284565b005b610143600480360381019061013e91906108ac565b61028d565b60405161015091906108e6565b60405180910390f35b61016161043a565b60405161016e91906107f0565b60405180910390f35b61017f610441565b60405161018c91906107f0565b60405180910390f35b6101af60048036038101906101aa9190610844565b610448565b005b6101cb60048036038101906101c69190610afd565b610451565b6040516101d89190610b8c565b60405180910390f35b6101e9610600565b005b61020560048036038101906102009190610844565b610619565b6040516102129190610bb4565b60405180910390f35b610223610623565b60405161023091906107f0565b60405180910390f35b61024161062a565b60405161024e91906108e6565b60405180910390f35b61025f6107cb565b60405161026c9190610bdc565b60405180910390f35b5f8054905090565b5f42905090565b805f8190555f80fd5b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f53e87d66000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516103409190610c47565b5f60405180830381855afa9150503d805f8114610378576040519150601f19603f3d011682016040523d82523d5f602084013e61037d565b606091505b5091509150816103c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103b990610cb7565b60405180910390fd5b5f818060200190518101906103d79190610ce9565b90508067ffffffffffffffff168567ffffffffffffffff161461042f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042690610d84565b60405180910390fd5b809350505050919050565b5f43905090565b5f44905090565b805f8190555050565b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff1686868660405160240161048993929190610dea565b6040516020818303038152906040527f5ee837e7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516105139190610c47565b5f60405180830381855afa9150503d805f811461054b576040519150601f19603f3d011682016040523d82523d5f602084013e610550565b606091505b509150915081610595576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058c90610e70565b60405180910390fd5b5f818060200190518101906105aa9190610ea2565b9050801515881515146105f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e990610d84565b60405180910390fd5b809350505050949350505050565b3373ffffffffffffffffffffffffffffffffffffffff16ff5b5f81409050919050565b5f46905090565b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f705fab20000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516106dd9190610c47565b5f60405180830381855afa9150503d805f8114610715576040519150601f19603f3d011682016040523d82523d5f602084013e61071a565b606091505b50915091508161075f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161075690610cb7565b60405180910390fd5b5f818060200190518101906107749190610ce9565b90505f8167ffffffffffffffff16036107c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107b990610f17565b60405180910390fd5b80935050505090565b6801000000000000000181565b5f819050919050565b6107ea816107d8565b82525050565b5f6020820190506108035f8301846107e1565b92915050565b5f604051905090565b5f80fd5b5f80fd5b610823816107d8565b811461082d575f80fd5b50565b5f8135905061083e8161081a565b92915050565b5f6020828403121561085957610858610812565b5b5f61086684828501610830565b91505092915050565b5f67ffffffffffffffff82169050919050565b61088b8161086f565b8114610895575f80fd5b50565b5f813590506108a681610882565b92915050565b5f602082840312156108c1576108c0610812565b5b5f6108ce84828501610898565b91505092915050565b6108e08161086f565b82525050565b5f6020820190506108f95f8301846108d7565b92915050565b5f8115159050919050565b610913816108ff565b811461091d575f80fd5b50565b5f8135905061092e8161090a565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61095d82610934565b9050919050565b61096d81610953565b8114610977575f80fd5b50565b5f8135905061098881610964565b92915050565b5f819050919050565b6109a08161098e565b81146109aa575f80fd5b50565b5f813590506109bb81610997565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610a0f826109c9565b810181811067ffffffffffffffff82111715610a2e57610a2d6109d9565b5b80604052505050565b5f610a40610809565b9050610a4c8282610a06565b919050565b5f67ffffffffffffffff821115610a6b57610a6a6109d9565b5b610a74826109c9565b9050602081019050919050565b828183375f83830152505050565b5f610aa1610a9c84610a51565b610a37565b905082815260208101848484011115610abd57610abc6109c5565b5b610ac8848285610a81565b509392505050565b5f82601f830112610ae457610ae36109c1565b5b8135610af4848260208601610a8f565b91505092915050565b5f805f8060808587031215610b1557610b14610812565b5b5f610b2287828801610920565b9450506020610b338782880161097a565b9350506040610b44878288016109ad565b925050606085013567ffffffffffffffff811115610b6557610b64610816565b5b610b7187828801610ad0565b91505092959194509250565b610b86816108ff565b82525050565b5f602082019050610b9f5f830184610b7d565b92915050565b610bae8161098e565b82525050565b5f602082019050610bc75f830184610ba5565b92915050565b610bd681610953565b82525050565b5f602082019050610bef5f830184610bcd565b92915050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f610c2182610bf5565b610c2b8185610bff565b9350610c3b818560208601610c09565b80840191505092915050565b5f610c528284610c17565b915081905092915050565b5f82825260208201905092915050565b7f756e7375636365737366756c2063616c6c20746f2061726368200000000000005f82015250565b5f610ca1601a83610c5d565b9150610cac82610c6d565b602082019050919050565b5f6020820190508181035f830152610cce81610c95565b9050919050565b5f81519050610ce381610882565b92915050565b5f60208284031215610cfe57610cfd610812565b5b5f610d0b84828501610cd5565b91505092915050565b7f6f757470757420646f65736e74206d61746368207468652065787065637465645f8201527f2076616c75650000000000000000000000000000000000000000000000000000602082015250565b5f610d6e602683610c5d565b9150610d7982610d14565b604082019050919050565b5f6020820190508181035f830152610d9b81610d62565b9050919050565b5f82825260208201905092915050565b5f610dbc82610bf5565b610dc68185610da2565b9350610dd6818560208601610c09565b610ddf816109c9565b840191505092915050565b5f606082019050610dfd5f830186610bcd565b610e0a6020830185610ba5565b8181036040830152610e1c8184610db2565b9050949350505050565b7f756e7375636365737366756c2063616c6c20746f2061726368000000000000005f82015250565b5f610e5a601983610c5d565b9150610e6582610e26565b602082019050919050565b5f6020820190508181035f830152610e8781610e4e565b9050919050565b5f81519050610e9c8161090a565b92915050565b5f60208284031215610eb757610eb6610812565b5b5f610ec484828501610e8e565b91505092915050565b7f7a65726f2072616e646f6d2076616c75650000000000000000000000000000005f82015250565b5f610f01601183610c5d565b9150610f0c82610ecd565b602082019050919050565b5f6020820190508181035f830152610f2e81610ef5565b905091905056fea26469706673582212200d2ce1bfed86c0158e037cc9ed4cdab5d0c487e214ed404cc73686ada46dd58264736f6c63430008190033 \ No newline at end of file From fc1f600929ebd78a142ce32b9d6c059ad904eeb0 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Thu, 18 Apr 2024 14:06:35 +0200 Subject: [PATCH 11/20] add test for revertible random --- fvm/evm/evm_test.go | 52 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/fvm/evm/evm_test.go b/fvm/evm/evm_test.go index ecbd3b88133..77bd6c93f64 100644 --- a/fvm/evm/evm_test.go +++ b/fvm/evm/evm_test.go @@ -756,6 +756,58 @@ func TestCadenceArch(t *testing.T) { }) }) + t.Run("testing calling Cadence arch - revertible random (happy case)", func(t *testing.T) { + chain := flow.Emulator.Chain() + sc := systemcontracts.SystemContractsForChain(chain.ChainID()) + RunWithNewEnvironment(t, + chain, func( + ctx fvm.Context, + vm fvm.VM, + snapshot snapshot.SnapshotTree, + testContract *TestContract, + testAccount *EOATestAccount, + ) { + code := []byte(fmt.Sprintf( + ` + import EVM from %s + + access(all) + fun main(tx: [UInt8], coinbaseBytes: [UInt8; 20]): EVM.Result { + let coinbase = EVM.EVMAddress(bytes: coinbaseBytes) + return EVM.run(tx: tx, coinbase: coinbase) + } + `, + sc.EVMContract.Address.HexWithPrefix(), + )) + + innerTxBytes := testAccount.PrepareSignAndEncodeTx(t, + testContract.DeployedAt.ToCommon(), + testContract.MakeCallData(t, "verifyArchCallToRevertibleRandom"), + big.NewInt(0), + uint64(10_000_000), + big.NewInt(0), + ) + script := fvm.Script(code).WithArguments( + json.MustEncode( + cadence.NewArray( + ConvertToCadence(innerTxBytes), + ).WithType(stdlib.EVMTransactionBytesCadenceType), + ), + json.MustEncode( + cadence.NewArray( + ConvertToCadence(testAccount.Address().Bytes()), + ).WithType(stdlib.EVMAddressBytesCadenceType), + ), + ) + _, output, err := vm.Run( + ctx, + script, + snapshot) + require.NoError(t, err) + require.NoError(t, output.Err) + }) + }) + t.Run("testing calling Cadence arch - COA ownership proof (happy case)", func(t *testing.T) { chain := flow.Emulator.Chain() sc := systemcontracts.SystemContractsForChain(chain.ChainID()) From d4cd6035c16f5786e08084fea08743c8a6c22f87 Mon Sep 17 00:00:00 2001 From: Gregor G Date: Fri, 19 Apr 2024 16:07:48 +0200 Subject: [PATCH 12/20] add get random source function --- fvm/evm/precompiles/arch.go | 41 +++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/fvm/evm/precompiles/arch.go b/fvm/evm/precompiles/arch.go index 1a505b5957c..c5658bfac39 100644 --- a/fvm/evm/precompiles/arch.go +++ b/fvm/evm/precompiles/arch.go @@ -14,7 +14,7 @@ var ( []string{"address", "bytes32", "bytes"}, ) - RevertibleRandomFuncSig = ComputeFunctionSelector("revertibleRandom", nil) + RandomSourceFuncSig = ComputeFunctionSelector("getRandomSource", []string{"uint64"}) // FlowBlockHeightFixedGas is set to match the `number` opCode (0x43) FlowBlockHeightFixedGas = uint64(2) @@ -25,8 +25,8 @@ var ( // but we might increase this in the future ProofVerifierGasMultiplerPerSignature = uint64(3_000) - // RevertibleRandomGas covers the cost of calculating a revertible random bytes - RevertibleRandomGas = uint64(1_000) // todo define + // RandomSourceGas covers the cost of calculating a revertible random bytes + RandomSourceGas = uint64(1_000) // todo define // errUnexpectedInput is returned when the function that doesn't expect an input // argument, receives one @@ -40,14 +40,14 @@ func ArchContract( address types.Address, heightProvider func() (uint64, error), proofVer func(*types.COAOwnershipProofInContext) (bool, error), - revertibleRandomProvider func() (uint64, error), + randomSourceProvider func(uint64) (uint64, error), ) types.Precompile { return MultiFunctionPrecompileContract( address, []Function{ &flowBlockHeight{heightProvider}, &proofVerifier{proofVer}, - &revertibleRandomness{revertibleRandomProvider}, + &randomnessSource{randomSourceProvider}, }, ) } @@ -129,32 +129,37 @@ func (f *proofVerifier) Run(input []byte) ([]byte, error) { return buffer, EncodeBool(verified, buffer, 0) } -var _ Function = &revertibleRandomness{} +var _ Function = &randomnessSource{} -type revertibleRandomness struct { - revertibleRandomnessProvider func() (uint64, error) +type randomnessSource struct { + randomSourceProvider func(uint64) (uint64, error) } -func (r *revertibleRandomness) FunctionSelector() FunctionSelector { - return RevertibleRandomFuncSig +func (r *randomnessSource) FunctionSelector() FunctionSelector { + return RandomSourceFuncSig } -func (r *revertibleRandomness) ComputeGas(input []byte) uint64 { - return RevertibleRandomGas +func (r *randomnessSource) ComputeGas(input []byte) uint64 { + return RandomSourceGas } -func (r *revertibleRandomness) Run(input []byte) ([]byte, error) { - if len(input) > 0 { - return nil, errUnexpectedInput +func (r *randomnessSource) Run(input []byte) ([]byte, error) { + height, err := ReadUint64(input, 0) + if err != nil { + return nil, err + } + rand, err := r.randomSourceProvider(height) + if err != nil { + return nil, err } - rand, err := r.revertibleRandomnessProvider() + buf := make([]byte, EncodedUint64Size) + err = EncodeUint64(rand, buf, 0) if err != nil { return nil, err } - buffer := make([]byte, EncodedUint64Size) - return buffer, EncodeUint64(rand, buffer, 0) + return buf, nil } func DecodeABIEncodedProof(input []byte) (*types.COAOwnershipProofInContext, error) { From 6df47638c4db8372adb264208eeb956fbdbd9dda Mon Sep 17 00:00:00 2001 From: Gregor G Date: Fri, 19 Apr 2024 16:08:02 +0200 Subject: [PATCH 13/20] use random beacon contract address --- fvm/evm/evm.go | 7 +++++++ fvm/evm/handler/handler.go | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/fvm/evm/evm.go b/fvm/evm/evm.go index a29ab9f67cf..b0db385e751 100644 --- a/fvm/evm/evm.go +++ b/fvm/evm/evm.go @@ -23,6 +23,10 @@ func StorageAccountAddress(chainID flow.ChainID) (flow.Address, error) { return sc.EVMStorage.Address, nil } +func RandomBeaconAddress(chainID flow.ChainID) flow.Address { + return systemcontracts.SystemContractsForChain(chainID).RandomBeaconHistory.Address +} + func SetupEnvironment( chainID flow.ChainID, fvmEnv environment.Environment, @@ -39,6 +43,8 @@ func SetupEnvironment( return err } + randomBeaconAddress := RandomBeaconAddress(chainID) + backend := backends.NewWrappedEnvironment(fvmEnv) emulator := evm.NewEmulator(backend, evmStorageAccountAddress) @@ -51,6 +57,7 @@ func SetupEnvironment( chainID, evmContractAccountAddress, common.Address(flowToken), + randomBeaconAddress, blockStore, addressAllocator, backend, diff --git a/fvm/evm/handler/handler.go b/fvm/evm/handler/handler.go index 663c71c8c03..de00f8ec5e8 100644 --- a/fvm/evm/handler/handler.go +++ b/fvm/evm/handler/handler.go @@ -43,6 +43,7 @@ func NewContractHandler( flowChainID flow.ChainID, evmContractAddress flow.Address, flowTokenAddress common.Address, + randomBeaconAddress flow.Address, blockStore types.BlockStore, addressAllocator types.AddressAllocator, backend types.Backend, @@ -56,7 +57,7 @@ func NewContractHandler( addressAllocator: addressAllocator, backend: backend, emulator: emulator, - precompiles: preparePrecompiles(evmContractAddress, addressAllocator, backend), + precompiles: preparePrecompiles(evmContractAddress, randomBeaconAddress, addressAllocator, backend), } } From 882763d9e626e05b6c1b43b021f562c5356411a3 Mon Sep 17 00:00:00 2001 From: Gregor G Date: Fri, 19 Apr 2024 16:08:17 +0200 Subject: [PATCH 14/20] random source provider --- fvm/evm/handler/precompiles.go | 39 ++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/fvm/evm/handler/precompiles.go b/fvm/evm/handler/precompiles.go index 1887f8f8fa1..fd88a6f0707 100644 --- a/fvm/evm/handler/precompiles.go +++ b/fvm/evm/handler/precompiles.go @@ -15,6 +15,7 @@ import ( func preparePrecompiles( evmContractAddress flow.Address, + randomBeaconAddress flow.Address, addressAllocator types.AddressAllocator, backend types.Backend, ) []types.Precompile { @@ -23,7 +24,7 @@ func preparePrecompiles( archAddress, blockHeightProvider(backend), coaOwnershipProofValidator(evmContractAddress, backend), - revertibleRandomnessProvider(backend), + randomSourceProvider(randomBeaconAddress, backend), ) return []types.Precompile{archContract} } @@ -38,15 +39,41 @@ func blockHeightProvider(backend types.Backend) func() (uint64, error) { } } -func revertibleRandomnessProvider(backend types.Backend) func() (uint64, error) { - return func() (uint64, error) { - rand := make([]byte, 8) - err := backend.ReadRandom(rand) +func randomSourceProvider(contractAddress flow.Address, backend types.Backend) func(uint64) (uint64, error) { + return func(blockHeight uint64) (uint64, error) { + value, err := backend.Invoke( + environment.ContractFunctionSpec{ + AddressFromChain: func(_ flow.Chain) flow.Address { + return contractAddress + }, + LocationName: "RandomBeaconHistory", + FunctionName: "sourceOfRandomness", + ArgumentTypes: []sema.Type{ + sema.UInt64Type, + }, + }, + []cadence.Value{ + cadence.NewUInt64(blockHeight), + }, + ) if err != nil { + if types.IsAFatalError(err) || types.IsABackendError(err) { + panic(err) + } return 0, err } - return binary.BigEndian.Uint64(rand), nil + data, ok := value.(cadence.Struct) + if !ok { + return 0, fmt.Errorf("invalid output data received from getRandomSource") + } + + cadenceArray := data.Fields[1].(cadence.Array) + source := make([]byte, 8) + for i := range source { + source[i] = cadenceArray.Values[i].ToGoValue().(byte) + } + return binary.BigEndian.Uint64(source), nil } } From 3bb92b2770dae814431cd6fd294b7bab3eb2051e Mon Sep 17 00:00:00 2001 From: Gregor G Date: Fri, 19 Apr 2024 16:08:25 +0200 Subject: [PATCH 15/20] update test contract for random source test --- fvm/evm/testutils/contracts/test.sol | 6 +++--- fvm/evm/testutils/contracts/test_abi.json | 10 ++++++++-- fvm/evm/testutils/contracts/test_bytes.hex | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/fvm/evm/testutils/contracts/test.sol b/fvm/evm/testutils/contracts/test.sol index 2f08731e067..8d2c3a4bef8 100644 --- a/fvm/evm/testutils/contracts/test.sol +++ b/fvm/evm/testutils/contracts/test.sol @@ -48,9 +48,9 @@ contract Storage { selfdestruct(payable(msg.sender)); } - function verifyArchCallToRevertibleRandom() public view returns (uint64) { - (bool ok, bytes memory data) = cadenceArch.staticcall(abi.encodeWithSignature("revertibleRandom()")); - require(ok, "unsuccessful call to arch "); + function verifyArchCallToRandomSource(uint64 height) public view returns (uint64) { + (bool ok, bytes memory data) = cadenceArch.staticcall(abi.encodeWithSignature("getRandomSource(uint64)", height)); + //require(ok, "unsuccessful call to arch "); uint64 output = abi.decode(data, (uint64)); return output; } diff --git a/fvm/evm/testutils/contracts/test_abi.json b/fvm/evm/testutils/contracts/test_abi.json index b816a1f2888..59712df3a92 100644 --- a/fvm/evm/testutils/contracts/test_abi.json +++ b/fvm/evm/testutils/contracts/test_abi.json @@ -154,8 +154,14 @@ "type": "function" }, { - "inputs": [], - "name": "verifyArchCallToRevertibleRandom", + "inputs": [ + { + "internalType": "uint64", + "name": "height", + "type": "uint64" + } + ], + "name": "verifyArchCallToRandomSource", "outputs": [ { "internalType": "uint64", diff --git a/fvm/evm/testutils/contracts/test_bytes.hex b/fvm/evm/testutils/contracts/test_bytes.hex index e6c7991cee8..4ff084274fb 100644 --- a/fvm/evm/testutils/contracts/test_bytes.hex +++ b/fvm/evm/testutils/contracts/test_bytes.hex @@ -1 +1 @@ -6080604052610f6b806100115f395ff3fe608060405234801561000f575f80fd5b50600436106100cd575f3560e01c80636057361d1161008a57806385df51fd1161006457806385df51fd146101eb578063adc879e91461021b578063b2821c8f14610239578063d0d250bd14610257576100cd565b80636057361d14610195578063828dd048146101b157806383197ef0146101e1576100cd565b80632e64cec1146100d157806348b15166146100ef5780634cbefa6a1461010d57806352e240241461012957806357e871e7146101595780635ec01e4d14610177575b5f80fd5b6100d9610275565b6040516100e691906107f0565b60405180910390f35b6100f761027d565b60405161010491906107f0565b60405180910390f35b61012760048036038101906101229190610844565b610284565b005b610143600480360381019061013e91906108ac565b61028d565b60405161015091906108e6565b60405180910390f35b61016161043a565b60405161016e91906107f0565b60405180910390f35b61017f610441565b60405161018c91906107f0565b60405180910390f35b6101af60048036038101906101aa9190610844565b610448565b005b6101cb60048036038101906101c69190610afd565b610451565b6040516101d89190610b8c565b60405180910390f35b6101e9610600565b005b61020560048036038101906102009190610844565b610619565b6040516102129190610bb4565b60405180910390f35b610223610623565b60405161023091906107f0565b60405180910390f35b61024161062a565b60405161024e91906108e6565b60405180910390f35b61025f6107cb565b60405161026c9190610bdc565b60405180910390f35b5f8054905090565b5f42905090565b805f8190555f80fd5b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f53e87d66000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516103409190610c47565b5f60405180830381855afa9150503d805f8114610378576040519150601f19603f3d011682016040523d82523d5f602084013e61037d565b606091505b5091509150816103c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103b990610cb7565b60405180910390fd5b5f818060200190518101906103d79190610ce9565b90508067ffffffffffffffff168567ffffffffffffffff161461042f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042690610d84565b60405180910390fd5b809350505050919050565b5f43905090565b5f44905090565b805f8190555050565b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff1686868660405160240161048993929190610dea565b6040516020818303038152906040527f5ee837e7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516105139190610c47565b5f60405180830381855afa9150503d805f811461054b576040519150601f19603f3d011682016040523d82523d5f602084013e610550565b606091505b509150915081610595576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058c90610e70565b60405180910390fd5b5f818060200190518101906105aa9190610ea2565b9050801515881515146105f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e990610d84565b60405180910390fd5b809350505050949350505050565b3373ffffffffffffffffffffffffffffffffffffffff16ff5b5f81409050919050565b5f46905090565b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f705fab20000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516106dd9190610c47565b5f60405180830381855afa9150503d805f8114610715576040519150601f19603f3d011682016040523d82523d5f602084013e61071a565b606091505b50915091508161075f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161075690610cb7565b60405180910390fd5b5f818060200190518101906107749190610ce9565b90505f8167ffffffffffffffff16036107c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107b990610f17565b60405180910390fd5b80935050505090565b6801000000000000000181565b5f819050919050565b6107ea816107d8565b82525050565b5f6020820190506108035f8301846107e1565b92915050565b5f604051905090565b5f80fd5b5f80fd5b610823816107d8565b811461082d575f80fd5b50565b5f8135905061083e8161081a565b92915050565b5f6020828403121561085957610858610812565b5b5f61086684828501610830565b91505092915050565b5f67ffffffffffffffff82169050919050565b61088b8161086f565b8114610895575f80fd5b50565b5f813590506108a681610882565b92915050565b5f602082840312156108c1576108c0610812565b5b5f6108ce84828501610898565b91505092915050565b6108e08161086f565b82525050565b5f6020820190506108f95f8301846108d7565b92915050565b5f8115159050919050565b610913816108ff565b811461091d575f80fd5b50565b5f8135905061092e8161090a565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61095d82610934565b9050919050565b61096d81610953565b8114610977575f80fd5b50565b5f8135905061098881610964565b92915050565b5f819050919050565b6109a08161098e565b81146109aa575f80fd5b50565b5f813590506109bb81610997565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610a0f826109c9565b810181811067ffffffffffffffff82111715610a2e57610a2d6109d9565b5b80604052505050565b5f610a40610809565b9050610a4c8282610a06565b919050565b5f67ffffffffffffffff821115610a6b57610a6a6109d9565b5b610a74826109c9565b9050602081019050919050565b828183375f83830152505050565b5f610aa1610a9c84610a51565b610a37565b905082815260208101848484011115610abd57610abc6109c5565b5b610ac8848285610a81565b509392505050565b5f82601f830112610ae457610ae36109c1565b5b8135610af4848260208601610a8f565b91505092915050565b5f805f8060808587031215610b1557610b14610812565b5b5f610b2287828801610920565b9450506020610b338782880161097a565b9350506040610b44878288016109ad565b925050606085013567ffffffffffffffff811115610b6557610b64610816565b5b610b7187828801610ad0565b91505092959194509250565b610b86816108ff565b82525050565b5f602082019050610b9f5f830184610b7d565b92915050565b610bae8161098e565b82525050565b5f602082019050610bc75f830184610ba5565b92915050565b610bd681610953565b82525050565b5f602082019050610bef5f830184610bcd565b92915050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f610c2182610bf5565b610c2b8185610bff565b9350610c3b818560208601610c09565b80840191505092915050565b5f610c528284610c17565b915081905092915050565b5f82825260208201905092915050565b7f756e7375636365737366756c2063616c6c20746f2061726368200000000000005f82015250565b5f610ca1601a83610c5d565b9150610cac82610c6d565b602082019050919050565b5f6020820190508181035f830152610cce81610c95565b9050919050565b5f81519050610ce381610882565b92915050565b5f60208284031215610cfe57610cfd610812565b5b5f610d0b84828501610cd5565b91505092915050565b7f6f757470757420646f65736e74206d61746368207468652065787065637465645f8201527f2076616c75650000000000000000000000000000000000000000000000000000602082015250565b5f610d6e602683610c5d565b9150610d7982610d14565b604082019050919050565b5f6020820190508181035f830152610d9b81610d62565b9050919050565b5f82825260208201905092915050565b5f610dbc82610bf5565b610dc68185610da2565b9350610dd6818560208601610c09565b610ddf816109c9565b840191505092915050565b5f606082019050610dfd5f830186610bcd565b610e0a6020830185610ba5565b8181036040830152610e1c8184610db2565b9050949350505050565b7f756e7375636365737366756c2063616c6c20746f2061726368000000000000005f82015250565b5f610e5a601983610c5d565b9150610e6582610e26565b602082019050919050565b5f6020820190508181035f830152610e8781610e4e565b9050919050565b5f81519050610e9c8161090a565b92915050565b5f60208284031215610eb757610eb6610812565b5b5f610ec484828501610e8e565b91505092915050565b7f7a65726f2072616e646f6d2076616c75650000000000000000000000000000005f82015250565b5f610f01601183610c5d565b9150610f0c82610ecd565b602082019050919050565b5f6020820190508181035f830152610f2e81610ef5565b905091905056fea26469706673582212200d2ce1bfed86c0158e037cc9ed4cdab5d0c487e214ed404cc73686ada46dd58264736f6c63430008190033 \ No newline at end of file +6080604052610ed6806100115f395ff3fe608060405234801561000f575f80fd5b50600436106100cd575f3560e01c80636057361d1161008a57806385df51fd1161006457806385df51fd146101eb578063911007b41461021b578063adc879e91461024b578063d0d250bd14610269576100cd565b80636057361d14610195578063828dd048146101b157806383197ef0146101e1576100cd565b80632e64cec1146100d157806348b15166146100ef5780634cbefa6a1461010d57806352e240241461012957806357e871e7146101595780635ec01e4d14610177575b5f80fd5b6100d9610287565b6040516100e691906107c3565b60405180910390f35b6100f761028f565b60405161010491906107c3565b60405180910390f35b61012760048036038101906101229190610817565b610296565b005b610143600480360381019061013e919061087f565b61029f565b60405161015091906108b9565b60405180910390f35b61016161044c565b60405161016e91906107c3565b60405180910390f35b61017f610453565b60405161018c91906107c3565b60405180910390f35b6101af60048036038101906101aa9190610817565b61045a565b005b6101cb60048036038101906101c69190610ad0565b610463565b6040516101d89190610b5f565b60405180910390f35b6101e9610612565b005b61020560048036038101906102009190610817565b61062b565b6040516102129190610b87565b60405180910390f35b6102356004803603810190610230919061087f565b610635565b60405161024291906108b9565b60405180910390f35b610253610797565b60405161026091906107c3565b60405180910390f35b61027161079e565b60405161027e9190610baf565b60405180910390f35b5f8054905090565b5f42905090565b805f8190555f80fd5b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f53e87d66000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516103529190610c1a565b5f60405180830381855afa9150503d805f811461038a576040519150601f19603f3d011682016040523d82523d5f602084013e61038f565b606091505b5091509150816103d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103cb90610c8a565b60405180910390fd5b5f818060200190518101906103e99190610cbc565b90508067ffffffffffffffff168567ffffffffffffffff1614610441576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161043890610d57565b60405180910390fd5b809350505050919050565b5f43905090565b5f44905090565b805f8190555050565b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff1686868660405160240161049b93929190610dbd565b6040516020818303038152906040527f5ee837e7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516105259190610c1a565b5f60405180830381855afa9150503d805f811461055d576040519150601f19603f3d011682016040523d82523d5f602084013e610562565b606091505b5091509150816105a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161059e90610e43565b60405180910390fd5b5f818060200190518101906105bc9190610e75565b905080151588151514610604576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105fb90610d57565b60405180910390fd5b809350505050949350505050565b3373ffffffffffffffffffffffffffffffffffffffff16ff5b5f81409050919050565b5f805f6801000000000000000173ffffffffffffffffffffffffffffffffffffffff168460405160240161066991906108b9565b6040516020818303038152906040527f78a75fbe000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516106f39190610c1a565b5f60405180830381855afa9150503d805f811461072b576040519150601f19603f3d011682016040523d82523d5f602084013e610730565b606091505b509150915081610775576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161076c90610c8a565b60405180910390fd5b5f8180602001905181019061078a9190610cbc565b9050809350505050919050565b5f46905090565b6801000000000000000181565b5f819050919050565b6107bd816107ab565b82525050565b5f6020820190506107d65f8301846107b4565b92915050565b5f604051905090565b5f80fd5b5f80fd5b6107f6816107ab565b8114610800575f80fd5b50565b5f81359050610811816107ed565b92915050565b5f6020828403121561082c5761082b6107e5565b5b5f61083984828501610803565b91505092915050565b5f67ffffffffffffffff82169050919050565b61085e81610842565b8114610868575f80fd5b50565b5f8135905061087981610855565b92915050565b5f60208284031215610894576108936107e5565b5b5f6108a18482850161086b565b91505092915050565b6108b381610842565b82525050565b5f6020820190506108cc5f8301846108aa565b92915050565b5f8115159050919050565b6108e6816108d2565b81146108f0575f80fd5b50565b5f81359050610901816108dd565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61093082610907565b9050919050565b61094081610926565b811461094a575f80fd5b50565b5f8135905061095b81610937565b92915050565b5f819050919050565b61097381610961565b811461097d575f80fd5b50565b5f8135905061098e8161096a565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6109e28261099c565b810181811067ffffffffffffffff82111715610a0157610a006109ac565b5b80604052505050565b5f610a136107dc565b9050610a1f82826109d9565b919050565b5f67ffffffffffffffff821115610a3e57610a3d6109ac565b5b610a478261099c565b9050602081019050919050565b828183375f83830152505050565b5f610a74610a6f84610a24565b610a0a565b905082815260208101848484011115610a9057610a8f610998565b5b610a9b848285610a54565b509392505050565b5f82601f830112610ab757610ab6610994565b5b8135610ac7848260208601610a62565b91505092915050565b5f805f8060808587031215610ae857610ae76107e5565b5b5f610af5878288016108f3565b9450506020610b068782880161094d565b9350506040610b1787828801610980565b925050606085013567ffffffffffffffff811115610b3857610b376107e9565b5b610b4487828801610aa3565b91505092959194509250565b610b59816108d2565b82525050565b5f602082019050610b725f830184610b50565b92915050565b610b8181610961565b82525050565b5f602082019050610b9a5f830184610b78565b92915050565b610ba981610926565b82525050565b5f602082019050610bc25f830184610ba0565b92915050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f610bf482610bc8565b610bfe8185610bd2565b9350610c0e818560208601610bdc565b80840191505092915050565b5f610c258284610bea565b915081905092915050565b5f82825260208201905092915050565b7f756e7375636365737366756c2063616c6c20746f2061726368200000000000005f82015250565b5f610c74601a83610c30565b9150610c7f82610c40565b602082019050919050565b5f6020820190508181035f830152610ca181610c68565b9050919050565b5f81519050610cb681610855565b92915050565b5f60208284031215610cd157610cd06107e5565b5b5f610cde84828501610ca8565b91505092915050565b7f6f757470757420646f65736e74206d61746368207468652065787065637465645f8201527f2076616c75650000000000000000000000000000000000000000000000000000602082015250565b5f610d41602683610c30565b9150610d4c82610ce7565b604082019050919050565b5f6020820190508181035f830152610d6e81610d35565b9050919050565b5f82825260208201905092915050565b5f610d8f82610bc8565b610d998185610d75565b9350610da9818560208601610bdc565b610db28161099c565b840191505092915050565b5f606082019050610dd05f830186610ba0565b610ddd6020830185610b78565b8181036040830152610def8184610d85565b9050949350505050565b7f756e7375636365737366756c2063616c6c20746f2061726368000000000000005f82015250565b5f610e2d601983610c30565b9150610e3882610df9565b602082019050919050565b5f6020820190508181035f830152610e5a81610e21565b9050919050565b5f81519050610e6f816108dd565b92915050565b5f60208284031215610e8a57610e896107e5565b5b5f610e9784828501610e61565b9150509291505056fea2646970667358221220779580cda4620f587da2be1f07924a019675a839731e81f8e2b6752c87edbc5764736f6c63430008190033 \ No newline at end of file From a3ab4d017381d95c2ec57a5ee27f06a28ba394de Mon Sep 17 00:00:00 2001 From: Gregor G Date: Fri, 19 Apr 2024 16:08:36 +0200 Subject: [PATCH 16/20] add random source test --- fvm/evm/evm_test.go | 56 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/fvm/evm/evm_test.go b/fvm/evm/evm_test.go index 77bd6c93f64..123dc3be395 100644 --- a/fvm/evm/evm_test.go +++ b/fvm/evm/evm_test.go @@ -756,7 +756,7 @@ func TestCadenceArch(t *testing.T) { }) }) - t.Run("testing calling Cadence arch - revertible random (happy case)", func(t *testing.T) { + t.Run("testing calling Cadence arch - random source (happy case)", func(t *testing.T) { chain := flow.Emulator.Chain() sc := systemcontracts.SystemContractsForChain(chain.ChainID()) RunWithNewEnvironment(t, @@ -767,22 +767,61 @@ func TestCadenceArch(t *testing.T) { testContract *TestContract, testAccount *EOATestAccount, ) { + entropy := []byte{13, 37} + source := []byte{91, 161, 206, 171, 100, 17, 141, 44} // coresponding out to the above entropy + + // 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 + height := uint64(1) + block1 := unittest.BlockFixture() + block1.Header.Height = height + ctx.BlockHeader = block1.Header + ctx.EntropyProvider = testutil.EntropyProviderFixture(entropy) // fix the entropy + + txBody := flow.NewTransactionBody(). + SetScript([]byte(fmt.Sprintf(` + import RandomBeaconHistory from %s + + transaction { + prepare(serviceAccount: AuthAccount) { + let randomBeaconHistoryHeartbeat = serviceAccount.borrow<&RandomBeaconHistory.Heartbeat>( + from: RandomBeaconHistory.HeartbeatStoragePath) + ?? panic("Couldn't borrow RandomBeaconHistory.Heartbeat Resource") + randomBeaconHistoryHeartbeat.heartbeat(randomSourceHistory: randomSourceHistory()) + } + }`, sc.RandomBeaconHistory.Address.HexWithPrefix())), + ). + AddAuthorizer(sc.FlowServiceAccount.Address) + + s, out, err := vm.Run(ctx, fvm.Transaction(txBody, 0), snapshot) + require.NoError(t, err) + require.NoError(t, out.Err) + + snapshot = snapshot.Append(s) + code := []byte(fmt.Sprintf( ` import EVM from %s access(all) - fun main(tx: [UInt8], coinbaseBytes: [UInt8; 20]): EVM.Result { + fun main(tx: [UInt8], coinbaseBytes: [UInt8; 20]): [UInt8] { let coinbase = EVM.EVMAddress(bytes: coinbaseBytes) - return EVM.run(tx: tx, coinbase: coinbase) + let res = EVM.run(tx: tx, coinbase: coinbase) + assert(res.status == EVM.Status.successful, message: "evm tx wrong status") + return res.data } `, sc.EVMContract.Address.HexWithPrefix(), )) + // we fake progressing to new block height since random beacon does the check the + // current height (2) is bigger than the height requested (1) + block1.Header.Height = 2 + ctx.BlockHeader = block1.Header + innerTxBytes := testAccount.PrepareSignAndEncodeTx(t, testContract.DeployedAt.ToCommon(), - testContract.MakeCallData(t, "verifyArchCallToRevertibleRandom"), + testContract.MakeCallData(t, "verifyArchCallToRandomSource", height), big.NewInt(0), uint64(10_000_000), big.NewInt(0), @@ -805,6 +844,14 @@ func TestCadenceArch(t *testing.T) { snapshot) require.NoError(t, err) require.NoError(t, output.Err) + + res := make([]byte, 8) + vals := output.Value.(cadence.Array).Values + vals = vals[len(vals)-8:] // only last 8 bytes is the value + for i := range res { + res[i] = vals[i].ToGoValue().(byte) + } + require.Equal(t, source, res) }) }) @@ -1173,6 +1220,7 @@ func RunWithNewEnvironment( fvm.WithAuthorizationChecksEnabled(false), fvm.WithSequenceNumberCheckAndIncrementEnabled(false), fvm.WithEntropyProvider(testutil.EntropyProviderFixture(nil)), + fvm.WithRandomSourceHistoryCallAllowed(true), fvm.WithBlocks(blocks), } ctx := fvm.NewContext(opts...) From afe19b1923460567cb34b447e420b39909cec4b7 Mon Sep 17 00:00:00 2001 From: Gregor G Date: Fri, 19 Apr 2024 16:23:24 +0200 Subject: [PATCH 17/20] add a fail test --- fvm/evm/evm_test.go | 88 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/fvm/evm/evm_test.go b/fvm/evm/evm_test.go index 123dc3be395..d25f0b5df4b 100644 --- a/fvm/evm/evm_test.go +++ b/fvm/evm/evm_test.go @@ -855,6 +855,94 @@ func TestCadenceArch(t *testing.T) { }) }) + t.Run("testing calling Cadence arch - random source (failed due to incorrect height)", func(t *testing.T) { + chain := flow.Emulator.Chain() + sc := systemcontracts.SystemContractsForChain(chain.ChainID()) + RunWithNewEnvironment(t, + chain, func( + ctx fvm.Context, + vm fvm.VM, + snapshot snapshot.SnapshotTree, + testContract *TestContract, + testAccount *EOATestAccount, + ) { + // 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 + height := uint64(1) + block1 := unittest.BlockFixture() + block1.Header.Height = height + ctx.BlockHeader = block1.Header + + txBody := flow.NewTransactionBody(). + SetScript([]byte(fmt.Sprintf(` + import RandomBeaconHistory from %s + + transaction { + prepare(serviceAccount: AuthAccount) { + let randomBeaconHistoryHeartbeat = serviceAccount.borrow<&RandomBeaconHistory.Heartbeat>( + from: RandomBeaconHistory.HeartbeatStoragePath) + ?? panic("Couldn't borrow RandomBeaconHistory.Heartbeat Resource") + randomBeaconHistoryHeartbeat.heartbeat(randomSourceHistory: randomSourceHistory()) + } + }`, sc.RandomBeaconHistory.Address.HexWithPrefix())), + ). + AddAuthorizer(sc.FlowServiceAccount.Address) + + s, out, err := vm.Run(ctx, fvm.Transaction(txBody, 0), snapshot) + require.NoError(t, err) + require.NoError(t, out.Err) + + snapshot = snapshot.Append(s) + + height = 1337 // invalid + // we make sure the transaction fails, due to requested height being invalid + code := []byte(fmt.Sprintf( + ` + import EVM from %s + + access(all) + fun main(tx: [UInt8], coinbaseBytes: [UInt8; 20]) { + let coinbase = EVM.EVMAddress(bytes: coinbaseBytes) + let res = EVM.run(tx: tx, coinbase: coinbase) + } + `, + sc.EVMContract.Address.HexWithPrefix(), + )) + + // we fake progressing to new block height since random beacon does the check the + // current height (2) is bigger than the height requested (1) + block1.Header.Height = 2 + ctx.BlockHeader = block1.Header + + innerTxBytes := testAccount.PrepareSignAndEncodeTx(t, + testContract.DeployedAt.ToCommon(), + testContract.MakeCallData(t, "verifyArchCallToRandomSource", height), + big.NewInt(0), + uint64(10_000_000), + big.NewInt(0), + ) + script := fvm.Script(code).WithArguments( + json.MustEncode( + cadence.NewArray( + ConvertToCadence(innerTxBytes), + ).WithType(stdlib.EVMTransactionBytesCadenceType), + ), + json.MustEncode( + cadence.NewArray( + ConvertToCadence(testAccount.Address().Bytes()), + ).WithType(stdlib.EVMAddressBytesCadenceType), + ), + ) + _, output, err := vm.Run( + ctx, + script, + snapshot) + require.NoError(t, err) + // make sure the error is correct + require.ErrorContains(t, output.Err, "Source of randomness not yet recorded") + }) + }) + t.Run("testing calling Cadence arch - COA ownership proof (happy case)", func(t *testing.T) { chain := flow.Emulator.Chain() sc := systemcontracts.SystemContractsForChain(chain.ChainID()) From 46c6e97e8da4dc3b52fb0260a6c39fd2f7d02e45 Mon Sep 17 00:00:00 2001 From: Gregor G Date: Fri, 19 Apr 2024 16:32:05 +0200 Subject: [PATCH 18/20] add arch test for random --- fvm/evm/precompiles/arch_test.go | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/fvm/evm/precompiles/arch_test.go b/fvm/evm/precompiles/arch_test.go index e890f294654..c0401e1c46e 100644 --- a/fvm/evm/precompiles/arch_test.go +++ b/fvm/evm/precompiles/arch_test.go @@ -38,6 +38,34 @@ func TestArchContract(t *testing.T) { require.Error(t, err) }) + t.Run("test get random source", func(t *testing.T) { + address := testutils.RandomAddress(t) + rand := uint64(1337) + pc := precompiles.ArchContract( + address, + nil, + nil, + func(u uint64) (uint64, error) { + return rand, nil + }, + ) + + require.Equal(t, address, pc.Address()) + + height := make([]byte, 32) + require.NoError(t, precompiles.EncodeUint64(13, height, 0)) + + input := append(precompiles.RandomSourceFuncSig.Bytes(), height...) + require.Equal(t, precompiles.RandomSourceGas, pc.RequiredGas(input)) + + ret, err := pc.Run(input) + require.NoError(t, err) + + resultRand, err := precompiles.ReadUint64(ret, 0) + require.NoError(t, err) + require.Equal(t, rand, resultRand) + }) + t.Run("test proof verification", func(t *testing.T) { proof := testutils.COAOwnershipProofInContextFixture(t) pc := precompiles.ArchContract( From 83a514a3fbdb40f0b88c2b1d7cc824fd19190cab Mon Sep 17 00:00:00 2001 From: Gregor G Date: Fri, 19 Apr 2024 17:20:14 +0200 Subject: [PATCH 19/20] fix api change test --- fvm/evm/handler/handler_test.go | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/fvm/evm/handler/handler_test.go b/fvm/evm/handler/handler_test.go index ccbc1ae2d86..e7980ffb84e 100644 --- a/fvm/evm/handler/handler_test.go +++ b/fvm/evm/handler/handler_test.go @@ -64,7 +64,7 @@ func TestHandler_TransactionRunOrPanic(t *testing.T) { return result, nil }, } - handler := handler.NewContractHandler(flow.Emulator, rootAddr, flowTokenAddress, bs, aa, backend, em) + handler := handler.NewContractHandler(flow.Emulator, rootAddr, flowTokenAddress, rootAddr, bs, aa, backend, em) coinbase := types.NewAddress(gethCommon.Address{}) @@ -163,7 +163,7 @@ func TestHandler_TransactionRunOrPanic(t *testing.T) { }, nil }, } - handler := handler.NewContractHandler(flow.Testnet, rootAddr, flowTokenAddress, bs, aa, backend, em) + handler := handler.NewContractHandler(flow.Testnet, rootAddr, flowTokenAddress, rootAddr, bs, aa, backend, em) coinbase := types.NewAddress(gethCommon.Address{}) @@ -220,7 +220,7 @@ func TestHandler_TransactionRunOrPanic(t *testing.T) { return &types.Result{}, types.NewFatalError(fmt.Errorf("Fatal error")) }, } - handler := handler.NewContractHandler(flow.Testnet, rootAddr, flowTokenAddress, bs, aa, backend, em) + handler := handler.NewContractHandler(flow.Testnet, rootAddr, flowTokenAddress, rootAddr, bs, aa, backend, em) assertPanic(t, errors.IsFailure, func() { tx := eoa.PrepareSignAndEncodeTx( t, @@ -464,7 +464,7 @@ func TestHandler_COA(t *testing.T) { }, } - handler := handler.NewContractHandler(flow.Testnet, rootAddr, flowTokenAddress, bs, aa, backend, em) + handler := handler.NewContractHandler(flow.Testnet, rootAddr, flowTokenAddress, rootAddr, bs, aa, backend, em) account := handler.AccountByAddress(testutils.RandomAddress(t), false) account.Withdraw(types.NewBalanceFromUFix64(1)) @@ -481,7 +481,7 @@ func TestHandler_COA(t *testing.T) { }, } - handler := handler.NewContractHandler(flow.Testnet, rootAddr, flowTokenAddress, bs, aa, backend, em) + handler := handler.NewContractHandler(flow.Testnet, rootAddr, flowTokenAddress, rootAddr, bs, aa, backend, em) account := handler.AccountByAddress(testutils.RandomAddress(t), true) account.Withdraw(types.NewBalanceFromUFix64(1)) @@ -498,7 +498,7 @@ func TestHandler_COA(t *testing.T) { }, } - handler := handler.NewContractHandler(flow.Testnet, rootAddr, flowTokenAddress, bs, aa, backend, em) + handler := handler.NewContractHandler(flow.Testnet, rootAddr, flowTokenAddress, rootAddr, bs, aa, backend, em) account := handler.AccountByAddress(testutils.RandomAddress(t), true) account.Withdraw(types.NewBalanceFromUFix64(0)) @@ -515,7 +515,7 @@ func TestHandler_COA(t *testing.T) { }, } - handler := handler.NewContractHandler(flow.Testnet, rootAddr, flowTokenAddress, bs, aa, backend, em) + handler := handler.NewContractHandler(flow.Testnet, rootAddr, flowTokenAddress, rootAddr, bs, aa, backend, em) account := handler.AccountByAddress(testutils.RandomAddress(t), true) account.Withdraw(types.NewBalanceFromUFix64(0)) @@ -545,7 +545,7 @@ func TestHandler_COA(t *testing.T) { }, } - handler := handler.NewContractHandler(flow.Testnet, rootAddr, flowTokenAddress, bs, aa, backend, em) + handler := handler.NewContractHandler(flow.Testnet, rootAddr, flowTokenAddress, rootAddr, bs, aa, backend, em) account := handler.AccountByAddress(testutils.RandomAddress(t), true) account.Deposit(types.NewFlowTokenVault(types.NewBalanceFromUFix64(1))) @@ -562,7 +562,7 @@ func TestHandler_COA(t *testing.T) { }, } - handler := handler.NewContractHandler(flow.Testnet, rootAddr, flowTokenAddress, bs, aa, backend, em) + handler := handler.NewContractHandler(flow.Testnet, rootAddr, flowTokenAddress, rootAddr, bs, aa, backend, em) account := handler.AccountByAddress(testutils.RandomAddress(t), true) account.Deposit(types.NewFlowTokenVault(types.NewBalanceFromUFix64(1))) @@ -700,7 +700,7 @@ func TestHandler_TransactionRun(t *testing.T) { return result, nil }, } - handler := handler.NewContractHandler(flow.Testnet, rootAddr, flowTokenAddress, bs, aa, backend, em) + handler := handler.NewContractHandler(flow.Testnet, rootAddr, flowTokenAddress, rootAddr, bs, aa, backend, em) tx := eoa.PrepareSignAndEncodeTx( t, gethCommon.Address{}, @@ -746,7 +746,7 @@ func TestHandler_TransactionRun(t *testing.T) { return result, nil }, } - handler := handler.NewContractHandler(flow.Testnet, rootAddr, flowTokenAddress, bs, aa, backend, em) + handler := handler.NewContractHandler(flow.Testnet, rootAddr, flowTokenAddress, rootAddr, bs, aa, backend, em) tx := eoa.PrepareSignAndEncodeTx( t, @@ -781,7 +781,7 @@ func TestHandler_TransactionRun(t *testing.T) { return &types.Result{ValidationError: evmErr}, nil }, } - handler := handler.NewContractHandler(flow.Testnet, rootAddr, flowTokenAddress, bs, aa, backend, em) + handler := handler.NewContractHandler(flow.Testnet, rootAddr, flowTokenAddress, rootAddr, bs, aa, backend, em) coinbase := types.NewAddress(gethCommon.Address{}) @@ -845,6 +845,6 @@ func SetupHandler(t testing.TB, backend types.Backend, rootAddr flow.Address) *h aa := handler.NewAddressAllocator() emulator := emulator.NewEmulator(backend, rootAddr) - handler := handler.NewContractHandler(flow.Emulator, rootAddr, flowTokenAddress, bs, aa, backend, emulator) + handler := handler.NewContractHandler(flow.Emulator, rootAddr, flowTokenAddress, rootAddr, bs, aa, backend, emulator) return handler } From a0ed6b5b0b5196f7191adb93feaa1fc6face5f85 Mon Sep 17 00:00:00 2001 From: Gregor G Date: Fri, 19 Apr 2024 17:44:44 +0200 Subject: [PATCH 20/20] update store test source --- fvm/evm/testutils/contracts/test.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fvm/evm/testutils/contracts/test.sol b/fvm/evm/testutils/contracts/test.sol index 8d2c3a4bef8..5e202cfc5c7 100644 --- a/fvm/evm/testutils/contracts/test.sol +++ b/fvm/evm/testutils/contracts/test.sol @@ -50,7 +50,7 @@ contract Storage { function verifyArchCallToRandomSource(uint64 height) public view returns (uint64) { (bool ok, bytes memory data) = cadenceArch.staticcall(abi.encodeWithSignature("getRandomSource(uint64)", height)); - //require(ok, "unsuccessful call to arch "); + require(ok, "unsuccessful call to arch "); uint64 output = abi.decode(data, (uint64)); return output; }