github.com/tacshi/go-ethereum@v0.0.0-20230616113857-84a434e20921/arbitrum/conditionaltx.go (about)

     1  package arbitrum
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  
     7  	"github.com/tacshi/go-ethereum/arbitrum_types"
     8  	"github.com/tacshi/go-ethereum/common"
     9  	"github.com/tacshi/go-ethereum/common/hexutil"
    10  	"github.com/tacshi/go-ethereum/core/types"
    11  	"github.com/tacshi/go-ethereum/crypto"
    12  	"github.com/tacshi/go-ethereum/internal/ethapi"
    13  	"github.com/tacshi/go-ethereum/log"
    14  	"github.com/tacshi/go-ethereum/rpc"
    15  )
    16  
    17  type ArbTransactionAPI struct {
    18  	b *APIBackend
    19  }
    20  
    21  func NewArbTransactionAPI(b *APIBackend) *ArbTransactionAPI {
    22  	return &ArbTransactionAPI{b}
    23  }
    24  
    25  func (s *ArbTransactionAPI) SendRawTransactionConditional(ctx context.Context, input hexutil.Bytes, options *arbitrum_types.ConditionalOptions) (common.Hash, error) {
    26  	tx := new(types.Transaction)
    27  	if err := tx.UnmarshalBinary(input); err != nil {
    28  		return common.Hash{}, err
    29  	}
    30  	return SubmitConditionalTransaction(ctx, s.b, tx, options)
    31  }
    32  
    33  func SubmitConditionalTransaction(ctx context.Context, b *APIBackend, tx *types.Transaction, options *arbitrum_types.ConditionalOptions) (common.Hash, error) {
    34  	// If the transaction fee cap is already specified, ensure the
    35  	// fee of the given transaction is _reasonable_.
    36  	if err := ethapi.CheckTxFee(tx.GasPrice(), tx.Gas(), b.RPCTxFeeCap()); err != nil {
    37  		return common.Hash{}, err
    38  	}
    39  	if !b.UnprotectedAllowed() && !tx.Protected() {
    40  		// Ensure only eip155 signed transactions are submitted if EIP155Required is set.
    41  		return common.Hash{}, errors.New("only replay-protected (EIP-155) transactions allowed over RPC")
    42  	}
    43  	if err := b.SendConditionalTx(ctx, tx, options); err != nil {
    44  		return common.Hash{}, err
    45  	}
    46  	// Print a log with full tx details for manual investigations and interventions
    47  	signer := types.MakeSigner(b.ChainConfig(), b.CurrentBlock().Number)
    48  	from, err := types.Sender(signer, tx)
    49  	if err != nil {
    50  		return common.Hash{}, err
    51  	}
    52  
    53  	if tx.To() == nil {
    54  		addr := crypto.CreateAddress(from, tx.Nonce())
    55  		log.Info("Submitted contract creation", "hash", tx.Hash().Hex(), "from", from, "nonce", tx.Nonce(), "contract", addr.Hex(), "value", tx.Value())
    56  	} else {
    57  		log.Info("Submitted transaction", "hash", tx.Hash().Hex(), "from", from, "nonce", tx.Nonce(), "recipient", tx.To(), "value", tx.Value())
    58  	}
    59  	return tx.Hash(), nil
    60  }
    61  
    62  func SendConditionalTransactionRPC(ctx context.Context, rpc *rpc.Client, tx *types.Transaction, options *arbitrum_types.ConditionalOptions) error {
    63  	data, err := tx.MarshalBinary()
    64  	if err != nil {
    65  		return err
    66  	}
    67  	return rpc.CallContext(ctx, nil, "eth_sendRawTransactionConditional", hexutil.Encode(data), options)
    68  }