From 99f76847ba8091ce1b8b894710961ff6336a39bd Mon Sep 17 00:00:00 2001 From: beer-1 Date: Wed, 13 Nov 2024 19:25:28 +0900 Subject: [PATCH] introduce lock --- jsonrpc/backend/backend.go | 14 ++++++++++++++ jsonrpc/backend/eth.go | 9 +++++---- jsonrpc/backend/gas.go | 29 ++++++++++++++++++++--------- 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/jsonrpc/backend/backend.go b/jsonrpc/backend/backend.go index 5362ebe..bcf0b37 100644 --- a/jsonrpc/backend/backend.go +++ b/jsonrpc/backend/backend.go @@ -43,6 +43,7 @@ type JSONRPCBackend struct { // fee cache feeDenom string feeDecimals uint8 + feeMutex sync.RWMutex mut sync.Mutex // mutex for accMuts accMuts map[string]*AccMut @@ -126,6 +127,17 @@ func NewJSONRPCBackend( return b, nil } +func (b *JSONRPCBackend) feeInfo() (string, uint8, error) { + b.feeMutex.RLock() + defer b.feeMutex.RUnlock() + + if b.feeDenom == "" { + return "", 0, NewInternalError("jsonrpc is not ready") + } + + return b.feeDenom, b.feeDecimals, nil +} + func (b *JSONRPCBackend) feeFetcher() { fetcher := func() (err error) { defer func() { @@ -150,8 +162,10 @@ func (b *JSONRPCBackend) feeFetcher() { return err } + b.feeMutex.Lock() b.feeDenom = feeDenom b.feeDecimals = decimals + b.feeMutex.Unlock() return nil } diff --git a/jsonrpc/backend/eth.go b/jsonrpc/backend/eth.go index 41ff3d4..8f48e2f 100644 --- a/jsonrpc/backend/eth.go +++ b/jsonrpc/backend/eth.go @@ -26,16 +26,17 @@ func (b *JSONRPCBackend) GetBalance(address common.Address, blockNrOrHash rpc.Bl } // jsonrpc is not ready for querying - if b.feeDenom == "" { - return nil, errors.New("jsonrpc is not ready") + feeDenom, feeDecimals, err := b.feeInfo() + if err != nil { + return nil, err } - balance, err := b.app.EVMKeeper.ERC20Keeper().GetBalance(queryCtx, sdk.AccAddress(address[:]), b.feeDenom) + balance, err := b.app.EVMKeeper.ERC20Keeper().GetBalance(queryCtx, sdk.AccAddress(address[:]), feeDenom) if err != nil { return nil, err } - return (*hexutil.Big)(types.ToEthersUint(b.feeDecimals, balance.BigInt())), nil + return (*hexutil.Big)(types.ToEthersUint(feeDecimals, balance.BigInt())), nil } func (b *JSONRPCBackend) Call(args rpctypes.TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash, overrides *rpctypes.StateOverride, blockOverrides *rpctypes.BlockOverrides) (hexutil.Bytes, error) { diff --git a/jsonrpc/backend/gas.go b/jsonrpc/backend/gas.go index fe6e5e5..edf2022 100644 --- a/jsonrpc/backend/gas.go +++ b/jsonrpc/backend/gas.go @@ -40,8 +40,9 @@ func (b *JSONRPCBackend) EstimateGas(args rpctypes.TransactionArgs, blockNrOrHas } // jsonrpc is not ready for querying - if b.feeDenom == "" { - return hexutil.Uint64(0), NewInternalError("jsonrpc is not ready") + _, feeDecimals, err := b.feeInfo() + if err != nil { + return hexutil.Uint64(0), err } sdkMsgs := []sdk.Msg{} @@ -49,14 +50,14 @@ func (b *JSONRPCBackend) EstimateGas(args rpctypes.TransactionArgs, blockNrOrHas sdkMsgs = append(sdkMsgs, &types.MsgCreate{ Sender: sender, Code: hexutil.Encode(args.GetData()), - Value: math.NewIntFromBigInt(types.FromEthersUnit(b.feeDecimals, args.Value.ToInt())), + Value: math.NewIntFromBigInt(types.FromEthersUnit(feeDecimals, args.Value.ToInt())), }) } else { sdkMsgs = append(sdkMsgs, &types.MsgCall{ Sender: sender, ContractAddr: args.To.Hex(), Input: hexutil.Encode(args.GetData()), - Value: math.NewIntFromBigInt(types.FromEthersUnit(b.feeDecimals, args.Value.ToInt())), + Value: math.NewIntFromBigInt(types.FromEthersUnit(feeDecimals, args.Value.ToInt())), }) } @@ -102,16 +103,26 @@ func (b *JSONRPCBackend) GasPrice() (*hexutil.Big, error) { } // jsonrpc is not ready for querying - if b.feeDenom == "" { - return nil, NewInternalError("jsonrpc is not ready") + feeDenom, feeDecimals, err := b.feeInfo() + if err != nil { + return nil, err } + // Multiply by 1e9 to maintain precision during conversion + // This adds 9 decimal places to prevent truncation errors + const precisionMultiplier = 1e9 + // multiply by 1e9 to prevent decimal drops - gasPrice := params.MinGasPrices.AmountOf(b.feeDenom). - MulTruncate(math.LegacyNewDec(1e9)). + gasPrice := params.MinGasPrices.AmountOf(feeDenom). + MulTruncate(math.LegacyNewDec(precisionMultiplier)). TruncateInt().BigInt() - return (*hexutil.Big)(types.ToEthersUint(b.feeDecimals+9, gasPrice)), nil + // Verify the result is within safe bounds + if gasPrice.BitLen() > 256 { + return nil, NewInternalError("gas price overflow") + } + + return (*hexutil.Big)(types.ToEthersUint(feeDecimals+9, gasPrice)), nil } func (b *JSONRPCBackend) MaxPriorityFeePerGas() (*hexutil.Big, error) {