Skip to content

Commit

Permalink
Merge pull request #6 from rarimo/fix/multiple-gas-limit
Browse files Browse the repository at this point in the history
add: gas limit for transit state; multiplier for all gas limits
  • Loading branch information
artemskriabin authored May 9, 2024
2 parents c5954a1 + ed5da51 commit dd14776
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 127 deletions.
75 changes: 2 additions & 73 deletions internal/service/api/handlers/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,10 @@ package handlers
import (
"encoding/json"
"net/http"
"strings"

"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/rarimo/proof-verification-relayer/internal/contracts"
"github.com/rarimo/proof-verification-relayer/internal/service/api/requests"
"gitlab.com/distributed_lab/ape"
Expand Down Expand Up @@ -77,83 +73,16 @@ func Register(w http.ResponseWriter, r *http.Request) {
return
}

gasPrice, err := EthClient(r).SuggestGasPrice(r.Context())
if err != nil {
Log(r).WithError(err).Error("failed to suggest gas price")
ape.RenderErr(w, problems.InternalError())
return
}
gasPrice = multiplyGasPrice(gasPrice, NetworkConfig(r).GasMultiplier)

NetworkConfig(r).LockNonce()
defer NetworkConfig(r).UnlockNonce()

gas, err := EthClient(r).EstimateGas(r.Context(), ethereum.CallMsg{
From: crypto.PubkeyToAddress(NetworkConfig(r).PrivateKey.PublicKey),
To: &registration,
GasPrice: gasPrice,
Data: dataBytes,
})
if err != nil {
Log(r).WithError(err).Error("failed to estimate gas")
ape.RenderErr(w, problems.InternalError())
return
}

tx, err := types.SignNewTx(
NetworkConfig(r).PrivateKey,
types.NewCancunSigner(NetworkConfig(r).ChainID),
&types.LegacyTx{
Nonce: NetworkConfig(r).Nonce(),
Gas: gas,
GasPrice: gasPrice,
To: &registration,
Data: dataBytes,
},
)
tx, err := processLegacyTx(r, registration, dataBytes)
if err != nil {
Log(r).WithError(err).Error("failed to sign new tx")
Log(r).WithError(err).Error("failed to process legacy transaction")
ape.RenderErr(w, problems.InternalError())
return
}

if err := EthClient(r).SendTransaction(r.Context(), tx); err != nil {
if strings.Contains(err.Error(), "nonce") {
if err := NetworkConfig(r).ResetNonce(EthClient(r)); err != nil {
Log(r).WithError(err).Error("failed to reset nonce")
ape.RenderErr(w, problems.InternalError())
return
}

tx, err = types.SignNewTx(
NetworkConfig(r).PrivateKey,
types.NewCancunSigner(NetworkConfig(r).ChainID),
&types.LegacyTx{
Nonce: NetworkConfig(r).Nonce(),
Gas: gas,
GasPrice: gasPrice,
To: &registration,
Data: dataBytes,
},
)
if err != nil {
Log(r).WithError(err).Error("failed to sign new tx")
ape.RenderErr(w, problems.InternalError())
return
}

if err := EthClient(r).SendTransaction(r.Context(), tx); err != nil {
Log(r).WithError(err).Error("failed to send transaction")
ape.RenderErr(w, problems.InternalError())
return
}
} else {
Log(r).WithError(err).Error("failed to send transaction")
ape.RenderErr(w, problems.InternalError())
return
}
}

NetworkConfig(r).IncrementNonce()

ape.Render(w, newTxModel(tx))
Expand Down
11 changes: 6 additions & 5 deletions internal/service/api/handlers/transit_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"net/http"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
validation "github.com/go-ozzo/ozzo-validation/v4"
Expand Down Expand Up @@ -43,7 +44,7 @@ func TransitState(w http.ResponseWriter, r *http.Request) {

NetworkConfig(r).LockNonce()
defer NetworkConfig(r).UnlockNonce()
txOpts, err := getTxOpts(r)
txOpts, err := getTxOpts(r, NetworkConfig(r).LightweightState, dataBytes)
if err != nil {
Log(r).WithError(err).Error("failed to get transaction options")
ape.RenderErr(w, problems.InternalError())
Expand Down Expand Up @@ -97,12 +98,11 @@ func getSignedTransitStateTxDataParams(r *http.Request, data []byte) ([32]byte,
return newStateRoot, gistRootData, lightweightStateProof, nil
}

func getTxOpts(r *http.Request) (*bind.TransactOpts, error) {
gasPrice, err := EthClient(r).SuggestGasPrice(r.Context())
func getTxOpts(r *http.Request, receiver common.Address, txData []byte) (*bind.TransactOpts, error) {
gasPrice, gasLimit, err := getGasCosts(r, receiver, txData)
if err != nil {
return nil, errors.Wrap(err, "failed to suggest gas price")
return nil, errors.Wrap(err, "failed to get gas costs")
}
gasPrice = multiplyGasPrice(gasPrice, NetworkConfig(r).GasMultiplier)

txOpts, err := bind.NewKeyedTransactorWithChainID(NetworkConfig(r).PrivateKey, NetworkConfig(r).ChainID)
if err != nil {
Expand All @@ -111,6 +111,7 @@ func getTxOpts(r *http.Request) (*bind.TransactOpts, error) {

txOpts.Nonce = new(big.Int).SetUint64(NetworkConfig(r).Nonce())
txOpts.GasPrice = gasPrice
txOpts.GasLimit = gasLimit

return txOpts, nil
}
Expand Down
117 changes: 68 additions & 49 deletions internal/service/api/handlers/vote.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,93 +48,112 @@ func Vote(w http.ResponseWriter, r *http.Request) {
return
}

gasPrice, err := EthClient(r).SuggestGasPrice(r.Context())
NetworkConfig(r).LockNonce()
defer NetworkConfig(r).UnlockNonce()

tx, err := processLegacyTx(r, voting, dataBytes)
if err != nil {
Log(r).WithError(err).Error("failed to suggest gas price")
Log(r).WithError(err).Error("failed to process legacy transaction")
ape.RenderErr(w, problems.InternalError())
return
}
gasPrice = multiplyGasPrice(gasPrice, NetworkConfig(r).GasMultiplier)

NetworkConfig(r).LockNonce()
defer NetworkConfig(r).UnlockNonce()
NetworkConfig(r).IncrementNonce()

gas, err := EthClient(r).EstimateGas(r.Context(), ethereum.CallMsg{
From: crypto.PubkeyToAddress(NetworkConfig(r).PrivateKey.PublicKey),
To: &voting,
GasPrice: gasPrice,
Data: dataBytes,
})
ape.Render(w, newTxModel(tx))
}

// ONE - One GWEI
var ONE = 1000000000

func multiplyGasPrice(gasPrice *big.Int, multiplier float64) *big.Int {
mult := big.NewFloat(0).Mul(big.NewFloat(multiplier), big.NewFloat(float64(ONE)))
gas, _ := big.NewFloat(0).Mul(big.NewFloat(0).SetInt(gasPrice), mult).Int(nil)
return big.NewInt(0).Div(gas, big.NewInt(int64(ONE)))
}

func processLegacyTx(r *http.Request, receiver common.Address, txData []byte) (*types.Transaction, error) {
gasPrice, gasLimit, err := getGasCosts(r, receiver, txData)
if err != nil {
Log(r).WithError(err).Error("failed to estimate gas")
ape.RenderErr(w, problems.InternalError())
return
return nil, errors.Wrap(err, "failed to get gas costs")
}

tx, err := types.SignNewTx(
NetworkConfig(r).PrivateKey,
types.NewCancunSigner(NetworkConfig(r).ChainID),
&types.LegacyTx{
Nonce: NetworkConfig(r).Nonce(),
Gas: gas,
Gas: gasLimit,
GasPrice: gasPrice,
To: &voting,
Data: dataBytes,
To: &receiver,
Data: txData,
},
)
if err != nil {
Log(r).WithError(err).Error("failed to sign new tx")
ape.RenderErr(w, problems.InternalError())
return
return nil, errors.Wrap(err, "failed to sign new tx")
}

if err = sendTransaction(r, tx); err != nil {
return nil, errors.Wrap(err, "failed to send transaction")
}

return tx, nil
}

func getGasCosts(
r *http.Request,
receiver common.Address,
txData []byte,
) (gasPrice *big.Int, gasLimit uint64, err error) {
gasPrice, err = EthClient(r).SuggestGasPrice(r.Context())
if err != nil {
return nil, 0, errors.Wrap(err, "failed to suggest gas price")
}
gasPrice = multiplyGasPrice(gasPrice, NetworkConfig(r).GasMultiplier)

gasLimit, err = EthClient(r).EstimateGas(r.Context(), ethereum.CallMsg{
From: crypto.PubkeyToAddress(NetworkConfig(r).PrivateKey.PublicKey),
To: &receiver,
GasPrice: gasPrice,
Data: txData,
})
if err != nil {
return nil, 0, errors.Wrap(err, "failed to estimate gas costs limit")
}
gasLimit = uint64(float64(gasLimit) * NetworkConfig(r).GasMultiplier)

return
}

func sendTransaction(r *http.Request, tx *types.Transaction) error {
if err := EthClient(r).SendTransaction(r.Context(), tx); err != nil {
if strings.Contains(err.Error(), "nonce") {
if err := NetworkConfig(r).ResetNonce(EthClient(r)); err != nil {
Log(r).WithError(err).Error("failed to reset nonce")
ape.RenderErr(w, problems.InternalError())
return
if err = NetworkConfig(r).ResetNonce(EthClient(r)); err != nil {
return errors.Wrap(err, "failed to reset nonce")
}

tx, err = types.SignNewTx(
NetworkConfig(r).PrivateKey,
types.NewCancunSigner(NetworkConfig(r).ChainID),
&types.LegacyTx{
Nonce: NetworkConfig(r).Nonce(),
Gas: gas,
GasPrice: gasPrice,
To: &voting,
Data: dataBytes,
Gas: tx.Gas(),
GasPrice: tx.GasPrice(),
To: tx.To(),
Data: tx.Data(),
},
)
if err != nil {
Log(r).WithError(err).Error("failed to sign new tx")
ape.RenderErr(w, problems.InternalError())
return
return errors.Wrap(err, "failed to sign new tx")
}

if err := EthClient(r).SendTransaction(r.Context(), tx); err != nil {
Log(r).WithError(err).Error("failed to send transaction")
ape.RenderErr(w, problems.InternalError())
return
return errors.Wrap(err, "failed to resend transaction")
}
} else {
Log(r).WithError(err).Error("failed to send transaction")
ape.RenderErr(w, problems.InternalError())
return
return errors.Wrap(err, "failed to send transaction")
}
}

NetworkConfig(r).IncrementNonce()

ape.Render(w, newTxModel(tx))
}

// ONE - One GWEI
var ONE = 1000000000

func multiplyGasPrice(gasPrice *big.Int, multiplier float64) *big.Int {
mult := big.NewFloat(0).Mul(big.NewFloat(multiplier), big.NewFloat(float64(ONE)))
gas, _ := big.NewFloat(0).Mul(big.NewFloat(0).SetInt(gasPrice), mult).Int(nil)
return big.NewInt(0).Div(gas, big.NewInt(int64(ONE)))
return nil
}

0 comments on commit dd14776

Please sign in to comment.