Skip to content

Commit

Permalink
optimize gas compute
Browse files Browse the repository at this point in the history
  • Loading branch information
cherry-yl-sh committed Mar 14, 2024
1 parent ab09981 commit 00ebc7d
Show file tree
Hide file tree
Showing 14 changed files with 203 additions and 126 deletions.
4 changes: 2 additions & 2 deletions common/model/api_response.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ type TryPayUserOpResponse struct {

type ComputeGasResponse struct {
GasInfo *GasPrice `json:"gas_info"`
TokenCost string `json:"token_cost"`
TokenCost *big.Float `json:"token_cost"`
Network types.Network `json:"network"`
Token types.TokenType `json:"token"`
TokenCount string `json:"token_count"`
UsdCost string `json:"usd_cost"`
UsdCost float64 `json:"usd_cost"`
BlobEnable bool `json:"blob_enable"`
MaxFee big.Int `json:"max_fee"`
}
Expand Down
13 changes: 13 additions & 0 deletions common/types/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@ package types

type TokenType string

var StableCoinMap map[TokenType]bool

func init() {
StableCoinMap = map[TokenType]bool{
USDT: true,
USDC: true,
}
}
func IsStableToken(token TokenType) bool {
_, ok := StableCoinMap[token]
return ok
}

const (
USDT TokenType = "usdt"
USDC TokenType = "usdc"
Expand Down
22 changes: 11 additions & 11 deletions common/utils/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ var HexPattern = regexp.MustCompile(`^0x[a-fA-F\d]*$`)
func GenerateMockUserOperation() *map[string]any {
//TODO use config
var MockUserOpData = map[string]any{
"sender": "0x4A2FD3215420376DA4eD32853C19E4755deeC4D1",
"nonce": "1",
"initCode": "0xe19e9755942bb0bd0cccce25b1742596b8a8250b3bf2c3e700000000000000000000000078d4f01f56b982a3b03c4e127a5d3afa8ebee6860000000000000000000000008b388a082f370d8ac2e2b3997e9151168bd09ff50000000000000000000000000000000000000000000000000000000000000000",
"callData": "0xb61d27f6000000000000000000000000c206b552ab127608c3f666156c8e03a8471c72df000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000",
"callGasLimit": "39837",
"verificationGasLimit": "100000",
"maxFeePerGas": "44020",
"maxPriorityFeePerGas": "1743509478",
"paymasterAndData": "0x",
"preVerificationGas": "44020",
"signature": "0x760868cd7d9539c6e31c2169c4cab6817beb8247516a90e4301e929011451658623455035b83d38e987ef2e57558695040a25219c39eaa0e31a0ead16a5c925c1c",
"sender": "0x4A2FD3215420376DA4eD32853C19E4755deeC4D1",
"nonce": "1",
"init_code": "0xe19e9755942bb0bd0cccce25b1742596b8a8250b3bf2c3e700000000000000000000000078d4f01f56b982a3b03c4e127a5d3afa8ebee6860000000000000000000000008b388a082f370d8ac2e2b3997e9151168bd09ff50000000000000000000000000000000000000000000000000000000000000000",
"call_data": "0xb61d27f6000000000000000000000000c206b552ab127608c3f666156c8e03a8471c72df000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000",
"call_gas_limit": "39837",
"verification_gas_limit": "100000",
"max_fee_per_gas": "44020",
"max_priority_fee_per_gas": "1743509478",
"paymaster_and_data": "0x",
"pre_verification_gas": "44020",
"signature": "0x760868cd7d9539c6e31c2169c4cab6817beb8247516a90e4301e929011451658623455035b83d38e987ef2e57558695040a25219c39eaa0e31a0ead16a5c925c1c",
}

return &MockUserOpData
Expand Down
17 changes: 0 additions & 17 deletions paymaster_data_generator/erc20_paymaster_generator.go

This file was deleted.

29 changes: 0 additions & 29 deletions paymaster_data_generator/paymaster_generator.go

This file was deleted.

20 changes: 0 additions & 20 deletions paymaster_data_generator/vertifying_paymaster_generator.go

This file was deleted.

34 changes: 34 additions & 0 deletions paymaster_pay_type/erc20_paymaster_generator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package paymaster_pay_type

import (
"AAStarCommunity/EthPaymaster_BackService/common/model"
"AAStarCommunity/EthPaymaster_BackService/common/types"
"AAStarCommunity/EthPaymaster_BackService/service/chain_service"
"encoding/hex"
"golang.org/x/xerrors"
"math/big"
)

type Erc20PaymasterExecutor struct {
}

func (e *Erc20PaymasterExecutor) ValidateGas(userOp *model.UserOperation, gasResponse *model.ComputeGasResponse, strategy *model.Strategy) error {
tokenBalance, getTokenBalanceErr := chain_service.GetAddressTokenBalance(strategy.NetWork, userOp.Sender, strategy.Token)
if getTokenBalanceErr != nil {
return getTokenBalanceErr
}
tokenCost := gasResponse.TokenCost
bigFloatValue := new(big.Float).SetFloat64(tokenBalance)
if bigFloatValue.Cmp(tokenCost) < 0 {
return xerrors.Errorf("user Token Not Enough tokenBalance %s < tokenCost %s", tokenBalance, tokenCost)
}
return nil
}

func (e *Erc20PaymasterExecutor) GeneratePayMasterAndData(strategy *model.Strategy, userOp *model.UserOperation, gasResponse *model.ComputeGasResponse, extra map[string]any) ([]byte, error) {
//ERC20:[0-1]pay type,[1-21]paymaster address,[21-53]token Amount
//tokenCost := gasResponse.TokenCost.Float64()
res := "0x" + string(types.PayTypeERC20) + strategy.PayMasterAddress
//TODO implement me
return hex.DecodeString(res)
}
29 changes: 29 additions & 0 deletions paymaster_pay_type/paymaster_generator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package paymaster_pay_type

import (
"AAStarCommunity/EthPaymaster_BackService/common/model"
"AAStarCommunity/EthPaymaster_BackService/common/types"
)

var (
PaymasterDataGeneratorFactories map[types.PayType]PaymasterPayTypeExecutor
)

func init() {
PaymasterDataGeneratorFactories = make(map[types.PayType]PaymasterPayTypeExecutor)
PaymasterDataGeneratorFactories[types.PayTypeVerifying] = &VerifyingPaymasterExecutor{}
PaymasterDataGeneratorFactories[types.PayTypeERC20] = &Erc20PaymasterExecutor{}
}

type PaymasterPayTypeExecutor interface {
GeneratePayMasterAndData(strategy *model.Strategy, userOp *model.UserOperation, gasResponse *model.ComputeGasResponse, extra map[string]any) ([]byte, error)
ValidateGas(userOp *model.UserOperation, response *model.ComputeGasResponse, strategy *model.Strategy) error
}

func GetPaymasterDataExecutor(payType types.PayType) PaymasterPayTypeExecutor {
paymasterDataGenerator, ok := PaymasterDataGeneratorFactories[payType]
if !ok {
return nil
}
return paymasterDataGenerator
}
39 changes: 39 additions & 0 deletions paymaster_pay_type/vertifying_paymaster_generator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package paymaster_pay_type

import (
"AAStarCommunity/EthPaymaster_BackService/common/model"
"AAStarCommunity/EthPaymaster_BackService/common/types"
"AAStarCommunity/EthPaymaster_BackService/service/chain_service"
"github.com/ethereum/go-ethereum/common"
"golang.org/x/xerrors"
"math/big"
)

type VerifyingPaymasterExecutor struct {
}

func (v VerifyingPaymasterExecutor) ValidateGas(userOp *model.UserOperation, response *model.ComputeGasResponse, strategy *model.Strategy) error {
//Validate the account’s deposit in the entryPoint is high enough to cover the max possible cost (cover the already-done verification and max execution gas)
// Paymaster check paymaster balance

//check EntryPoint paymasterAddress balance
tokenBalance, getTokenBalanceErr := chain_service.GetAddressTokenBalance(strategy.NetWork, common.HexToAddress(strategy.PayMasterAddress), strategy.Token)
if getTokenBalanceErr != nil {
return getTokenBalanceErr
}
tokenBalanceBigFloat := new(big.Float).SetFloat64(tokenBalance)
if tokenBalanceBigFloat.Cmp(response.TokenCost) > 0 {
return xerrors.Errorf("paymaster Token Not Enough tokenBalance %s < tokenCost %s", tokenBalance, response.TokenCost)
}
return nil
}

func (v VerifyingPaymasterExecutor) GeneratePayMasterAndData(strategy *model.Strategy, userOp *model.UserOperation, gasResponse *model.ComputeGasResponse, extra map[string]any) ([]byte, error) {
//verifying:[0-1]pay type,[1-21]paymaster address,[21-85]valid timestamp,[85-] signature
signature, ok := extra["signature"]
if !ok {
return nil, xerrors.Errorf("signature not found")
}
res := "0x" + string(types.PayTypeVerifying) + strategy.PayMasterAddress + "" + signature.(string)
return []byte(res), nil
}
58 changes: 41 additions & 17 deletions service/chain_service/chain_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,29 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/holiman/uint256"
"golang.org/x/xerrors"
"math"
"math/big"
"strings"
)

var GweiFactor = new(big.Float).SetInt(big.NewInt(1e9))
var EthWeiFactor = new(big.Float).SetInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil))

const balanceOfAbi = `[{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]`

var TokenAddressMap map[types.Network]*map[types.TokenType]common.Address

func init() {
TokenAddressMap = map[types.Network]*map[types.TokenType]common.Address{
types.Ethereum: {
types.ETH: common.HexToAddress("0xdac17f958d2ee523a2206206994597c13d831ec7"),
},
types.Sepolia: {
types.USDT: common.HexToAddress("0xaa8e23fb1079ea71e0a56f48a2aa51851d8433d0"),
types.USDC: common.HexToAddress("0x1c7d4b196cb0c7b01d743fbc6116a902379c7238"),
},
}
}
func CheckContractAddressAccess(contract common.Address, chain types.Network) (bool, error) {
if chain == "" {
return false, xerrors.Errorf("chain can not be empty")
Expand Down Expand Up @@ -103,36 +119,44 @@ func EstimateGasLimitAndCost(chain types.Network, msg ethereum.CallMsg) (uint64,
}
return client.EstimateGas(context.Background(), msg)
}
func GetAddressTokenBalance(network types.Network, address common.Address, token types.TokenType) ([]interface{}, error) {
func GetAddressTokenBalance(network types.Network, address common.Address, token types.TokenType) (float64, error) {
client, exist := EthCompatibleNetWorkClientMap[network]
if !exist {
return nil, xerrors.Errorf("chain Client [%s] not exist", network)
return 0, xerrors.Errorf("chain Client [%s] not exist", network)
}
if token == types.ETH {
res, err := client.BalanceAt(context.Background(), address, nil)
if err != nil {
return 0, err
}
bananceV := float64(res.Int64()) * math.Pow(10, -18)
return bananceV, nil
}
client.BalanceAt(context.Background(), address, nil)
usdtContractAddress := common.HexToAddress("0xdac17f958d2ee523a2206206994597c13d831ec7")
//address := common.HexToAddress("0xDf7093eF81fa23415bb703A685c6331584D30177")
const bananceABI = `[{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]`
usdtABI, jsonErr := abi.JSON(strings.NewReader(bananceABI))

tokenContractAddress := (*TokenAddressMap[network])[token]
usdtABI, jsonErr := abi.JSON(strings.NewReader(balanceOfAbi))
if jsonErr != nil {
return nil, jsonErr
return 0, jsonErr
}
data, backErr := usdtABI.Pack("balanceOf", address)
if backErr != nil {
return nil, backErr

return 0, backErr
}
//usdtInstance, err := ethclient.NewContract(usdtContractAddress, usdtAbi, client)
result, callErr := client.CallContract(context.Background(), ethereum.CallMsg{
To: &usdtContractAddress,
To: &tokenContractAddress,
Data: data,
}, nil)
if callErr != nil {
return nil, callErr
return 0, callErr
}
var balanceResult, unpackErr = usdtABI.Unpack("balanceOf", result)

var balanceResult *big.Int
unpackErr := usdtABI.UnpackIntoInterface(&balanceResult, "balanceOf", result)
if unpackErr != nil {
return nil, unpackErr
return 0, unpackErr
}
//TODO get token balance
return balanceResult, nil
balanceResultFloat := float64(balanceResult.Int64()) * math.Pow(10, -6)

return balanceResultFloat, nil

}
6 changes: 6 additions & 0 deletions service/chain_service/chain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,9 @@ func TestGethClient(t *testing.T) {
assert.NotEqual(t, 0, num)
fmt.Println(num)
}
func TestGetAddressTokenBalance(t *testing.T) {

res, err := GetAddressTokenBalance(types.Sepolia, common.HexToAddress("0xDf7093eF81fa23415bb703A685c6331584D30177"), types.USDC)
assert.NoError(t, err)
fmt.Println(res)
}
4 changes: 4 additions & 0 deletions service/dashboard_service/dashboard_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@ func init() {
EntryPointAddress: "0x0576a174D229E3cFA37253523E645A78A0C91B57",
PayMasterAddress: "0x0000000000325602a77416A16136FDafd04b299f",
NetWork: types.Sepolia,
PayType: types.PayTypeVerifying,
EntryPointTag: types.EntrypointV06,
Token: types.USDT,
}
mockStrategyMap["2"] = &model.Strategy{
Id: "2",
EntryPointAddress: "0x0576a174D229E3cFA37253523E645A78A0C91B57",
PayMasterAddress: "0x0000000000325602a77416A16136FDafd04b299f",
PayType: types.PayTypeERC20,
EntryPointTag: types.EntrypointV06,
NetWork: types.Sepolia,
Token: types.ETH,
}
Expand Down
Loading

0 comments on commit 00ebc7d

Please sign in to comment.