diff --git a/node/node.go b/node/node.go index 96fa8b967e..a1f37f7a1b 100644 --- a/node/node.go +++ b/node/node.go @@ -52,7 +52,8 @@ type Node struct { DataExchange exchange.Interface DAG format.DAGService // p2p protocols - PubSub *pubsub.PubSub + PubSub *pubsub.PubSub + // services ShareServ share.Service // not optional HeaderServ *header.Service // not optional StateServ *state.Service // not optional diff --git a/service/state/pfd.go b/service/state/pfd.go index 68270bf6e9..c7725a3eb4 100644 --- a/service/state/pfd.go +++ b/service/state/pfd.go @@ -10,17 +10,22 @@ import ( ) var ( + // TODO @renaynay: docs +/ this should be configurable gasLim = uint64(200000) + // TODO @renaynay: docs + shareSizes = []uint64{16, 32, 64, 128} ) +// TODO @renaynay: docs type PayForData = apptypes.MsgWirePayForMessage // SubmitPayForData builds, signs and submits a PayForData message. -func (s *Service) SubmitPayForData(ctx context.Context, nID namespace.ID, message []byte) (*TxResponse, error) { - pfd, err := s.BuildPayForData(ctx, nID, message) +func (s *Service) SubmitPayForData(ctx context.Context, nID namespace.ID, data []byte) (*TxResponse, error) { + pfd, err := s.BuildPayForData(ctx, nID, data) if err != nil { return nil, err } + signed, err := s.SignPayForData(pfd, apptypes.SetGasLimit(gasLim)) if err != nil { return nil, err @@ -36,9 +41,11 @@ func (s *Service) SubmitPayForData(ctx context.Context, nID namespace.ID, messag } // BuildPayForData builds a PayForData message. +// TODO @renaynay: make max size a param and anything above errors out. func (s *Service) BuildPayForData(ctx context.Context, nID namespace.ID, message []byte) (*PayForData, error) { // create the raw WirePayForMessage transaction - wpfmMsg, err := apptypes.NewWirePayForMessage(nID, message, 16, 32, 64, 128) + // TODO @renaynay: make sizes a const + wpfmMsg, err := apptypes.NewWirePayForMessage(nID, message, shareSizes...) if err != nil { return nil, err } diff --git a/service/state/pfd_test.go b/service/state/pfd_test.go new file mode 100644 index 0000000000..e379e1e7b3 --- /dev/null +++ b/service/state/pfd_test.go @@ -0,0 +1,58 @@ +package state + +import ( + "context" + "github.com/celestiaorg/celestia-app/app" + apptypes "github.com/celestiaorg/celestia-app/x/payment/types" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + "github.com/stretchr/testify/require" + "github.com/tendermint/spm/cosmoscmd" + "os" + "path/filepath" + "testing" +) + +// TODO @renaynay remove unit tests as we don't have mockable app instance + +func TestService_SubmitPayForData(t *testing.T) { + cosmoscmd.SetPrefixes(app.AccountAddressPrefix) + + ctx, cancel := context.WithCancel(context.Background()) + t.Cleanup(cancel) + // setup Service + signer := setupKeyring(t) + endpoint := "127.0.0.1:9090" + ca := NewCoreAccessor(signer, endpoint) + serv := NewService(ca) + // start CA + err := ca.Start(ctx) + require.NoError(t, err) + t.Cleanup(func() { + err = ca.Stop(ctx) + require.NoError(t, err) + }) + // build PFD + nID := []byte{0, 0, 1, 0, 0, 0, 0, 0} + msg := []byte("hello") + + resp, err := serv.SubmitPayForData(ctx, nID, msg) + require.NoError(t, err) + + t.Logf("RESP: \n\n%v", resp) +} + +func TestRene(t *testing.T) { + t.Logf("%x", []byte{0, 0, 1, 0, 0, 0, 0, 0}) + t.Logf("%x", []byte("hello")) +} + +func setupKeyring(t *testing.T) *apptypes.KeyringSigner { + path, err := filepath.Abs(".") + require.NoError(t, err) + t.Log("path: ", path) + + ring, err := keyring.New(app.Name, keyring.BackendTest, path, os.Stdin) + require.NoError(t, err) + + return apptypes.NewKeyringSigner(ring, "celes", "test") +} diff --git a/service/state/rpc.go b/service/state/rpc.go index 57eb69353c..016a093a31 100644 --- a/service/state/rpc.go +++ b/service/state/rpc.go @@ -4,6 +4,7 @@ import ( "encoding/hex" "encoding/json" "fmt" + "io/ioutil" "net/http" "github.com/cosmos/cosmos-sdk/types" @@ -13,17 +14,23 @@ import ( "github.com/celestiaorg/celestia-node/node/rpc" ) -var log = logging.Logger("state/rpc") - var ( addrKey = "address" txKey = "tx" + + log = logging.Logger("state/rpc") ) +type submitPFDRequest struct { + NamespaceID string `json:"namespace_id"` + Data string `json:"data"` +} + func (s *Service) RegisterEndpoints(rpc *rpc.Server) { rpc.RegisterHandlerFunc("/balance", s.handleBalanceRequest, http.MethodGet) rpc.RegisterHandlerFunc(fmt.Sprintf("/balance/{%s}", addrKey), s.handleBalanceForAddrRequest, http.MethodGet) rpc.RegisterHandlerFunc(fmt.Sprintf("/submit_tx/{%s}", txKey), s.handleSubmitTx, http.MethodPost) + rpc.RegisterHandlerFunc("/submit_pfd", s.handleSubmitPFD, http.MethodPost) } func (s *Service) handleBalanceRequest(w http.ResponseWriter, r *http.Request) { @@ -101,3 +108,51 @@ func (s *Service) handleSubmitTx(w http.ResponseWriter, r *http.Request) { log.Errorw("writing /balance response", "err", err) } } + +func (s *Service) handleSubmitPFD(w http.ResponseWriter, r *http.Request) { + // parse body from request + raw, err := ioutil.ReadAll(r.Body) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + log.Errorw("serving /submit_pfd request", "err", err) + return + } + // decode request + req := new(submitPFDRequest) + err = json.Unmarshal(raw, req) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + log.Errorw("serving /submit_pfd request", "err", err) + return + } + nID, err := hex.DecodeString(req.NamespaceID) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + log.Errorw("serving /submit_pfd request", "err", err) + return + } + data, err := hex.DecodeString(req.Data) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + log.Errorw("serving /submit_pfd request", "err", err) + return + } + + // perform request + txResp, err := s.SubmitPayForData(r.Context(), nID, data) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + log.Errorw("serving /submit_pfd request", "err", err) + return + } + resp, err := json.Marshal(txResp) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + log.Errorw("serving /submit_pfd request", "err", err) + return + } + _, err = w.Write(resp) + if err != nil { + log.Errorw("writing /submit_pfd response", "err", err) + } +} diff --git a/service/state/state.go b/service/state/state.go index 74e50ae99b..bd1b4d587f 100644 --- a/service/state/state.go +++ b/service/state/state.go @@ -8,7 +8,6 @@ import ( // Balance is an alias to the Coin type from Cosmos-SDK. type Balance = sdk.Coin -// Tx is an alias to the Tx type from celestia-core. type Tx = coretypes.Tx // TxResponse is an alias to the TxResponse type from Cosmos-SDK.