Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(evm): Combine both account queries into "/eth.evm.v1.Query/EthAccount", accepting both nibi-prefixed Bech32 addresses and Ethereum-type hexadecimal addresses as input. #1986

Merged
merged 27 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
1f0d8d0
refactor: remove unused vars. improve error clarity for testnetwork/New
Unique-Divine Jul 30, 2024
3335463
refactor: use pebbledb as the test db
Unique-Divine Jul 30, 2024
e106002
changelog
Unique-Divine Jul 30, 2024
a1c5782
refactor(statedb): separate Account and AccountWei to have state obje…
Unique-Divine Aug 4, 2024
cd9642b
math functions for unibi and wei
Unique-Divine Aug 4, 2024
9cd1edf
chore: wei unit migration
Unique-Divine Aug 4, 2024
18995b6
test(statedb): complete the wei-based account migration. Remove all m…
Unique-Divine Aug 4, 2024
4419067
test(statedb_test.go): more thorough test cases
Unique-Divine Aug 5, 2024
e171a5e
Merge branch 'main' into ud/attonibi
Unique-Divine Aug 5, 2024
37c09ff
Squashed commit of the following: merge ud/attonibi
Unique-Divine Aug 5, 2024
7b8addd
address conversion fns and tests
Unique-Divine Aug 5, 2024
82a1d33
feat(evm): Combine both account queries into "/eth.evm.v1.Query/EthAc…
Unique-Divine Aug 5, 2024
3f83bcf
fix(evmante): check balance in wei, deduct unibi gas
Unique-Divine Aug 5, 2024
811d6b5
fix(e2e): JavaScript BigInt is a joke
Unique-Divine Aug 6, 2024
ec8216f
fix(e2e): avoid BigInt overflow with 10^18 values
Unique-Divine Aug 6, 2024
d14ccf3
pull /eth from ud/account-query
Unique-Divine Aug 6, 2024
a90ef2f
fix(evmante): CheckSenderBalance needs to use wei
Unique-Divine Aug 6, 2024
82bf5f0
revert: add back NibiruAccount query to mock client
Unique-Divine Aug 6, 2024
9f2fc57
Merge branch 'main' into ud/attonibi
Unique-Divine Aug 6, 2024
6ae937f
fix(e2e-evm): add logging and fix tests
Unique-Divine Aug 6, 2024
a6c17b5
chore: resolve last few merge conflicts
Unique-Divine Aug 6, 2024
598b0ce
Merge branch 'main' into ud/attonibi
Unique-Divine Aug 6, 2024
7126a88
refactor: include variable name change suggestion for BalanceNative
Unique-Divine Aug 6, 2024
2c1d2b3
refactor: include variable name change suggestion for BalanceNative
Unique-Divine Aug 6, 2024
dfab619
Merge branch 'ud/attonibi' of https://github.com/NibiruChain/nibiru i…
Unique-Divine Aug 6, 2024
fd2fadb
Merge branch 'main' into ud/attonibi
Unique-Divine Aug 6, 2024
13c6ae9
Merge branch 'ud/attonibi' into ud/account-query
Unique-Divine Aug 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [#1973](https://github.com/NibiruChain/nibiru/pull/1973) - chore(appconst): Add chain IDs ending in "3" to the "knownEthChainIDMap". This makes it possible to use devnet 3 and testnet 3.
- [#1976](https://github.com/NibiruChain/nibiru/pull/1976) - refactor(evm): unique chain ids for all networks
- [#1977](https://github.com/NibiruChain/nibiru/pull/1977) - fix(localnet): rolled back change of evm validator address with cosmos derivation path
- [#1981](https://github.com/NibiruChain/nibiru/pull/1981) - fix(evm): remove isCheckTx() short circuit on `AnteDecVerifyEthAcc`
- [#1979](https://github.com/NibiruChain/nibiru/pull/1979) -refactor(db): use pebbledb as the default db in integration tests
- [#1981](https://github.com/NibiruChain/nibiru/pull/1981) - fix(evm): remove isCheckTx() short circuit on `AnteDecVerifyEthAcc`
- [#1985](https://github.com/NibiruChain/nibiru/pull/1985) - feat(evm)!: Use atto denomination for the wei units in the EVM so that NIBI is "ether" to clients. Only micronibi (unibi) amounts can be transferred. All clients follow the constraint equation, 1 ether == 1 NIBI == 10^6 unibi == 10^18 wei.
- [#1986](https://github.com/NibiruChain/nibiru/pull/1986) - feat(evm): Combine both account queries into "/eth.evm.v1.Query/EthAccount", accepting both nibi-prefixed Bech32 addresses and Ethereum-type hexadecimal addresses as input.

#### Dapp modules: perp, spot, oracle, etc

Expand Down
4 changes: 3 additions & 1 deletion app/evmante/evmante_can_transfer.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,12 @@ func (ctd CanTransferDecorator) AnteHandle(
// NOTE: here the gas consumed is from the context with the infinite gas meter
if coreMsg.Value().Sign() > 0 &&
!evmInstance.Context.CanTransfer(stateDB, coreMsg.From(), coreMsg.Value()) {
balanceWei := stateDB.GetBalance(coreMsg.From())
return ctx, errors.Wrapf(
errortypes.ErrInsufficientFunds,
"failed to transfer %s from address %s using the EVM block context transfer function",
"failed to transfer %s wei (balance=%s) from address %s using the EVM block context transfer function",
coreMsg.Value(),
balanceWei,
coreMsg.From(),
)
}
Expand Down
12 changes: 9 additions & 3 deletions app/evmante/evmante_can_transfer_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package evmante_test

import (
"math/big"

sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/NibiruChain/nibiru/app/evmante"
"github.com/NibiruChain/nibiru/eth"
"github.com/NibiruChain/nibiru/x/common/testutil/testapp"
"github.com/NibiruChain/nibiru/x/evm/evmtest"
"github.com/NibiruChain/nibiru/x/evm/statedb"
)
Expand All @@ -22,7 +21,14 @@ func (s *TestSuite) TestCanTransferDecorator() {
{
name: "happy: signed tx, sufficient funds",
beforeTxSetup: func(deps *evmtest.TestDeps, sdb *statedb.StateDB) {
sdb.AddBalance(deps.Sender.EthAddr, big.NewInt(100))
s.NoError(
testapp.FundAccount(
deps.Chain.BankKeeper,
deps.Ctx,
deps.Sender.NibiruAddr,
sdk.NewCoins(sdk.NewInt64Coin(eth.EthBaseDenom, 100)),
),
)
},
txSetup: func(deps *evmtest.TestDeps) sdk.FeeTx {
txMsg := evmtest.HappyTransferTx(deps, 0)
Expand Down
4 changes: 2 additions & 2 deletions app/evmante/evmante_gas_consume_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func (s *TestSuite) TestAnteDecEthGasConsume() {
name: "happy: sender with funds",
beforeTxSetup: func(deps *evmtest.TestDeps, sdb *statedb.StateDB) {
gasLimit := happyGasLimit()
balance := new(big.Int).Add(gasLimit, big.NewInt(100))
balance := evm.NativeToWei(new(big.Int).Add(gasLimit, big.NewInt(100)))
sdb.AddBalance(deps.Sender.EthAddr, balance)
},
txSetup: evmtest.HappyCreateContractTx,
Expand All @@ -46,7 +46,7 @@ func (s *TestSuite) TestAnteDecEthGasConsume() {
name: "sad: out of gas",
beforeTxSetup: func(deps *evmtest.TestDeps, sdb *statedb.StateDB) {
gasLimit := happyGasLimit()
balance := new(big.Int).Add(gasLimit, big.NewInt(100))
balance := evm.NativeToWei(new(big.Int).Add(gasLimit, big.NewInt(100)))
sdb.AddBalance(deps.Sender.EthAddr, balance)
},
txSetup: evmtest.HappyCreateContractTx,
Expand Down
7 changes: 5 additions & 2 deletions app/evmante/evmante_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/NibiruChain/nibiru/app/ante"
"github.com/NibiruChain/nibiru/app/evmante"
"github.com/NibiruChain/nibiru/eth"
"github.com/NibiruChain/nibiru/x/evm"
"github.com/NibiruChain/nibiru/x/evm/evmtest"
"github.com/NibiruChain/nibiru/x/evm/statedb"
)
Expand All @@ -26,16 +27,18 @@ func (s *TestSuite) TestAnteHandlerEVM() {
{
name: "happy: signed tx, sufficient funds",
beforeTxSetup: func(deps *evmtest.TestDeps, sdb *statedb.StateDB) {
balanceMicronibi := new(big.Int).Add(evmtest.GasLimitCreateContract(), big.NewInt(100))
sdb.AddBalance(
deps.Sender.EthAddr,
new(big.Int).Add(evmtest.GasLimitCreateContract(), big.NewInt(100)),
evm.NativeToWei(balanceMicronibi),
)
},
ctxSetup: func(deps *evmtest.TestDeps) {
gasPrice := sdk.NewInt64Coin("unibi", 1)
maxGasMicronibi := new(big.Int).Add(evmtest.GasLimitCreateContract(), big.NewInt(100))
cp := &tmproto.ConsensusParams{
Block: &tmproto.BlockParams{
MaxGas: new(big.Int).Add(evmtest.GasLimitCreateContract(), big.NewInt(100)).Int64(),
MaxGas: evm.NativeToWei(maxGasMicronibi).Int64(),
},
}
deps.Ctx = deps.Ctx.
Expand Down
5 changes: 3 additions & 2 deletions app/evmante/evmante_verify_eth_acc.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package evmante

import (
"cosmossdk.io/errors"
sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
errortypes "github.com/cosmos/cosmos-sdk/types/errors"
gethcommon "github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -69,7 +68,9 @@ func (anteDec AnteDecVerifyEthAcc) AnteHandle(
"the sender is not EOA: address %s, codeHash <%s>", fromAddr, acct.CodeHash)
}

if err := keeper.CheckSenderBalance(sdkmath.NewIntFromBigInt(acct.Balance), txData); err != nil {
if err := keeper.CheckSenderBalance(
evm.NativeToWei(acct.BalanceEvmDenom), txData,
); err != nil {
return ctx, errors.Wrap(err, "failed to check sender balance")
}
}
Expand Down
2 changes: 1 addition & 1 deletion app/evmante/evmante_verify_eth_acc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func (s *TestSuite) TestAnteDecoratorVerifyEthAcc_CheckTx() {
{
name: "happy: sender with funds",
beforeTxSetup: func(deps *evmtest.TestDeps, sdb *statedb.StateDB) {
sdb.AddBalance(deps.Sender.EthAddr, happyGasLimit())
sdb.AddBalance(deps.Sender.EthAddr, evm.NativeToWei(happyGasLimit()))
},
txSetup: evmtest.HappyCreateContractTx,
wantErr: "",
Expand Down
31 changes: 20 additions & 11 deletions eth/eth_account.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,19 @@
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"

"github.com/ethereum/go-ethereum/common"
sdk "github.com/cosmos/cosmos-sdk/types"
gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)

func EthAddrToNibiruAddr(ethAddr gethcommon.Address) sdk.AccAddress {
return ethAddr.Bytes()
}

func NibiruAddrToEthAddr(nibiruAddr sdk.AccAddress) gethcommon.Address {
return gethcommon.BytesToAddress(nibiruAddr.Bytes())
}

var (
_ authtypes.AccountI = (*EthAccount)(nil)
_ EthAccountI = (*EthAccount)(nil)
Expand All @@ -32,11 +41,11 @@
type EthAccountI interface { //revive:disable-line:exported
authtypes.AccountI
// EthAddress returns the ethereum Address representation of the AccAddress
EthAddress() common.Address
EthAddress() gethcommon.Address
// CodeHash is the keccak256 hash of the contract code (if any)
GetCodeHash() common.Hash
GetCodeHash() gethcommon.Hash
// SetCodeHash sets the code hash to the account fields
SetCodeHash(code common.Hash) error
SetCodeHash(code gethcommon.Hash) error
// Type returns the type of Ethereum Account (EOA or Contract)
Type() EthAccType
}
Expand All @@ -46,23 +55,23 @@
}

// EthAddress returns the account address ethereum format.
func (acc EthAccount) EthAddress() common.Address {
return common.BytesToAddress(acc.GetAddress().Bytes())
func (acc EthAccount) EthAddress() gethcommon.Address {
return gethcommon.BytesToAddress(acc.GetAddress().Bytes())

Check warning on line 59 in eth/eth_account.go

View check run for this annotation

Codecov / codecov/patch

eth/eth_account.go#L58-L59

Added lines #L58 - L59 were not covered by tests
}

func (acc EthAccount) GetCodeHash() common.Hash {
return common.HexToHash(acc.CodeHash)
func (acc EthAccount) GetCodeHash() gethcommon.Hash {
return gethcommon.HexToHash(acc.CodeHash)

Check warning on line 63 in eth/eth_account.go

View check run for this annotation

Codecov / codecov/patch

eth/eth_account.go#L62-L63

Added lines #L62 - L63 were not covered by tests
}

func (acc *EthAccount) SetCodeHash(codeHash common.Hash) error {
func (acc *EthAccount) SetCodeHash(codeHash gethcommon.Hash) error {

Check warning on line 66 in eth/eth_account.go

View check run for this annotation

Codecov / codecov/patch

eth/eth_account.go#L66

Added line #L66 was not covered by tests
acc.CodeHash = codeHash.Hex()
return nil
}

// Type returns the type of Ethereum Account (EOA or Contract)
func (acc EthAccount) Type() EthAccType {
if bytes.Equal(
emptyCodeHash, common.HexToHash(acc.CodeHash).Bytes(),
emptyCodeHash, gethcommon.HexToHash(acc.CodeHash).Bytes(),

Check warning on line 74 in eth/eth_account.go

View check run for this annotation

Codecov / codecov/patch

eth/eth_account.go#L74

Added line #L74 was not covered by tests
) {
return EthAccType_EOA
}
Expand All @@ -79,6 +88,6 @@
func ProtoBaseAccount() authtypes.AccountI {
return &EthAccount{
BaseAccount: &authtypes.BaseAccount{},
CodeHash: common.BytesToHash(emptyCodeHash).String(),
CodeHash: gethcommon.BytesToHash(emptyCodeHash).String(),

Check warning on line 91 in eth/eth_account.go

View check run for this annotation

Codecov / codecov/patch

eth/eth_account.go#L91

Added line #L91 was not covered by tests
}
}
40 changes: 40 additions & 0 deletions eth/eth_account_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package eth_test

import (
"github.com/NibiruChain/nibiru/eth"
"github.com/NibiruChain/nibiru/x/evm/evmtest"
)

func (s *Suite) TestEthAddrToNibiruAddr() {
accInfo := evmtest.NewEthAccInfo()
s.Equal(
accInfo.EthAddr,
eth.NibiruAddrToEthAddr(accInfo.NibiruAddr),
)
s.Equal(
accInfo.NibiruAddr,
eth.EthAddrToNibiruAddr(accInfo.EthAddr),
)

s.T().Log("unit operation - hex -> nibi -> hex")
{
addr := evmtest.NewEthAccInfo().NibiruAddr
s.Equal(
addr,
eth.EthAddrToNibiruAddr(
eth.NibiruAddrToEthAddr(addr),
),
)
}

s.T().Log("unit operation - nibi -> hex -> nibi")
{
addr := evmtest.NewEthAccInfo().EthAddr
s.Equal(
addr,
eth.NibiruAddrToEthAddr(
eth.EthAddrToNibiruAddr(addr),
),
)
}
}
11 changes: 7 additions & 4 deletions eth/rpc/backend/account_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func (b *Backend) GetProof(
return nil, err
}

balance, ok := sdkmath.NewIntFromString(res.Balance)
balance, ok := sdkmath.NewIntFromString(res.BalanceWei)
if !ok {
return nil, errors.New("invalid balance")
}
Expand Down Expand Up @@ -152,7 +152,10 @@ func (b *Backend) GetStorageAt(address common.Address, key string, blockNrOrHash
}

// GetBalance returns the provided account's balance up to the provided block number.
func (b *Backend) GetBalance(address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Big, error) {
func (b *Backend) GetBalance(
address common.Address,
blockNrOrHash rpc.BlockNumberOrHash,
) (*hexutil.Big, error) {
blockNum, err := b.BlockNumberFromTendermint(blockNrOrHash)
if err != nil {
return nil, err
Expand All @@ -172,9 +175,9 @@ func (b *Backend) GetBalance(address common.Address, blockNrOrHash rpc.BlockNumb
return nil, err
}

val, ok := sdkmath.NewIntFromString(res.Balance)
val, ok := sdkmath.NewIntFromString(res.BalanceWei)
if !ok {
return nil, errors.New("invalid balance")
return nil, fmt.Errorf("invalid balance: %s", res.BalanceWei)
}

// balance can only be negative in case of pruned node
Expand Down
12 changes: 6 additions & 6 deletions eth/rpc/backend/evm_query_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,9 +289,9 @@ func RegisterAccount(
) {
queryClient.On("EthAccount", rpc.NewContextWithHeight(height), &evm.QueryEthAccountRequest{Address: addr.String()}).
Return(&evm.QueryEthAccountResponse{
Balance: "0",
CodeHash: "",
Nonce: 0,
BalanceWei: "0",
CodeHash: "",
Nonce: 0,
},
nil,
)
Expand All @@ -302,21 +302,21 @@ func RegisterBalance(
queryClient *mocks.EVMQueryClient, addr common.Address, height int64,
) {
queryClient.On("Balance", rpc.NewContextWithHeight(height), &evm.QueryBalanceRequest{Address: addr.String()}).
Return(&evm.QueryBalanceResponse{Balance: "1"}, nil)
Return(&evm.QueryBalanceResponse{BalanceWei: "1"}, nil)
}

func RegisterBalanceInvalid(
queryClient *mocks.EVMQueryClient, addr common.Address, height int64,
) {
queryClient.On("Balance", rpc.NewContextWithHeight(height), &evm.QueryBalanceRequest{Address: addr.String()}).
Return(&evm.QueryBalanceResponse{Balance: "invalid"}, nil)
Return(&evm.QueryBalanceResponse{BalanceWei: "invalid"}, nil)
}

func RegisterBalanceNegative(
queryClient *mocks.EVMQueryClient, addr common.Address, height int64,
) {
queryClient.On("Balance", rpc.NewContextWithHeight(height), &evm.QueryBalanceRequest{Address: addr.String()}).
Return(&evm.QueryBalanceResponse{Balance: "-1"}, nil)
Return(&evm.QueryBalanceResponse{BalanceWei: "-1"}, nil)
}

func RegisterBalanceError(
Expand Down
30 changes: 0 additions & 30 deletions eth/rpc/backend/mocks/evm_query_client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading