Skip to content

Commit 391bf5d

Browse files
authored
Merge branch 'master' into gregor/callbacks/verifier
2 parents 5add34e + 381a07d commit 391bf5d

File tree

6 files changed

+724
-6
lines changed

6 files changed

+724
-6
lines changed

fvm/evm/evm_test.go

Lines changed: 195 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
package evm_test
22

33
import (
4+
"bytes"
45
"encoding/binary"
56
"fmt"
67
"math"
78
"math/big"
89
"testing"
910

11+
"github.com/ethereum/go-ethereum/common"
1012
gethTypes "github.com/ethereum/go-ethereum/core/types"
1113
gethParams "github.com/ethereum/go-ethereum/params"
1214
"github.com/ethereum/go-ethereum/rlp"
1315
"github.com/onflow/cadence/encoding/ccf"
1416
"github.com/stretchr/testify/assert"
17+
"github.com/stretchr/testify/require"
1518

1619
"github.com/onflow/cadence"
1720
"github.com/onflow/cadence/encoding/json"
18-
"github.com/stretchr/testify/require"
1921

2022
"github.com/onflow/flow-go/engine/execution/testutil"
2123
"github.com/onflow/flow-go/fvm"
@@ -3114,6 +3116,136 @@ func TestCadenceArch(t *testing.T) {
31143116
})
31153117
}
31163118

3119+
func TestEVMDeployFileSystemContract(t *testing.T) {
3120+
chain := flow.Emulator.Chain()
3121+
3122+
RunContractWithNewEnvironment(
3123+
t,
3124+
chain,
3125+
GetFileSystemContract(t),
3126+
func(
3127+
ctx fvm.Context,
3128+
vm fvm.VM,
3129+
snapshot snapshot.SnapshotTree,
3130+
testContract *TestContract,
3131+
testAccount *EOATestAccount,
3132+
) {
3133+
sc := systemcontracts.SystemContractsForChain(chain.ChainID())
3134+
3135+
code := []byte(fmt.Sprintf(
3136+
`
3137+
import EVM from %s
3138+
3139+
transaction(tx: [UInt8], coinbaseBytes: [UInt8; 20]){
3140+
prepare(account: &Account) {
3141+
let coinbase = EVM.EVMAddress(bytes: coinbaseBytes)
3142+
let res = EVM.run(tx: tx, coinbase: coinbase)
3143+
3144+
assert(res.status == EVM.Status.successful, message: "unexpected status")
3145+
assert(res.errorCode == 0, message: "unexpected error code")
3146+
assert(res.deployedContract == nil, message: "unexpected deployed contract")
3147+
}
3148+
}
3149+
`,
3150+
sc.EVMContract.Address.HexWithPrefix(),
3151+
))
3152+
3153+
coinbaseAddr := types.Address{1, 2, 3}
3154+
coinbaseBalance := getEVMAccountBalance(t, ctx, vm, snapshot, coinbaseAddr)
3155+
require.Zero(t, types.BalanceToBigInt(coinbaseBalance).Uint64())
3156+
3157+
var buffer bytes.Buffer
3158+
address := common.HexToAddress("0xea02F564664A477286B93712829180be4764fAe2")
3159+
chunkHash := "0x2521660d04da85198d1cc71c20a69b7e875ebbf1682f6a5c6a3fec69068ccc13"
3160+
index := int64(0)
3161+
chunk := "T1ARYBYsPOJPVYoU7wVp+PYuXmdS6bgkLf2egcxa+1hP64wAxfkLXtnllU6DmEuj+Id4oWl1ZV4ftQ+ofQ3DQhOoxNlPZGOYbhoMLuzE"
3162+
for i := 0; i <= 500; i++ {
3163+
buffer.WriteString(chunk)
3164+
}
3165+
innerTxBytes := testAccount.PrepareSignAndEncodeTx(t,
3166+
testContract.DeployedAt.ToCommon(),
3167+
testContract.MakeCallData(
3168+
t,
3169+
"publishChunk",
3170+
address,
3171+
chunkHash,
3172+
big.NewInt(index),
3173+
buffer.String(),
3174+
),
3175+
big.NewInt(0),
3176+
uint64(2_500_000),
3177+
big.NewInt(1),
3178+
)
3179+
3180+
innerTx := cadence.NewArray(
3181+
unittest.BytesToCdcUInt8(innerTxBytes),
3182+
).WithType(stdlib.EVMTransactionBytesCadenceType)
3183+
3184+
coinbase := cadence.NewArray(
3185+
unittest.BytesToCdcUInt8(coinbaseAddr.Bytes()),
3186+
).WithType(stdlib.EVMAddressBytesCadenceType)
3187+
3188+
txBody, err := flow.NewTransactionBodyBuilder().
3189+
SetScript(code).
3190+
AddAuthorizer(sc.FlowServiceAccount.Address).
3191+
AddArgument(json.MustEncode(innerTx)).
3192+
AddArgument(json.MustEncode(coinbase)).
3193+
Build()
3194+
require.NoError(t, err)
3195+
3196+
tx := fvm.Transaction(
3197+
txBody,
3198+
0,
3199+
)
3200+
3201+
state, output, err := vm.Run(ctx, tx, snapshot)
3202+
require.NoError(t, err)
3203+
require.NoError(t, output.Err)
3204+
require.NotEmpty(t, state.WriteSet)
3205+
snapshot = snapshot.Append(state)
3206+
3207+
// assert event fields are correct
3208+
require.Len(t, output.Events, 2)
3209+
txEvent := output.Events[0]
3210+
txEventPayload := TxEventToPayload(t, txEvent, sc.EVMContract.Address)
3211+
require.NoError(t, err)
3212+
3213+
// fee transfer event
3214+
feeTransferEvent := output.Events[1]
3215+
feeTranferEventPayload := TxEventToPayload(t, feeTransferEvent, sc.EVMContract.Address)
3216+
require.NoError(t, err)
3217+
require.Equal(t, uint16(types.ErrCodeNoError), feeTranferEventPayload.ErrorCode)
3218+
require.Equal(t, uint16(1), feeTranferEventPayload.Index)
3219+
require.Equal(t, uint64(21000), feeTranferEventPayload.GasConsumed)
3220+
3221+
// commit block
3222+
blockEventPayload, _ := callEVMHeartBeat(t,
3223+
ctx,
3224+
vm,
3225+
snapshot,
3226+
)
3227+
3228+
require.NotEmpty(t, blockEventPayload.Hash)
3229+
require.Equal(t, uint64(2132170), blockEventPayload.TotalGasUsed)
3230+
require.NotEmpty(t, blockEventPayload.Hash)
3231+
3232+
txHashes := types.TransactionHashes{txEventPayload.Hash, feeTranferEventPayload.Hash}
3233+
require.Equal(t,
3234+
txHashes.RootHash(),
3235+
blockEventPayload.TransactionHashRoot,
3236+
)
3237+
require.NotEmpty(t, blockEventPayload.ReceiptRoot)
3238+
3239+
require.Equal(t, innerTxBytes, txEventPayload.Payload)
3240+
require.Equal(t, uint16(types.ErrCodeNoError), txEventPayload.ErrorCode)
3241+
require.Equal(t, uint16(0), txEventPayload.Index)
3242+
require.Equal(t, blockEventPayload.Height, txEventPayload.BlockHeight)
3243+
require.Equal(t, blockEventPayload.TotalGasUsed-feeTranferEventPayload.GasConsumed, txEventPayload.GasConsumed)
3244+
require.Empty(t, txEventPayload.ContractAddress)
3245+
},
3246+
)
3247+
}
3248+
31173249
func createAndFundFlowAccount(
31183250
t *testing.T,
31193251
ctx fvm.Context,
@@ -3404,6 +3536,62 @@ func getEVMAccountNonce(
34043536
func RunWithNewEnvironment(
34053537
t *testing.T,
34063538
chain flow.Chain,
3539+
f func(fvm.Context, fvm.VM, snapshot.SnapshotTree, *TestContract, *EOATestAccount),
3540+
) {
3541+
rootAddr := evm.StorageAccountAddress(chain.ChainID())
3542+
RunWithTestBackend(t, func(backend *TestBackend) {
3543+
RunWithDeployedContract(t, GetStorageTestContract(t), backend, rootAddr, func(testContract *TestContract) {
3544+
RunWithEOATestAccount(t, backend, rootAddr, func(testAccount *EOATestAccount) {
3545+
blocks := new(envMock.Blocks)
3546+
block1 := unittest.BlockFixture()
3547+
blocks.On("ByHeightFrom",
3548+
block1.Height,
3549+
block1.ToHeader(),
3550+
).Return(block1.ToHeader(), nil)
3551+
3552+
opts := []fvm.Option{
3553+
fvm.WithChain(chain),
3554+
fvm.WithBlockHeader(block1.ToHeader()),
3555+
fvm.WithAuthorizationChecksEnabled(false),
3556+
fvm.WithSequenceNumberCheckAndIncrementEnabled(false),
3557+
fvm.WithEntropyProvider(testutil.EntropyProviderFixture(nil)),
3558+
fvm.WithRandomSourceHistoryCallAllowed(true),
3559+
fvm.WithBlocks(blocks),
3560+
fvm.WithCadenceLogging(true),
3561+
}
3562+
ctx := fvm.NewContext(opts...)
3563+
3564+
vm := fvm.NewVirtualMachine()
3565+
snapshotTree := snapshot.NewSnapshotTree(backend)
3566+
3567+
baseBootstrapOpts := []fvm.BootstrapProcedureOption{
3568+
fvm.WithInitialTokenSupply(unittest.GenesisTokenSupply),
3569+
}
3570+
3571+
executionSnapshot, _, err := vm.Run(
3572+
ctx,
3573+
fvm.Bootstrap(unittest.ServiceAccountPublicKey, baseBootstrapOpts...),
3574+
snapshotTree)
3575+
require.NoError(t, err)
3576+
3577+
snapshotTree = snapshotTree.Append(executionSnapshot)
3578+
3579+
f(
3580+
fvm.NewContextFromParent(ctx, fvm.WithEVMEnabled(true)),
3581+
vm,
3582+
snapshotTree,
3583+
testContract,
3584+
testAccount,
3585+
)
3586+
})
3587+
})
3588+
})
3589+
}
3590+
3591+
func RunContractWithNewEnvironment(
3592+
t *testing.T,
3593+
chain flow.Chain,
3594+
tc *TestContract,
34073595
f func(
34083596
fvm.Context,
34093597
fvm.VM,
@@ -3415,19 +3603,20 @@ func RunWithNewEnvironment(
34153603
rootAddr := evm.StorageAccountAddress(chain.ChainID())
34163604

34173605
RunWithTestBackend(t, func(backend *TestBackend) {
3418-
RunWithDeployedContract(t, GetStorageTestContract(t), backend, rootAddr, func(testContract *TestContract) {
3606+
RunWithDeployedContract(t, tc, backend, rootAddr, func(testContract *TestContract) {
34193607
RunWithEOATestAccount(t, backend, rootAddr, func(testAccount *EOATestAccount) {
34203608

34213609
blocks := new(envMock.Blocks)
34223610
block1 := unittest.BlockFixture()
3611+
header1 := block1.ToHeader()
34233612
blocks.On("ByHeightFrom",
3424-
block1.Height,
3425-
block1.ToHeader(),
3426-
).Return(block1.ToHeader(), nil)
3613+
header1.Height,
3614+
header1,
3615+
).Return(header1, nil)
34273616

34283617
opts := []fvm.Option{
34293618
fvm.WithChain(chain),
3430-
fvm.WithBlockHeader(block1.ToHeader()),
3619+
fvm.WithBlockHeader(header1),
34313620
fvm.WithAuthorizationChecksEnabled(false),
34323621
fvm.WithSequenceNumberCheckAndIncrementEnabled(false),
34333622
fvm.WithEntropyProvider(testutil.EntropyProviderFixture(nil)),

fvm/evm/testutils/contract.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,13 @@ func GetFactoryTestContract(t testing.TB) *TestContract {
6666
}
6767
}
6868

69+
func GetFileSystemContract(t testing.TB) *TestContract {
70+
return &TestContract{
71+
ABI: contracts.FileSystemContractABIJSON,
72+
ByteCode: contracts.FileSystemContractBytes,
73+
}
74+
}
75+
6976
func RunWithDeployedContract(t testing.TB, tc *TestContract, led atree.Ledger, flowEVMRootAddress flow.Address, f func(*TestContract)) {
7077
DeployContract(t, RandomAddress(t), tc, led, flowEVMRootAddress)
7178
f(tc)

fvm/evm/testutils/contracts/contracts.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,11 @@ var FactoryContractABIJSON string
3939

4040
//go:embed factory_deployable_abi.json
4141
var FactoryDeployableContractABIJSON string
42+
43+
//go:embed file_system_bytes.hex
44+
var fileSystemContractBytesInHex string
45+
46+
var FileSystemContractBytes, _ = hex.DecodeString(fileSystemContractBytesInHex)
47+
48+
//go:embed file_system_abi.json
49+
var FileSystemContractABIJSON string

0 commit comments

Comments
 (0)