2020-11-18 18:33:03 +00:00
|
|
|
package filecoin
|
2020-08-03 20:01:38 +00:00
|
|
|
|
|
|
|
import (
|
2020-12-02 14:03:39 +00:00
|
|
|
"bytes"
|
2020-08-06 22:48:28 +00:00
|
|
|
"encoding/json"
|
2020-08-03 20:01:38 +00:00
|
|
|
"fmt"
|
2020-11-14 11:25:14 +00:00
|
|
|
|
2020-11-23 16:53:44 +00:00
|
|
|
ftypes "github.com/Secured-Finance/dione/rpc/filecoin/types"
|
2020-11-18 18:33:03 +00:00
|
|
|
"github.com/Secured-Finance/dione/rpc/types"
|
2020-12-02 14:03:39 +00:00
|
|
|
"github.com/filecoin-project/go-address"
|
2020-11-18 18:33:03 +00:00
|
|
|
|
2020-11-14 11:25:14 +00:00
|
|
|
"github.com/sirupsen/logrus"
|
|
|
|
"github.com/valyala/fasthttp"
|
2020-08-03 20:01:38 +00:00
|
|
|
)
|
|
|
|
|
2020-11-23 16:53:44 +00:00
|
|
|
var filecoinURL = "https://api.node.glif.io/"
|
2020-11-14 11:25:14 +00:00
|
|
|
|
2020-11-23 16:53:44 +00:00
|
|
|
// client implements the `Client` interface.
|
2020-08-06 22:48:28 +00:00
|
|
|
type LotusClient struct {
|
2020-11-23 16:53:44 +00:00
|
|
|
host string
|
|
|
|
httpClient *fasthttp.Client
|
2020-08-03 20:01:38 +00:00
|
|
|
}
|
|
|
|
|
2020-11-23 16:53:44 +00:00
|
|
|
// NewClient returns a new client.
|
|
|
|
func NewLotusClient() *LotusClient {
|
2020-08-06 22:48:28 +00:00
|
|
|
return &LotusClient{
|
2020-11-23 16:53:44 +00:00
|
|
|
host: filecoinURL,
|
|
|
|
httpClient: &fasthttp.Client{},
|
2020-08-03 20:01:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-23 16:53:44 +00:00
|
|
|
func (c *LotusClient) GetBlock(cid string) ([]byte, error) {
|
|
|
|
i := ftypes.NewCidParam(cid)
|
|
|
|
return c.HandleRequest("Filecoin.ChainGetBlock", i)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *LotusClient) GetTipSetByHeight(chainEpoch int64) ([]byte, error) {
|
|
|
|
i := make([]interface{}, 0)
|
|
|
|
i = append(i, chainEpoch, nil)
|
|
|
|
return c.HandleRequest("Filecoin.ChainGetTipSetByHeight", i)
|
|
|
|
}
|
|
|
|
|
2020-12-02 14:03:39 +00:00
|
|
|
// func (c *LotusClient) GetTransaction(cid string) (string, error) {
|
|
|
|
// i := ftypes.NewCidParam(cid)
|
|
|
|
// resp, err := c.HandleRequest("Filecoin.ChainGetMessage", i)
|
|
|
|
// return string(resp), err
|
|
|
|
// }
|
2020-11-23 16:53:44 +00:00
|
|
|
|
|
|
|
func (c *LotusClient) GetNodeVersion() ([]byte, error) {
|
|
|
|
return c.HandleRequest("Filecoin.Version", nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *LotusClient) GetChainHead() ([]byte, error) {
|
|
|
|
return c.HandleRequest("Filecoin.ChainHead", nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *LotusClient) VerifyCid(cid string) ([]byte, error) {
|
|
|
|
i := ftypes.NewCidParam(cid)
|
|
|
|
return c.HandleRequest("Filecoin.ChainHasObj", i)
|
|
|
|
}
|
|
|
|
|
2020-12-02 14:03:39 +00:00
|
|
|
// Gets signed transaction from Filecoin and returns SignedTransaction struct in byte slice
|
|
|
|
func (c *LotusClient) GetTransaction(cid string) ([]byte, error) {
|
|
|
|
i := ftypes.NewCidParam(cid)
|
|
|
|
bodyBytes, err := c.HandleRequest("Filecoin.ChainReadObj", i)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("Failed to get object information %v", err)
|
|
|
|
}
|
|
|
|
var response types.RPCResponseBody
|
|
|
|
err = json.Unmarshal(bodyBytes, &response)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("Failed to unmarshal response body %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
var msg ftypes.SignedMessage
|
|
|
|
if err := msg.UnmarshalCBOR(bytes.NewReader(response.Result)); err != nil {
|
|
|
|
if err := msg.Message.UnmarshalCBOR(bytes.NewReader(response.Result)); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch msg.Message.From.Protocol() | msg.Message.To.Protocol() {
|
|
|
|
case address.BLS:
|
2020-12-02 14:18:45 +00:00
|
|
|
msg.Type = ftypes.MessageTypeBLS
|
2020-12-02 14:03:39 +00:00
|
|
|
case address.SECP256K1:
|
2020-12-02 14:18:45 +00:00
|
|
|
msg.Type = ftypes.MessageTypeSecp256k1
|
2020-12-02 14:03:39 +00:00
|
|
|
default:
|
|
|
|
return nil, fmt.Errorf("Address has unsupported protocol %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
b := new(bytes.Buffer)
|
|
|
|
if err := msg.MarshalCBOR(b); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return b.Bytes(), nil
|
|
|
|
}
|
|
|
|
|
2020-11-23 16:53:44 +00:00
|
|
|
// HandleRequest implements the `Client` interface.
|
|
|
|
func (c *LotusClient) HandleRequest(method string, params []interface{}) ([]byte, error) {
|
2020-11-14 11:25:14 +00:00
|
|
|
req := fasthttp.AcquireRequest()
|
|
|
|
req.SetRequestURI(c.host)
|
|
|
|
req.Header.SetMethod("POST")
|
|
|
|
req.Header.SetContentType("application/json")
|
2020-11-23 16:53:44 +00:00
|
|
|
requestBody := types.NewRPCRequestBody(method)
|
|
|
|
requestBody.Params = append(requestBody.Params, params...)
|
2020-08-06 22:48:28 +00:00
|
|
|
body, err := json.Marshal(requestBody)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("Failed to marshal request body %v", err)
|
|
|
|
}
|
2020-11-14 11:25:14 +00:00
|
|
|
req.AppendBody(body)
|
|
|
|
resp := fasthttp.AcquireResponse()
|
2020-11-18 18:33:03 +00:00
|
|
|
if err = c.httpClient.Do(req, resp); err != nil {
|
2020-11-14 11:25:14 +00:00
|
|
|
logrus.Warn("Failed to construct filecoin node rpc request", err)
|
|
|
|
return nil, err
|
2020-08-03 20:01:38 +00:00
|
|
|
}
|
2020-11-14 11:25:14 +00:00
|
|
|
bodyBytes := resp.Body()
|
2021-07-11 23:23:00 +00:00
|
|
|
logrus.Tracef("Filecoin RPC reply: %v", string(bodyBytes))
|
2020-11-18 18:33:03 +00:00
|
|
|
return bodyBytes, nil
|
2020-08-03 20:01:38 +00:00
|
|
|
}
|