diff --git a/builder/builder_test.go b/builder/builder_test.go index 77b7eac9..fc45aba4 100644 --- a/builder/builder_test.go +++ b/builder/builder_test.go @@ -311,14 +311,16 @@ func TestBuildRollupTxs(t *testing.T) { require.Len(t, ethTxs, 2, "Expected two Ethereum transactions: L1 attribute and deposit tx, got %d", len(ethTxs)) depositTxETH := ethTxs[1] - require.NotNil(t, depositTxETH.Value()) + require.NotNil(t, depositTxETH.Mint()) require.NotNil(t, depositTxETH.To(), "Deposit transaction must have a 'to' address") - cosmAddr := utils.EvmToCosmosAddress(*depositTxETH.To()) + from, err := gethtypes.NewCancunSigner(depositTxETH.ChainId()).Sender(depositTxETH) + require.NoError(t, err) + cosmAddr := utils.EvmToCosmosAddress(from) withdrawalTx := testapp.ToTx(t, &types.MsgInitiateWithdrawal{ Sender: cosmAddr.String(), Target: common.HexToAddress("0x12345abcde").String(), - Value: math.NewIntFromBigInt(depositTxETH.Value()), + Value: math.NewIntFromBigInt(depositTxETH.Mint()), GasLimit: big.NewInt(100_000).Bytes(), Data: []byte{}, }) @@ -346,7 +348,7 @@ func TestBuildRollupTxs(t *testing.T) { builtBlock, preBuildInfo, postBuildInfo := buildBlock(t, b, env.app, payload) // Test deposit was received - checkDepositTxResult(t, env.txStore, depositTxs, fmt.Sprintf("%sETH", depositTxETH.Value().String()), cosmAddr.String()) + checkDepositTxResult(t, env.txStore, depositTxs, fmt.Sprintf("%sETH", depositTxETH.Mint().String()), cosmAddr.String()) withdrawalTxResult, err := env.txStore.Get(bfttypes.Tx(withdrawalTx).Hash()) require.NoError(t, err) diff --git a/e2e/stack_test.go b/e2e/stack_test.go index 52d59789..0522882e 100644 --- a/e2e/stack_test.go +++ b/e2e/stack_test.go @@ -258,12 +258,11 @@ func rollupFlow(t *testing.T, stack *e2e.StackConfig) { require.NoError(t, err) // send user Deposit Tx - // TODO: the only reason the L1 balance assertions are passing is because depositTx.Value == depositTx.Mint. Once we pivot to using Mint instead of Value in x/rollup we should add separate deposit tx cases with and without a Value field set depositAmount := big.NewInt(oneEth) depositTx, err := stack.L1Portal.DepositTransaction( createL1TransactOpts(t, stack, userPrivKey, l1signer, l1GasLimit, depositAmount), userAddress, - depositAmount, + big.NewInt(0), l2GasLimit, false, // _isCreation []byte{}, // no data diff --git a/eth/api_backend.go b/eth/api_backend.go index 8e873f84..0b458282 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -11,7 +11,6 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" "github.com/polymerdao/monomer" - "github.com/polymerdao/monomer/eth/internal/ethapi" ) type ethAPIBackend struct { @@ -27,7 +26,7 @@ func newEthAPIBackend(db state.Database, blockStore DB) *ethAPIBackend { } func (*ethAPIBackend) ChainConfig() *params.ChainConfig { - return ethapi.NewChainConfig(nil) + return monomer.NewChainConfig(nil) } func (*ethAPIBackend) GetReceipts(_ context.Context, _ common.Hash) (types.Receipts, error) { diff --git a/eth/internal/ethapi/helpers.go b/eth/internal/ethapi/helpers.go index ad6b58f1..4a5990c6 100644 --- a/eth/internal/ethapi/helpers.go +++ b/eth/internal/ethapi/helpers.go @@ -9,7 +9,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" - "github.com/polymerdao/monomer/utils" + "github.com/polymerdao/monomer" ) type noopBackend struct{} @@ -34,27 +34,6 @@ func (noopBackend) StateAndHeaderByNumberOrHash(_ context.Context, _ rpc.BlockNu return nil, nil, nil } -func NewChainConfig(chainID *big.Int) *params.ChainConfig { - return ¶ms.ChainConfig{ - ChainID: chainID, - - ByzantiumBlock: new(big.Int), - ConstantinopleBlock: new(big.Int), - PetersburgBlock: new(big.Int), - IstanbulBlock: new(big.Int), - MuirGlacierBlock: new(big.Int), - BerlinBlock: new(big.Int), - LondonBlock: new(big.Int), - ArrowGlacierBlock: new(big.Int), - GrayGlacierBlock: new(big.Int), - MergeNetsplitBlock: new(big.Int), - - BedrockBlock: new(big.Int), - RegolithTime: utils.Ptr(uint64(0)), - CanyonTime: utils.Ptr(uint64(0)), - } -} - func SimpleRPCMarshalBlock(block *types.Block, fullTx bool, chainID *big.Int) (map[string]interface{}, error) { - return RPCMarshalBlock(context.Background(), block, true, fullTx, NewChainConfig(chainID), noopBackend{}) + return RPCMarshalBlock(context.Background(), block, true, fullTx, monomer.NewChainConfig(chainID), noopBackend{}) } diff --git a/monomer.go b/monomer.go index 559295bd..99106db0 100644 --- a/monomer.go +++ b/monomer.go @@ -18,7 +18,9 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/trie" + "github.com/polymerdao/monomer/utils" ) type Application interface { @@ -214,3 +216,24 @@ func ValidForkchoiceUpdateResult(headBlockHash *common.Hash, id *engine.PayloadI PayloadID: id, } } + +func NewChainConfig(chainID *big.Int) *params.ChainConfig { + return ¶ms.ChainConfig{ + ChainID: chainID, + + ByzantiumBlock: new(big.Int), + ConstantinopleBlock: new(big.Int), + PetersburgBlock: new(big.Int), + IstanbulBlock: new(big.Int), + MuirGlacierBlock: new(big.Int), + BerlinBlock: new(big.Int), + LondonBlock: new(big.Int), + ArrowGlacierBlock: new(big.Int), + GrayGlacierBlock: new(big.Int), + MergeNetsplitBlock: new(big.Int), + + BedrockBlock: new(big.Int), + RegolithTime: utils.Ptr(uint64(0)), + CanyonTime: utils.Ptr(uint64(0)), + } +} diff --git a/testutils/utils.go b/testutils/utils.go index 35d642d7..fbc8736e 100644 --- a/testutils/utils.go +++ b/testutils/utils.go @@ -76,7 +76,9 @@ func GenerateEthTxs(t *testing.T) (*gethtypes.Transaction, *gethtypes.Transactio l1InfoTx := gethtypes.NewTx(l1InfoRawTx) rng := rand.New(rand.NewSource(1234)) - depositTx := gethtypes.NewTx(testutils.GenerateDeposit(testutils.RandomHash(rng), rng)) + depositRawTx := testutils.GenerateDeposit(testutils.RandomHash(rng), rng) + depositRawTx.Mint = big.NewInt(100) + depositTx := gethtypes.NewTx(depositRawTx) cosmosEthTx := monomer.AdaptNonDepositCosmosTxToEthTx([]byte{1}) return l1InfoTx, depositTx, cosmosEthTx diff --git a/x/rollup/keeper/deposits.go b/x/rollup/keeper/deposits.go index a6471a3a..6732f264 100644 --- a/x/rollup/keeper/deposits.go +++ b/x/rollup/keeper/deposits.go @@ -3,12 +3,14 @@ package keeper import ( "encoding/json" "fmt" + "math/big" sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum/go-ethereum/common/hexutil" ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/polymerdao/monomer" "github.com/polymerdao/monomer/utils" "github.com/polymerdao/monomer/x/rollup/types" "github.com/samber/lo" @@ -50,7 +52,11 @@ func (k *Keeper) processL1AttributesTx(ctx sdk.Context, txBytes []byte) (*derive // processL1UserDepositTxs processes the L1 user deposit txs, mints ETH to the user's cosmos address, // and returns associated events. -func (k *Keeper) processL1UserDepositTxs(ctx sdk.Context, txs [][]byte) (sdk.Events, error) { //nolint:gocritic // hugeParam +func (k *Keeper) processL1UserDepositTxs( + ctx sdk.Context, //nolint:gocritic // hugeParam + txs [][]byte, + l1blockInfo *derive.L1BlockInfo, +) (sdk.Events, error) { mintEvents := sdk.Events{} // skip the first tx - it is the L1 attributes tx @@ -70,18 +76,29 @@ func (k *Keeper) processL1UserDepositTxs(ctx sdk.Context, txs [][]byte) (sdk.Eve return nil, types.WrapError(types.ErrInvalidL1Txs, "L1 tx must be a user deposit tx, type %d", tx.Type()) } ctx.Logger().Debug("User deposit tx", "index", i, "tx", string(lo.Must(tx.MarshalJSON()))) - to := tx.To() // if the receipient is nil, it means the tx is creating a contract which we don't support, so return an error. // see https://github.com/ethereum-optimism/op-geth/blob/v1.101301.0-rc.2/core/state_processor.go#L154 - if to == nil { + if tx.To() == nil { ctx.Logger().Error("Contract creation txs are not supported", "index", i) return nil, types.WrapError(types.ErrInvalidL1Txs, "Contract creation txs are not supported, index:%d", i) } - cosmAddr := utils.EvmToCosmosAddress(*to) - mintAmount := sdkmath.NewIntFromBigInt(tx.Value()) + + // Get the sender's address from the transaction + from, err := ethtypes.MakeSigner( + monomer.NewChainConfig(tx.ChainId()), + new(big.Int).SetUint64(l1blockInfo.Number), + l1blockInfo.Time, + ).Sender(&tx) + if err != nil { + ctx.Logger().Error("Failed to get sender address", "evmAddress", from, "err", err) + return nil, types.WrapError(types.ErrInvalidL1Txs, "failed to get sender address: %v", err) + } + cosmAddr := utils.EvmToCosmosAddress(from) + mintAmount := sdkmath.NewIntFromBigInt(tx.Mint()) + mintEvent, err := k.mintETH(ctx, cosmAddr, mintAmount) if err != nil { - ctx.Logger().Error("Failed to mint ETH", "evmAddress", to, "cosmosAddress", cosmAddr, "err", err) + ctx.Logger().Error("Failed to mint ETH", "evmAddress", from, "cosmosAddress", cosmAddr, "err", err) return nil, types.WrapError(types.ErrMintETH, "failed to mint ETH for cosmosAddress: %v; err: %v", cosmAddr, err) } mintEvents = append(mintEvents, *mintEvent) diff --git a/x/rollup/keeper/msg_server.go b/x/rollup/keeper/msg_server.go index bff5ec14..960cc15d 100644 --- a/x/rollup/keeper/msg_server.go +++ b/x/rollup/keeper/msg_server.go @@ -34,7 +34,7 @@ func (k *Keeper) ApplyL1Txs(goCtx context.Context, msg *types.MsgApplyL1Txs) (*t ctx.Logger().Info("Save L1 block info", "l1blockInfo", string(lo.Must(json.Marshal(l1blockInfo)))) // process L1 user deposit txs - mintEvents, err := k.processL1UserDepositTxs(ctx, msg.TxBytes) + mintEvents, err := k.processL1UserDepositTxs(ctx, msg.TxBytes, l1blockInfo) if err != nil { ctx.Logger().Error("Failed to process L1 user deposit txs", "err", err) return nil, types.WrapError(types.ErrProcessL1UserDepositTxs, "err: %v", err) diff --git a/x/rollup/tests/integration/rollup_test.go b/x/rollup/tests/integration/rollup_test.go index 2fe54348..58dfb7fc 100644 --- a/x/rollup/tests/integration/rollup_test.go +++ b/x/rollup/tests/integration/rollup_test.go @@ -22,7 +22,9 @@ import ( bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/ethereum/go-ethereum/common" + gethtypes "github.com/ethereum/go-ethereum/core/types" monomertestutils "github.com/polymerdao/monomer/testutils" + "github.com/polymerdao/monomer/utils" "github.com/polymerdao/monomer/x/rollup" rollupkeeper "github.com/polymerdao/monomer/x/rollup/keeper" rolluptypes "github.com/polymerdao/monomer/x/rollup/types" @@ -40,14 +42,16 @@ func TestRollup(t *testing.T) { l1AttributesTxBz := monomertestutils.TxToBytes(t, l1AttributesTx) depositTxBz := monomertestutils.TxToBytes(t, depositTx) - depositAmount := depositTx.Value() - var userAddr sdk.AccAddress = depositTx.To().Bytes() + depositAmount := depositTx.Mint() + from, err := gethtypes.NewCancunSigner(depositTx.ChainId()).Sender(depositTx) + require.NoError(t, err) + userAddr := utils.EvmToCosmosAddress(from) // query the user's ETH balance and assert it's zero require.Equal(t, math.ZeroInt(), queryUserETHBalance(t, queryClient, userAddr, integrationApp)) // send an invalid MsgApplyL1Txs and assert error - _, err := integrationApp.RunMsg(&rolluptypes.MsgApplyL1Txs{ + _, err = integrationApp.RunMsg(&rolluptypes.MsgApplyL1Txs{ TxBytes: [][]byte{l1AttributesTxBz, l1AttributesTxBz}, FromAddress: monomerSigner, })