From 34c827ecfa68ee99bc386aca8ac7f295ba43377b Mon Sep 17 00:00:00 2001 From: Ferran Date: Sun, 16 Jan 2022 15:32:14 +0100 Subject: [PATCH 1/3] Add relayer impl --- relayer/gaspricer/gaspricer.go | 8 +++ relayer/gaspricer/network.go | 74 +++++++++++++++++++++++ relayer/gaspricer/network_test.go | 22 +++++++ relayer/relayer.go | 98 +++++++++++++++++++++++++++++++ relayer/relayer_test.go | 1 + 5 files changed, 203 insertions(+) create mode 100644 relayer/gaspricer/gaspricer.go create mode 100644 relayer/gaspricer/network.go create mode 100644 relayer/gaspricer/network_test.go create mode 100644 relayer/relayer.go create mode 100644 relayer/relayer_test.go diff --git a/relayer/gaspricer/gaspricer.go b/relayer/gaspricer/gaspricer.go new file mode 100644 index 00000000..291d772f --- /dev/null +++ b/relayer/gaspricer/gaspricer.go @@ -0,0 +1,8 @@ +package gaspricer + +import "context" + +type GasPricer interface { + Start(ctx context.Context) + GasPrice() uint64 +} diff --git a/relayer/gaspricer/network.go b/relayer/gaspricer/network.go new file mode 100644 index 00000000..47520387 --- /dev/null +++ b/relayer/gaspricer/network.go @@ -0,0 +1,74 @@ +package gaspricer + +import ( + "context" + "log" + "os" + "sync" + "time" + + "github.com/umbracle/go-web3/jsonrpc" +) + +func NewNetworkGasPricer(logger *log.Logger, client *jsonrpc.Eth, interval ...time.Duration) (GasPricer, error) { + if logger == nil { + logger = log.New(os.Stdout, "", log.LstdFlags) + } + n := &NetworkGasPricer{ + client: client, + logger: logger, + } + if len(interval) == 1 { + n.interval = interval[0] + } else { + n.interval = 15 * time.Second + } + + // try to fetch the gas price once + if err := n.updateGasPrice(); err != nil { + return nil, err + } + return n, nil +} + +type NetworkGasPricer struct { + logger *log.Logger + lock sync.Mutex + client *jsonrpc.Eth + interval time.Duration + gasPrice uint64 +} + +func (n *NetworkGasPricer) updateGasPrice() error { + n.lock.Lock() + defer n.lock.Unlock() + + gasPrice, err := n.client.GasPrice() + if err != nil { + return err + } + n.gasPrice = gasPrice + return nil +} + +func (n *NetworkGasPricer) Start(ctx context.Context) { + go func() { + for { + select { + case <-time.After(n.interval): + if err := n.updateGasPrice(); err != nil { + n.logger.Printf("[ERROR]: Failed to get gas price: %v", err) + } + case <-ctx.Done(): + return + } + } + }() +} + +func (n *NetworkGasPricer) GasPrice() uint64 { + n.lock.Lock() + defer n.lock.Unlock() + + return n.gasPrice +} diff --git a/relayer/gaspricer/network_test.go b/relayer/gaspricer/network_test.go new file mode 100644 index 00000000..db7a8f56 --- /dev/null +++ b/relayer/gaspricer/network_test.go @@ -0,0 +1,22 @@ +package gaspricer + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/umbracle/go-web3/jsonrpc" + "github.com/umbracle/go-web3/testutil" +) + +func TestGasPricer_Network(t *testing.T) { + srv := testutil.NewTestServer(t, nil) + defer srv.Close() + + client, err := jsonrpc.NewClient(srv.HTTPAddr()) + assert.NoError(t, err) + + pricer, err := NewNetworkGasPricer(nil, client.Eth()) + assert.NoError(t, err) + + assert.Equal(t, pricer.GasPrice(), uint64(1)) +} diff --git a/relayer/relayer.go b/relayer/relayer.go new file mode 100644 index 00000000..9ee9c1f8 --- /dev/null +++ b/relayer/relayer.go @@ -0,0 +1,98 @@ +package relayer + +import ( + "log" + "os" + + "github.com/umbracle/go-web3" + "github.com/umbracle/go-web3/jsonrpc" + "github.com/umbracle/go-web3/relayer/gaspricer" +) + +type Config struct { + Logger *log.Logger + Endpoint string + GasPricer gaspricer.GasPricer +} + +type RelayerOption func(*Config) + +func WithGasPricer(pricer gaspricer.GasPricer) RelayerOption { + return func(c *Config) { + c.GasPricer = pricer + } +} + +func WithJSONRPCEndpoint(endpoint string) RelayerOption { + return func(c *Config) { + c.Endpoint = endpoint + } +} + +func WithLogger(logger *log.Logger) RelayerOption { + return func(c *Config) { + c.Logger = logger + } +} + +func DefaultConfig() *Config { + return &Config{ + Logger: log.New(os.Stdout, "", log.LstdFlags), + Endpoint: "http://localhost:8545", + } +} + +type Relayer struct { + config *Config + client *jsonrpc.Client + closeCh chan struct{} +} + +func NewRelayer(configOpts ...RelayerOption) (*Relayer, error) { + config := DefaultConfig() + for _, opts := range configOpts { + opts(config) + } + + client, err := jsonrpc.NewClient(config.Endpoint) + if err != nil { + return nil, err + } + + // if gas pricer is not set, use the network one + if config.GasPricer == nil { + pricer, err := gaspricer.NewNetworkGasPricer(config.Logger, client.Eth()) + if err != nil { + return nil, err + } + config.GasPricer = pricer + } + + r := &Relayer{ + config: config, + client: client, + closeCh: make(chan struct{}), + } + + // fill in the pending queue with the pending transactions + // from the storage + + go r.run() + + return r, nil +} + +func (r *Relayer) SendTransaction(txn *web3.Transaction) (web3.Hash, error) { + return web3.Hash{}, nil +} + +func (r *Relayer) run() { + for { + // wait to see if anything is stucked + // after it is done move to the next pending txn + select { + case <-r.closeCh: + return + } + } +} diff --git a/relayer/relayer_test.go b/relayer/relayer_test.go new file mode 100644 index 00000000..dfd65c3e --- /dev/null +++ b/relayer/relayer_test.go @@ -0,0 +1 @@ +package relayer From 92a3a2f62e33e4a22484f81332b3a43a921c68c6 Mon Sep 17 00:00:00 2001 From: Ferran Date: Tue, 5 Apr 2022 18:25:35 +0400 Subject: [PATCH 2/3] Merge conflicts --- relayer/gaspricer/network.go | 2 +- relayer/gaspricer/network_test.go | 4 ++-- relayer/relayer.go | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/relayer/gaspricer/network.go b/relayer/gaspricer/network.go index 47520387..ded3e54a 100644 --- a/relayer/gaspricer/network.go +++ b/relayer/gaspricer/network.go @@ -7,7 +7,7 @@ import ( "sync" "time" - "github.com/umbracle/go-web3/jsonrpc" + "github.com/umbracle/ethgo/jsonrpc" ) func NewNetworkGasPricer(logger *log.Logger, client *jsonrpc.Eth, interval ...time.Duration) (GasPricer, error) { diff --git a/relayer/gaspricer/network_test.go b/relayer/gaspricer/network_test.go index db7a8f56..7b539329 100644 --- a/relayer/gaspricer/network_test.go +++ b/relayer/gaspricer/network_test.go @@ -4,8 +4,8 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/umbracle/go-web3/jsonrpc" - "github.com/umbracle/go-web3/testutil" + "github.com/umbracle/ethgo/jsonrpc" + "github.com/umbracle/ethgo/testutil" ) func TestGasPricer_Network(t *testing.T) { diff --git a/relayer/relayer.go b/relayer/relayer.go index 9ee9c1f8..ed25c033 100644 --- a/relayer/relayer.go +++ b/relayer/relayer.go @@ -4,9 +4,9 @@ import ( "log" "os" - "github.com/umbracle/go-web3" - "github.com/umbracle/go-web3/jsonrpc" - "github.com/umbracle/go-web3/relayer/gaspricer" + "github.com/umbracle/ethgo" + "github.com/umbracle/ethgo/jsonrpc" + "github.com/umbracle/ethgo/relayer/gaspricer" ) type Config struct { @@ -82,8 +82,8 @@ func NewRelayer(configOpts ...RelayerOption) (*Relayer, error) { return r, nil } -func (r *Relayer) SendTransaction(txn *web3.Transaction) (web3.Hash, error) { - return web3.Hash{}, nil +func (r *Relayer) SendTransaction(txn *ethgo.Transaction) (ethgo.Hash, error) { + return ethgo.Hash{}, nil } func (r *Relayer) run() { From f45b9d09e62a2c0d9945a913ff94256991d0b6cc Mon Sep 17 00:00:00 2001 From: Ferran Date: Tue, 5 Apr 2022 18:39:13 +0400 Subject: [PATCH 3/3] Mock --- relayer/relayer.go | 24 +++++++++++++++++++++--- relayer/relayer_test.go | 6 ++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/relayer/relayer.go b/relayer/relayer.go index ed25c033..c2f5ffc8 100644 --- a/relayer/relayer.go +++ b/relayer/relayer.go @@ -1,14 +1,18 @@ package relayer import ( + "fmt" "log" "os" "github.com/umbracle/ethgo" + "github.com/umbracle/ethgo/contract" "github.com/umbracle/ethgo/jsonrpc" "github.com/umbracle/ethgo/relayer/gaspricer" ) +var _ contract.Provider = (*Relayer)(nil) + type Config struct { Logger *log.Logger Endpoint string @@ -74,14 +78,24 @@ func NewRelayer(configOpts ...RelayerOption) (*Relayer, error) { closeCh: make(chan struct{}), } - // fill in the pending queue with the pending transactions - // from the storage - go r.run() return r, nil } +type stateTxn struct { + To ethgo.Address + key ethgo.Key + input []byte + opts *contract.TxnOpts +} + +func (r *Relayer) Txn(to ethgo.Address, key ethgo.Key, input []byte, opts *contract.TxnOpts) (contract.Txn, error) { + txn := &stateTxn{} + fmt.Println(txn) + return nil, nil +} + func (r *Relayer) SendTransaction(txn *ethgo.Transaction) (ethgo.Hash, error) { return ethgo.Hash{}, nil } @@ -96,3 +110,7 @@ func (r *Relayer) run() { } } } + +func (r *Relayer) Call(to ethgo.Address, input []byte, opts *contract.CallOpts) ([]byte, error) { + panic("relayer does not make calls") +} diff --git a/relayer/relayer_test.go b/relayer/relayer_test.go index dfd65c3e..f2e91370 100644 --- a/relayer/relayer_test.go +++ b/relayer/relayer_test.go @@ -1 +1,7 @@ package relayer + +import "testing" + +func TestRelayer(t *testing.T) { + +}