Skip to content

Commit

Permalink
v0.3.9, broadcast eth_sendRawTransaction to all nodes
Browse files Browse the repository at this point in the history
superisaac committed Apr 19, 2024
1 parent b1ef629 commit a15fcc4
Showing 3 changed files with 90 additions and 2 deletions.
42 changes: 41 additions & 1 deletion chains/web3.go
Original file line number Diff line number Diff line change
@@ -170,6 +170,44 @@ func (self *Web3Chain) GetBlockhead(context context.Context, m *nodemuxcore.Mult
return block, nil
}

func (self *Web3Chain) sendRawTransaction(ctx context.Context, m *nodemuxcore.Multiplexer, chain nodemuxcore.ChainRef, reqmsg *jsoff.RequestMessage, r *http.Request) (jsoff.Message, error) {
resMsgs := m.BroadcastRPC(ctx, chain, reqmsg, -10)
if len(resMsgs) == 0 {
return m.DefaultRelayRPC(ctx, chain, reqmsg, -5)
}

// try find the correct response
// return the first correct response
for _, res := range resMsgs {
if res.Err == nil && res.Msg.IsResult() {
return res.Msg, nil
}
}

// return the first -32000, already known result
for _, res := range resMsgs {
if res.Err == nil && res.Msg.IsError() && res.Msg.MustError().Code == -32000 {
return res.Msg, nil
}
}

// return the first error msg
for _, res := range resMsgs {
if res.Err == nil && res.Msg.IsError() {
return res.Msg, nil
}
}

// return the first item that has a message
for _, res := range resMsgs {
if res.Err == nil && res.Msg != nil {
return res.Msg, nil
}
}
// reutrn error
return nil, resMsgs[0].Err
}

func (self *Web3Chain) DelegateRPC(ctx context.Context, m *nodemuxcore.Multiplexer, chain nodemuxcore.ChainRef, reqmsg *jsoff.RequestMessage, r *http.Request) (jsoff.Message, error) {
if allowed, ok := allowedMethods[reqmsg.Method]; !ok || !allowed {
reqmsg.Log().Warnf("relayer method not supported %s", reqmsg.Method)
@@ -203,7 +241,9 @@ func (self *Web3Chain) DelegateRPC(ctx context.Context, m *nodemuxcore.Multiplex
return retmsg, nil
}

if reqmsg.Method == "eth_getBlockByNumber" {
if reqmsg.Method == "eth_sendRawTransaction" {
return self.sendRawTransaction(ctx, m, chain, reqmsg, r)
} else if reqmsg.Method == "eth_getBlockByNumber" {
if h, ok := self.findBlockHeight(reqmsg); ok {
return m.DefaultRelayRPC(ctx, chain, reqmsg, h)
}
45 changes: 44 additions & 1 deletion core/multiplexer.go
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ import (
log "github.com/sirupsen/logrus"
"github.com/superisaac/jsoff"
"net/http"
//"sync"
"sync"
)

// singleton vars and methods
@@ -119,6 +119,18 @@ func (self *Multiplexer) Select(chain ChainRef, method string) (*Endpoint, bool)
return nil, false
}

func (self *Multiplexer) AllHealthyEndpoints(chain ChainRef, method string, height int) []*Endpoint {
if endpoints, ok := self.chainIndex[chain]; ok {
healthyEndpoints := make([]*Endpoint, 0)
for _, ep := range endpoints.items {
if ep.Available(method, height) {
healthyEndpoints = append(healthyEndpoints, ep)
}
}
}
return nil
}

func (self *Multiplexer) SelectOverHeight(chain ChainRef, method string, heightSpec int) (*Endpoint, bool) {
if endpoints, ok := self.chainIndex[chain]; ok {
height := heightSpec
@@ -181,6 +193,37 @@ func (self *Multiplexer) LoadFromConfig(nbcfg *NodemuxConfig) {
}
}

func (self *Multiplexer) BroadcastRPC(
rootCtx context.Context,
chain ChainRef,
reqmsg *jsoff.RequestMessage,
overHeight int) []RpcResult {
eps := self.AllHealthyEndpoints(chain, reqmsg.Method, overHeight)
if len(eps) == 0 {
return nil
}

wg := new(sync.WaitGroup)
results := make([]RpcResult, 0)
lock := sync.RWMutex{}

for _, ep := range eps {
wg.Add(1)
go func(ep *Endpoint) {
resmsg, err := ep.CallRPC(rootCtx, reqmsg)
lock.Lock()
defer lock.Unlock()
results = append(results, RpcResult{
Msg: resmsg,
Err: err,
})
wg.Done()
}(ep)
}
wg.Wait()
return results
}

func (self *Multiplexer) DefaultRelayRPC(
rootCtx context.Context,
chain ChainRef,
5 changes: 5 additions & 0 deletions core/types.go
Original file line number Diff line number Diff line change
@@ -15,6 +15,11 @@ const (
ApiGraphQL
)

type RpcResult struct {
Msg jsoff.Message
Err error
}

// data structures
type Block struct {
Height int `json:"height"`

0 comments on commit a15fcc4

Please sign in to comment.