mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 19:50:36 +00:00
87 lines
2.9 KiB
Go
87 lines
2.9 KiB
Go
package jsonrpc
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"math/big"
|
|
|
|
"github.com/ledgerwatch/erigon-lib/common"
|
|
"github.com/ledgerwatch/erigon-lib/common/hexutility"
|
|
txPoolProto "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool"
|
|
|
|
"github.com/ledgerwatch/erigon/core/types"
|
|
"github.com/ledgerwatch/erigon/eth/ethconfig"
|
|
"github.com/ledgerwatch/erigon/params"
|
|
)
|
|
|
|
// SendRawTransaction implements eth_sendRawTransaction. Creates new message call transaction or a contract creation for previously-signed transactions.
|
|
func (api *APIImpl) SendRawTransaction(ctx context.Context, encodedTx hexutility.Bytes) (common.Hash, error) {
|
|
txn, err := types.DecodeWrappedTransaction(encodedTx)
|
|
if err != nil {
|
|
return common.Hash{}, err
|
|
}
|
|
|
|
// If the transaction fee cap is already specified, ensure the
|
|
// fee of the given transaction is _reasonable_.
|
|
if err := checkTxFee(txn.GetPrice().ToBig(), txn.GetGas(), ethconfig.Defaults.RPCTxFeeCap); err != nil {
|
|
return common.Hash{}, err
|
|
}
|
|
if !txn.Protected() {
|
|
return common.Hash{}, errors.New("only replay-protected (EIP-155) transactions allowed over RPC")
|
|
}
|
|
|
|
// this has been moved to prior to adding of transactions to capture the
|
|
// pre state of the db - which is used for logging in the messages below
|
|
tx, err := api.db.BeginRo(ctx)
|
|
if err != nil {
|
|
return common.Hash{}, err
|
|
}
|
|
|
|
defer tx.Rollback()
|
|
|
|
cc, err := api.chainConfig(tx)
|
|
if err != nil {
|
|
return common.Hash{}, err
|
|
}
|
|
|
|
txnChainId := txn.GetChainID()
|
|
chainId := cc.ChainID
|
|
|
|
if chainId.Cmp(txnChainId.ToBig()) != 0 {
|
|
return common.Hash{}, fmt.Errorf("invalid chain id, expected: %d got: %d", chainId, *txnChainId)
|
|
}
|
|
|
|
hash := txn.Hash()
|
|
res, err := api.txPool.Add(ctx, &txPoolProto.AddRequest{RlpTxs: [][]byte{encodedTx}})
|
|
if err != nil {
|
|
return common.Hash{}, err
|
|
}
|
|
|
|
if res.Imported[0] != txPoolProto.ImportResult_SUCCESS {
|
|
return hash, fmt.Errorf("%s: %s", txPoolProto.ImportResult_name[int32(res.Imported[0])], res.Errors[0])
|
|
}
|
|
|
|
return txn.Hash(), nil
|
|
}
|
|
|
|
// SendTransaction implements eth_sendTransaction. Creates new message call transaction or a contract creation if the data field contains code.
|
|
func (api *APIImpl) SendTransaction(_ context.Context, txObject interface{}) (common.Hash, error) {
|
|
return common.Hash{0}, fmt.Errorf(NotImplemented, "eth_sendTransaction")
|
|
}
|
|
|
|
// checkTxFee is an internal function used to check whether the fee of
|
|
// the given transaction is _reasonable_(under the cap).
|
|
func checkTxFee(gasPrice *big.Int, gas uint64, gasCap float64) error {
|
|
// Short circuit if there is no gasCap for transaction fee at all.
|
|
if gasCap == 0 {
|
|
return nil
|
|
}
|
|
feeEth := new(big.Float).Quo(new(big.Float).SetInt(new(big.Int).Mul(gasPrice, new(big.Int).SetUint64(gas))), new(big.Float).SetInt(big.NewInt(params.Ether)))
|
|
feeFloat, _ := feeEth.Float64()
|
|
if feeFloat > gasCap {
|
|
return fmt.Errorf("tx fee (%.2f ether) exceeds the configured cap (%.2f ether)", feeFloat, gasCap)
|
|
}
|
|
return nil
|
|
}
|