feat: add alternative RPC provider support for sendTransaction

This commit is contained in:
etimofeeva
2025-08-14 21:11:24 +02:00
committed by Martin
parent 541e30dbaa
commit 0e92dd124b
13 changed files with 34 additions and 16 deletions

View File

@@ -302,9 +302,9 @@ func (c *blockChainWithMetrics) LongTermFeeRate() (v *bchain.LongTermFeeRate, er
return c.b.LongTermFeeRate()
}
func (c *blockChainWithMetrics) SendRawTransaction(tx string) (v string, err error) {
func (c *blockChainWithMetrics) SendRawTransaction(tx string, disableAlternativeRPC bool) (v string, err error) {
defer func(s time.Time) { c.observeRPCLatency("SendRawTransaction", s, err) }(time.Now())
return c.b.SendRawTransaction(tx)
return c.b.SendRawTransaction(tx, disableAlternativeRPC)
}
func (c *blockChainWithMetrics) GetMempoolEntry(txid string) (v *bchain.MempoolEntry, err error) {

View File

@@ -889,7 +889,7 @@ func (b *BitcoinRPC) LongTermFeeRate() (*bchain.LongTermFeeRate, error) {
}
// SendRawTransaction sends raw transaction
func (b *BitcoinRPC) SendRawTransaction(tx string) (string, error) {
func (b *BitcoinRPC) SendRawTransaction(tx string, disableAlternativeRPC bool) (string, error) {
glog.V(1).Info("rpc: sendrawtransaction")
res := ResSendRawTransaction{}

View File

@@ -791,7 +791,7 @@ func (d *DecredRPC) EstimateFee(blocks int) (big.Int, error) {
return r, nil
}
func (d *DecredRPC) SendRawTransaction(tx string) (string, error) {
func (d *DecredRPC) SendRawTransaction(tx string, disableAlternativeRPC bool) (string, error) {
sendRawTxRequest := &GenericCmd{
ID: 1,
Method: "sendrawtransaction",

View File

@@ -1122,12 +1122,15 @@ func (b *EthereumRPC) EthereumTypeGetEip1559Fees() (*bchain.Eip1559Fees, error)
}
// SendRawTransaction sends raw transaction
func (b *EthereumRPC) SendRawTransaction(hex string) (string, error) {
func (b *EthereumRPC) SendRawTransaction(hex string, disableAlternativeRPC bool) (string, error) {
var txid string
var retErr error
if b.alternativeSendTxProvider != nil {
if !disableAlternativeRPC && b.alternativeSendTxProvider != nil {
txid, retErr = b.alternativeSendTxProvider.SendRawTransaction(hex)
if retErr == nil {
return txid, nil
}
if b.alternativeSendTxProvider.UseOnlyAlternativeProvider() {
return txid, retErr
}

View File

@@ -471,7 +471,7 @@ func (n *NulsRPC) EstimateFee(blocks int) (big.Int, error) {
return *big.NewInt(100000), nil
}
func (n *NulsRPC) SendRawTransaction(tx string) (string, error) {
func (n *NulsRPC) SendRawTransaction(tx string, alternativeRPC bool) (string, error) {
broadcast := CmdTxBroadcast{}
req := struct {
TxHex string `json:"txHex"`

View File

@@ -331,7 +331,7 @@ type BlockChain interface {
EstimateSmartFee(blocks int, conservative bool) (big.Int, error)
EstimateFee(blocks int) (big.Int, error)
LongTermFeeRate() (*LongTermFeeRate, error)
SendRawTransaction(tx string) (string, error)
SendRawTransaction(tx string, disableAlternativeRPC bool) (string, error)
GetMempoolEntry(txid string) (*MempoolEntry, error)
GetContractInfo(contractDesc AddressDescriptor) (*ContractInfo, error)
// parser

View File

@@ -754,6 +754,8 @@ export interface WsLongTermFeeRateRes {
export interface WsSendTransactionReq {
/** Hex-encoded transaction data to broadcast. */
hex: string;
/** Use alternative RPC method to broadcast transaction. */
disableAlternativeRPC?: boolean;
}
export interface WsSubscribeAddressesReq {
/** List of addresses to subscribe for updates (e.g., new transactions). */

View File

@@ -1059,7 +1059,7 @@ func (s *PublicServer) explorerSendTx(w http.ResponseWriter, r *http.Request) (t
}
hex := r.FormValue("hex")
if len(hex) > 0 {
res, err := s.chain.SendRawTransaction(hex)
res, err := s.chain.SendRawTransaction(hex, false)
if err != nil {
data.SendTxHex = hex
data.Error = &api.APIError{Text: err.Error(), Public: true}
@@ -1509,7 +1509,7 @@ func (s *PublicServer) apiSendTx(r *http.Request, apiVersion int) (interface{},
}
}
if len(hex) > 0 {
res.Result, err = s.chain.SendRawTransaction(hex)
res.Result, err = s.chain.SendRawTransaction(hex, false)
if err != nil {
return nil, api.NewAPIError(err.Error(), true)
}

View File

@@ -153,6 +153,17 @@ var websocketTestsEthereumType = []websocketTest{
},
want: `{"id":"1","data":{"data":"0x4567abcd"}}`,
},
{
name: "websocket sendTransaction hex format",
req: websocketReq{
Method: "sendTransaction",
Params: WsSendTransactionReq{
Hex: "123456",
DisableAlternativeRPC: true,
},
},
want: `{"id":"2","data":{"result":"9876"}}`,
},
}
func initEthereumTypeDB(d *db.RocksDB) error {

View File

@@ -641,7 +641,7 @@ func (s *SocketIoServer) getDetailedTransaction(txid string) (res resultGetDetai
}
func (s *SocketIoServer) sendTransaction(tx string) (res resultSendTransaction, err error) {
txid, err := s.chain.SendRawTransaction(tx)
txid, err := s.chain.SendRawTransaction(tx, false)
if err != nil {
return res, err
}

View File

@@ -376,10 +376,11 @@ var requestHandlers = map[string]func(*WebsocketServer, *websocketChannel, *WsRe
r := WsSendTransactionReq{}
err = json.Unmarshal(req.Params, &r)
if err == nil {
rv, err = s.sendTransaction(r.Hex)
rv, err = s.sendTransaction(r.Hex, r.DisableAlternativeRPC)
}
return
},
"getMempoolFilters": func(s *WebsocketServer, c *websocketChannel, req *WsReq) (rv interface{}, err error) {
r := WsMempoolFiltersReq{}
err = json.Unmarshal(req.Params, &r)
@@ -751,8 +752,8 @@ func (s *WebsocketServer) longTermFeeRate() (res interface{}, err error) {
}, nil
}
func (s *WebsocketServer) sendTransaction(tx string) (res resultSendTransaction, err error) {
txid, err := s.chain.SendRawTransaction(tx)
func (s *WebsocketServer) sendTransaction(tx string, disableAlternativeRPC bool) (res resultSendTransaction, err error) {
txid, err := s.chain.SendRawTransaction(tx, disableAlternativeRPC)
if err != nil {
return res, err
}

View File

@@ -141,7 +141,8 @@ type WsLongTermFeeRateRes struct {
// WsSendTransactionReq is used to broadcast a transaction to the network.
type WsSendTransactionReq struct {
Hex string `json:"hex" ts_doc:"Hex-encoded transaction data to broadcast."`
Hex string `json:"hex,omitempty" ts_doc:"Hex-encoded transaction data to broadcast (string format)."`
DisableAlternativeRPC bool `json:"disableAlternativeRpc" ts_doc:"Use alternative RPC method to broadcast transaction."`
}
// WsSubscribeAddressesReq is used to subscribe to updates on a list of addresses.

View File

@@ -201,7 +201,7 @@ func (c *fakeBlockChain) EstimateFee(blocks int) (v big.Int, err error) {
return
}
func (c *fakeBlockChain) SendRawTransaction(tx string) (v string, err error) {
func (c *fakeBlockChain) SendRawTransaction(tx string, disableAlternativeRPC bool) (v string, err error) {
if tx == "123456" {
return "9876", nil
}