github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/evm/keeper/invariants.go (about) 1 package keeper 2 3 import ( 4 "fmt" 5 6 ethermint "github.com/fibonacci-chain/fbc/app/types" 7 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 8 authexported "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/exported" 9 "github.com/fibonacci-chain/fbc/x/evm/types" 10 ) 11 12 const ( 13 balanceInvariant = "balance" 14 nonceInvariant = "nonce" 15 ) 16 17 // RegisterInvariants registers the evm module invariants 18 func RegisterInvariants(ir sdk.InvariantRegistry, k Keeper) { 19 ir.RegisterRoute(types.ModuleName, balanceInvariant, k.BalanceInvariant()) 20 ir.RegisterRoute(types.ModuleName, nonceInvariant, k.NonceInvariant()) 21 } 22 23 // BalanceInvariant checks that all auth module's EthAccounts in the application have the same balance 24 // as the EVM one. 25 func (k Keeper) BalanceInvariant() sdk.Invariant { 26 return func(ctx sdk.Context) (string, bool) { 27 var ( 28 msg string 29 count int 30 ) 31 32 csdb := types.CreateEmptyCommitStateDB(k.GenerateCSDBParams(), ctx) 33 k.accountKeeper.IterateAccounts(ctx, func(account authexported.Account) bool { 34 ethAccount, ok := account.(*ethermint.EthAccount) 35 if !ok { 36 // ignore non EthAccounts 37 return false 38 } 39 40 accountBalance := ethAccount.GetCoins().AmountOf(sdk.DefaultBondDenom) 41 evmBalance := csdb.GetBalance(ethAccount.EthAddress()) 42 43 if evmBalance.Cmp(accountBalance.BigInt()) != 0 { 44 count++ 45 msg += fmt.Sprintf( 46 "\tbalance mismatch for address %s: account balance %s, evm balance %s\n", 47 account.GetAddress(), accountBalance.String(), evmBalance.String(), 48 ) 49 } 50 51 return false 52 }) 53 54 broken := count != 0 55 56 return sdk.FormatInvariant( 57 types.ModuleName, balanceInvariant, 58 fmt.Sprintf("account balances mismatches found %d\n%s", count, msg), 59 ), broken 60 } 61 } 62 63 // NonceInvariant checks that all auth module's EthAccounts in the application have the same nonce 64 // sequence as the EVM. 65 func (k Keeper) NonceInvariant() sdk.Invariant { 66 return func(ctx sdk.Context) (string, bool) { 67 var ( 68 msg string 69 count int 70 ) 71 72 csdb := types.CreateEmptyCommitStateDB(k.GenerateCSDBParams(), ctx) 73 k.accountKeeper.IterateAccounts(ctx, func(account authexported.Account) bool { 74 ethAccount, ok := account.(*ethermint.EthAccount) 75 if !ok { 76 // ignore non EthAccounts 77 return false 78 } 79 80 evmNonce := csdb.GetNonce(ethAccount.EthAddress()) 81 82 if evmNonce != ethAccount.Sequence { 83 count++ 84 msg += fmt.Sprintf( 85 "\nonce mismatch for address %s: account nonce %d, evm nonce %d\n", 86 account.GetAddress(), ethAccount.Sequence, evmNonce, 87 ) 88 } 89 90 return false 91 }) 92 93 broken := count != 0 94 95 return sdk.FormatInvariant( 96 types.ModuleName, nonceInvariant, 97 fmt.Sprintf("account nonces mismatches found %d\n%s", count, msg), 98 ), broken 99 } 100 }