Skip to content

Commit

Permalink
fix(go/client): allow tx generation in offline mode (#123)
Browse files Browse the repository at this point in the history
Signed-off-by: Artur Troian <troian.ap@gmail.com>
  • Loading branch information
troian authored Feb 28, 2024
1 parent 374b9b3 commit 3d15fce
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 39 deletions.
22 changes: 11 additions & 11 deletions go/node/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ package client
import (
"context"
"errors"
"strings"

sdkclient "github.com/cosmos/cosmos-sdk/client"
"github.com/spf13/pflag"

sdkclient "github.com/cosmos/cosmos-sdk/client"
tmjclient "github.com/tendermint/tendermint/rpc/jsonrpc/client"

"github.com/akash-network/akash-api/go/node/client/v1beta2"
Expand All @@ -23,15 +23,15 @@ func DiscoverClient(ctx context.Context, cctx sdkclient.Context, flags *pflag.Fl
}

result := new(Akash)
params := make(map[string]interface{})
_, err = rpc.Call(ctx, "akash", params, result)
if err != nil && !strings.Contains(err.Error(), "Method not found") {
return err

if !cctx.Offline {
params := make(map[string]interface{})
_, _ = rpc.Call(ctx, "akash", params, result)
}

// if client info is nil, mostly likely "akash" endpoint is not yet supported on the node
// fallback to manually set version to v1beta2
if result.ClientInfo == nil {
if result.ClientInfo == nil || cctx.Offline {
result.ClientInfo = &ClientInfo{ApiVersion: "v1beta2"}
}

Expand Down Expand Up @@ -62,10 +62,10 @@ func DiscoverQueryClient(ctx context.Context, cctx sdkclient.Context, setup func
}

result := new(Akash)
params := make(map[string]interface{})
_, err = rpc.Call(ctx, "akash", params, result)
if err != nil && !strings.Contains(err.Error(), "Method not found") {
return err

if !cctx.Offline {
params := make(map[string]interface{})
_, _ = rpc.Call(ctx, "akash", params, result)
}

if result.ClientInfo == nil {
Expand Down
18 changes: 16 additions & 2 deletions go/node/client/v1beta2/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package v1beta2

import (
"context"
"fmt"

"github.com/gogo/protobuf/proto"
"github.com/spf13/pflag"
Expand All @@ -25,13 +26,12 @@ type QueryClient interface {
ptypes.QueryClient
atypes.QueryClient
ctypes.QueryClient
// authtypes.QueryClient
ClientContext() sdkclient.Context
}

//go:generate mockery --name TxClient --output ./mocks
type TxClient interface {
Broadcast(context.Context, []sdk.Msg, ...BroadcastOption) (proto.Message, error)
Broadcast(context.Context, []sdk.Msg, ...BroadcastOption) (interface{}, error)
}

//go:generate mockery --name NodeClient --output ./mocks
Expand All @@ -45,6 +45,7 @@ type Client interface {
Tx() TxClient
Node() NodeClient
ClientContext() sdkclient.Context
PrintMessage(interface{}) error
}

type client struct {
Expand Down Expand Up @@ -87,3 +88,16 @@ func (cl *client) Node() NodeClient {
func (cl *client) ClientContext() sdkclient.Context {
return cl.qclient.cctx
}

func (cl *client) PrintMessage(msg interface{}) error {
var err error

switch m := msg.(type) {
case proto.Message:
err = cl.qclient.cctx.PrintProto(m)
case []byte:
err = cl.qclient.cctx.PrintString(fmt.Sprintf("%s\n", string(m)))
}

return err
}
80 changes: 54 additions & 26 deletions go/node/client/v1beta2/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ var (
ErrSyncTimedOut = errors.New("tx client: timed-out waiting for sequence sync")
ErrNodeCatchingUp = errors.New("tx client: cannot sync from catching up node")
ErrAdjustGas = errors.New("tx client: couldn't adjust gas")
ErrOffline = errors.New("tx client: cannot broadcast in offline mode")
)

const (
Expand Down Expand Up @@ -64,7 +65,7 @@ func WithResultCodeAsError() BroadcastOption {
}

type broadcastResp struct {
resp proto.Message
resp interface{}
err error
}

Expand Down Expand Up @@ -108,6 +109,10 @@ func newSerialTx(ctx context.Context, cctx sdkclient.Context, flags *pflag.FlagS

keyname := cctx.GetFromName()
info, err := txf.Keybase().Key(keyname)
if err != nil {
info, err = txf.Keybase().KeyByAddress(cctx.GetFromAddress())
}

if err != nil {
return nil, err
}
Expand Down Expand Up @@ -136,12 +141,15 @@ func newSerialTx(ctx context.Context, cctx sdkclient.Context, flags *pflag.FlagS
go client.lc.WatchContext(ctx)
go client.run()
go client.broadcaster(poptxf)
go client.sequenceSync()

if !client.cctx.Offline {
go client.sequenceSync()
}

return client, nil
}

func (c *serialBroadcaster) Broadcast(ctx context.Context, msgs []sdk.Msg, opts ...BroadcastOption) (proto.Message, error) {
func (c *serialBroadcaster) Broadcast(ctx context.Context, msgs []sdk.Msg, opts ...BroadcastOption) (interface{}, error) {
responsech := make(chan broadcastResp, 1)
request := broadcastReq{
responsech: responsech,
Expand Down Expand Up @@ -248,7 +256,7 @@ func (c *serialBroadcaster) broadcaster(txf tx.Factory) {
return
case req := <-c.broadcastch:
var err error
var resp proto.Message
var resp interface{}

resp, txf, err = AdjustGas(c.cctx, txf, req.msgs...)
if err == nil && !c.cctx.Simulate {
Expand All @@ -266,7 +274,8 @@ func (c *serialBroadcaster) broadcaster(txf tx.Factory) {
err: err,
}

if errors.Is(err, &sdkerrors.Error{}) {
terr := &sdkerrors.Error{}
if errors.Is(err, terr) {
_ = syncSequence(err)
}

Expand Down Expand Up @@ -317,10 +326,40 @@ func (c *serialBroadcaster) sequenceSync() {
}
}

func (c *serialBroadcaster) broadcastTxs(txf tx.Factory, msgs ...sdk.Msg) (*sdk.TxResponse, tx.Factory, error) {
func (c *serialBroadcaster) broadcastTxs(txf tx.Factory, msgs ...sdk.Msg) (interface{}, tx.Factory, error) {
var err error

response, err := c.doBroadcast(c.cctx, txf, c.broadcastTimeout, c.info.GetName(), msgs...)
txn, err := tx.BuildUnsignedTx(txf, msgs...)
if err != nil {
return nil, txf, err
}

txn.SetFeeGranter(c.cctx.GetFeeGranterAddress())

if c.cctx.GenerateOnly {
bytes, err := c.cctx.TxConfig.TxJSONEncoder()(txn.GetTx())
if err != nil {
return nil, txf, err
}

return bytes, txf, nil
}

if c.cctx.Offline {
return nil, txf, ErrOffline
}

err = tx.Sign(txf, c.info.GetName(), txn, true)
if err != nil {
return nil, txf, err
}

bytes, err := c.cctx.TxConfig.TxEncoder()(txn.GetTx())
if err != nil {
return nil, txf, err
}

response, err := c.doBroadcast(c.cctx, bytes, c.broadcastTimeout)
if err != nil {
return response, txf, err
}
Expand Down Expand Up @@ -355,24 +394,8 @@ func (c *serialBroadcaster) syncAccountSequence(lSeq uint64) (uint64, error) {
}
}

func (c *serialBroadcaster) doBroadcast(cctx sdkclient.Context, txf tx.Factory, timeout time.Duration, keyName string, msgs ...sdk.Msg) (*sdk.TxResponse, error) {
txn, err := tx.BuildUnsignedTx(txf, msgs...)
if err != nil {
return nil, err
}

txn.SetFeeGranter(cctx.GetFeeGranterAddress())
err = tx.Sign(txf, keyName, txn, true)
if err != nil {
return nil, err
}

bytes, err := cctx.TxConfig.TxEncoder()(txn.GetTx())
if err != nil {
return nil, err
}

txb := ttypes.Tx(bytes)
func (c *serialBroadcaster) doBroadcast(cctx sdkclient.Context, data []byte, timeout time.Duration) (*sdk.TxResponse, error) {
txb := ttypes.Tx(data)
hash := hex.EncodeToString(txb.Hash())

// broadcast-mode=block
Expand Down Expand Up @@ -417,6 +440,10 @@ func (c *serialBroadcaster) doBroadcast(cctx sdkclient.Context, txf tx.Factory,
// PrepareFactory has been copied from cosmos-sdk to make it public.
// Source: https://github.com/cosmos/cosmos-sdk/blob/v0.43.0-rc2/client/tx/tx.go#L311
func PrepareFactory(cctx sdkclient.Context, txf tx.Factory) (tx.Factory, error) {
if cctx.Offline {
return txf, nil
}

from := cctx.GetFromAddress()

if err := txf.AccountRetriever().EnsureExists(cctx, from); err != nil {
Expand All @@ -436,9 +463,10 @@ func PrepareFactory(cctx sdkclient.Context, txf tx.Factory) (tx.Factory, error)
}

func AdjustGas(ctx sdkclient.Context, txf tx.Factory, msgs ...sdk.Msg) (proto.Message, tx.Factory, error) {
if !ctx.Simulate && !txf.SimulateAndExecute() {
if ctx.Offline || (!ctx.Simulate && !txf.SimulateAndExecute()) {
return nil, txf, nil
}

resp, adjusted, err := tx.CalculateGas(ctx, txf, msgs...)
if err != nil {
return resp, txf, err
Expand Down

0 comments on commit 3d15fce

Please sign in to comment.