2022-11-14 19:06:55 +00:00
|
|
|
package itests
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"context"
|
|
|
|
"encoding/hex"
|
|
|
|
"os"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
cbg "github.com/whyrusleeping/cbor-gen"
|
|
|
|
|
|
|
|
"github.com/filecoin-project/go-address"
|
2022-11-17 01:42:38 +00:00
|
|
|
actorstypes "github.com/filecoin-project/go-state-types/actors"
|
|
|
|
builtintypes "github.com/filecoin-project/go-state-types/builtin"
|
2022-12-15 02:57:28 +00:00
|
|
|
"github.com/filecoin-project/go-state-types/manifest"
|
2022-11-14 19:06:55 +00:00
|
|
|
|
2022-11-17 01:42:38 +00:00
|
|
|
"github.com/filecoin-project/lotus/chain/actors"
|
|
|
|
"github.com/filecoin-project/lotus/chain/types"
|
2022-11-14 19:06:55 +00:00
|
|
|
"github.com/filecoin-project/lotus/itests/kit"
|
|
|
|
)
|
|
|
|
|
|
|
|
// TestFEVMBasic does a basic fevm contract installation and invocation
|
|
|
|
func TestFEVMBasic(t *testing.T) {
|
|
|
|
// TODO the contract installation and invocation can be lifted into utility methods
|
|
|
|
// He who writes the second test, shall do that.
|
|
|
|
kit.QuietMiningLogs()
|
|
|
|
|
|
|
|
blockTime := 100 * time.Millisecond
|
|
|
|
client, _, ens := kit.EnsembleMinimal(t, kit.MockProofs(), kit.ThroughRPC())
|
|
|
|
ens.InterconnectAll().BeginMining(blockTime)
|
|
|
|
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
// install contract
|
|
|
|
contractHex, err := os.ReadFile("contracts/SimpleCoin.bin")
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
contract, err := hex.DecodeString(string(contractHex))
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
fromAddr, err := client.WalletDefaultAddress(ctx)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2022-11-16 09:30:35 +00:00
|
|
|
result := client.EVM().DeployContract(ctx, fromAddr, contract)
|
2022-11-14 19:06:55 +00:00
|
|
|
|
|
|
|
idAddr, err := address.NewIDAddress(result.ActorID)
|
|
|
|
require.NoError(t, err)
|
|
|
|
t.Logf("actor ID address is %s", idAddr)
|
|
|
|
|
|
|
|
// invoke the contract with owner
|
|
|
|
{
|
|
|
|
entryPoint, err := hex.DecodeString("f8b2cb4f")
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
inputData, err := hex.DecodeString("000000000000000000000000ff00000000000000000000000000000000000064")
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2022-11-16 09:30:35 +00:00
|
|
|
wait := client.EVM().InvokeSolidity(ctx, fromAddr, idAddr, entryPoint, inputData)
|
2022-11-14 19:06:55 +00:00
|
|
|
|
|
|
|
require.True(t, wait.Receipt.ExitCode.IsSuccess(), "contract execution failed")
|
|
|
|
|
|
|
|
result, err := cbg.ReadByteArray(bytes.NewBuffer(wait.Receipt.Return), uint64(len(wait.Receipt.Return)))
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
expectedResult, err := hex.DecodeString("0000000000000000000000000000000000000000000000000000000000002710")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, result, expectedResult)
|
|
|
|
}
|
|
|
|
|
|
|
|
// invoke the contract with non owner
|
|
|
|
{
|
|
|
|
entryPoint, err := hex.DecodeString("f8b2cb4f")
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
inputData, err := hex.DecodeString("000000000000000000000000ff00000000000000000000000000000000000065")
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2022-11-16 09:30:35 +00:00
|
|
|
wait := client.EVM().InvokeSolidity(ctx, fromAddr, idAddr, entryPoint, inputData)
|
2022-11-14 19:06:55 +00:00
|
|
|
require.True(t, wait.Receipt.ExitCode.IsSuccess(), "contract execution failed")
|
|
|
|
|
|
|
|
result, err := cbg.ReadByteArray(bytes.NewBuffer(wait.Receipt.Return), uint64(len(wait.Receipt.Return)))
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
expectedResult, err := hex.DecodeString("0000000000000000000000000000000000000000000000000000000000000000")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, result, expectedResult)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2022-11-17 01:42:38 +00:00
|
|
|
|
|
|
|
// TestFEVMETH0 tests that the ETH0 actor is in genesis
|
|
|
|
func TestFEVMETH0(t *testing.T) {
|
|
|
|
kit.QuietMiningLogs()
|
|
|
|
|
|
|
|
blockTime := 100 * time.Millisecond
|
|
|
|
client, _, ens := kit.EnsembleMinimal(t, kit.MockProofs(), kit.ThroughRPC())
|
|
|
|
ens.InterconnectAll().BeginMining(blockTime)
|
|
|
|
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
eth0id, err := address.NewIDAddress(1001)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
act, err := client.StateGetActor(ctx, eth0id, types.EmptyTSK)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
nv, err := client.StateNetworkVersion(ctx, types.EmptyTSK)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
av, err := actorstypes.VersionForNetwork(nv)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2022-12-15 02:00:39 +00:00
|
|
|
evmCodeCid, ok := actors.GetActorCodeID(av, manifest.EvmKey)
|
2022-11-17 01:42:38 +00:00
|
|
|
require.True(t, ok, "failed to get EVM code id")
|
|
|
|
require.Equal(t, act.Code, evmCodeCid)
|
|
|
|
|
|
|
|
eth0Addr, err := address.NewDelegatedAddress(builtintypes.EthereumAddressManagerActorID, make([]byte, 20))
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, *act.Address, eth0Addr)
|
|
|
|
}
|