OSDN Git Service

doc(federation): add /list-crosschain-txs docs (#222)
authorHAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
Wed, 26 Jun 2019 06:57:31 +0000 (14:57 +0800)
committerPaladz <yzhu101@uottawa.ca>
Wed, 26 Jun 2019 06:57:31 +0000 (14:57 +0800)
* init

* add fed list-txs doc

* update

* refactor reponse

* update docs

docs/federation/README-en.md
federation/api/handler.go
federation/common/const.go
federation/database/orm/cross_transaction.go

index cbec063..907ee83 100644 (file)
@@ -46,3 +46,118 @@ A `fed_cfg.json` would look like this:
     }
 }
 ```
+## API
+A federation node can function as an api server for querying cross-chain transactions.
+
+The default JSON-RPC endpoint is: [http://host:port/api/v1/federation/](http://host:port/api/v1/federation/)
+
+The response contains some meta data of:
+
++ success/error status, which can be told from `code` and `msg`;
++ pagination info, which can be told from `start`, `limit` and `_links` (`_links` is used to look up the preceding and the succeeding items);
+
+and looks like:
+```
+{
+  "code":200,
+  "msg":"",
+  "result":{
+    "_links":{
+    },
+    "data":...,
+    "limit":10,
+    "start":0
+  }
+}
+```
+
+If a request succeed, `data` field contains the detailed result as an object or as an array of objects.
+
+### Pagination
+
+Append `?start=<integer>&limit=<integer>` to the url in order to use pagination.
+
+### Methods
+
+#### `/list-crosschain-txs`
+
+To list cross-chain transactions and filter the transactions.
+
+##### Parameters
+
+<!--  -->
+
+Optional:
+
+- `Object` - *filter*, transactions filter.
+    + Optional
+        * `String` - *status*, transactions status, which can be `pending` or `completed`.
+        * `String` - *from_chain*, transactions source chain, which can be `bytom` or `vapor`.
+        * `String` - *source_tx_hash*, souce transaction hash string.
+        * `String` - *dest_tx_hash*, destination transaction hash string.
+- `Object` - *sort*, transactions sorter.
+    + Optional
+        * `String` - *order*, transactions order sorter, which can be `asc` or `desc`.
+
+
+##### Returns
+
+
+`Object`:
+
+- `String` - *from_chain*, source chain name of the cross-chain transaction.
+- `Integer` - *source_block_height*, block height of the cross-chain transaction on the source chain.
+- `String` - *source_block_hash*, block hash of the cross-chain transaction on the source chain.
+- `Integer` - *source_tx_index*, transaction index in the source block.
+- `String` - *source_tx_hash*, source transaction hash.
+- `Integer` - *dest_block_height*, block height of the cross-chain transaction on the destination chain, `0` if `status` is `pending`.
+- `String` - *dest_block_hash*, block hash of the cross-chain transaction on the destination chain, empty string if `status` is `pending`.
+- `Integer` - *dest_tx_index*, transaction index in the destination block, `0` if `status` is `pending`.
+- `String` - *dest_tx_hash*, destination transaction hash, empty string if `status` is `pending`.
+- `String` - *status*, cross-chain transaction status, can be `pending` or `completed`.
+- `Array of objects` - *crosschain_requests*, asset transfer details per request included in the cross-chain transaction.
+    + `Integer` - *amount*, asset transfer amount.
+    + `Object` - *asset*, asset detail.
+        * `String` - *asset_id*, asset id string.
+
+##### Example
+
+```js
+// Request
+curl -X POST 127.0.0.1:3000/api/v1/federation/list-crosschain-txs -d '{}'
+
+// Result
+{
+  "code":200,
+  "msg":"",
+  "result":{
+    "_links":{
+
+    },
+    "data":[
+      {
+        "from_chain":"bytom",
+        "source_block_height":174,
+        "source_block_hash":"569a3a5a43910ea634a947fd092bb3085359db451235ae59c20daab4e4b0d274",
+        "source_tx_index":1,
+        "source_tx_hash":"584d1dcc4dfe741bb3ae5b193896b08db469169e6fd76098eac132af628a3183",
+        "dest_block_height":0,
+        "dest_block_hash":"",
+        "dest_tx_index":0,
+        "dest_tx_hash":"",
+        "status":"pending",
+        "crosschain_requests":[
+          {
+            "amount":1000000,
+            "asset":{
+              "asset_id":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+            }
+          }
+        ]
+      }
+    ],
+    "limit":10,
+    "start":0
+  }
+}
+```
index 0ea4b07..afd4bfb 100644 (file)
@@ -3,6 +3,7 @@ package api
 import (
        "database/sql"
        "fmt"
+       "strings"
 
        "github.com/gin-gonic/gin"
 
@@ -19,10 +20,10 @@ func (s *Server) ListCrosschainTxs(c *gin.Context, listTxsReq *listCrosschainTxs
 
        // filter tx status
        if status, err := listTxsReq.GetFilterString("status"); err == nil && status != "" {
-               switch status {
-               case "pending":
+               switch strings.ToLower(status) {
+               case common.CrossTxPendingStatusLabel:
                        txFilter.Status = common.CrossTxPendingStatus
-               case "completed":
+               case common.CrossTxCompletedStatusLabel:
                        txFilter.Status = common.CrossTxCompletedStatus
                }
        }
@@ -37,7 +38,7 @@ func (s *Server) ListCrosschainTxs(c *gin.Context, listTxsReq *listCrosschainTxs
 
        txQuery := s.db.Preload("Chain").Preload("Reqs").Preload("Reqs.Asset").Where(txFilter)
        // filter direction
-       if fromChainName, err := listTxsReq.GetFilterString("from"); err == nil && fromChainName != "" {
+       if fromChainName, err := listTxsReq.GetFilterString("from_chain"); err == nil && fromChainName != "" {
                txQuery = txQuery.Joins("join chains on chains.id = cross_transactions.chain_id").Where("chains.name = ?", fromChainName)
        }
        txQuery = txQuery.Order(fmt.Sprintf("cross_transactions.source_block_height %s", listTxsReq.Sorter.Order))
index 9402031..56f7d0b 100644 (file)
@@ -5,3 +5,8 @@ const (
        CrossTxPendingStatus
        CrossTxCompletedStatus
 )
+
+const (
+       CrossTxPendingStatusLabel   = "pending"
+       CrossTxCompletedStatusLabel = "completed"
+)
index 9a70d9e..4a327b8 100644 (file)
@@ -2,27 +2,68 @@ package orm
 
 import (
        "database/sql"
+       "encoding/json"
 
+       "github.com/vapor/errors"
+       "github.com/vapor/federation/common"
        "github.com/vapor/federation/types"
 )
 
 type CrossTransaction struct {
-       ID                   uint64          `gorm:"primary_key" json:"-"`
-       ChainID              uint64          `json:"-"`
-       SourceBlockHeight    uint64          `json:"source_block_height"`
-       SourceBlockHash      string          `json:"source_block_hash"`
-       SourceTxIndex        uint64          `json:"source_tx_index"`
-       SourceMuxID          string          `json:"-"`
-       SourceTxHash         string          `json:"source_tx_hash"`
-       SourceRawTransaction string          `json:"-"`
-       DestBlockHeight      sql.NullInt64   `sql:"default:null" json:"dest_block_height"`
-       DestBlockHash        sql.NullString  `sql:"default:null" json:"dest_block_hash"`
-       DestTxIndex          sql.NullInt64   `sql:"default:null" json:"dest_tx_index"`
-       DestTxHash           sql.NullString  `sql:"default:null" json:"dest_tx_hash"`
-       Status               uint8           `json:"status"`
-       CreatedAt            types.Timestamp `json:"-"`
-       UpdatedAt            types.Timestamp `json:"-"`
+       ID                   uint64 `gorm:"primary_key"`
+       ChainID              uint64
+       SourceBlockHeight    uint64
+       SourceBlockHash      string
+       SourceTxIndex        uint64
+       SourceMuxID          string
+       SourceTxHash         string
+       SourceRawTransaction string
+       DestBlockHeight      sql.NullInt64  `sql:"default:null"`
+       DestBlockHash        sql.NullString `sql:"default:null"`
+       DestTxIndex          sql.NullInt64  `sql:"default:null"`
+       DestTxHash           sql.NullString `sql:"default:null"`
+       Status               uint8
+       CreatedAt            types.Timestamp
+       UpdatedAt            types.Timestamp
 
-       Chain *Chain                 `gorm:"foreignkey:ChainID" json:"-"`
-       Reqs  []*CrossTransactionReq `json:"crosschain_requests"`
+       Chain *Chain `gorm:"foreignkey:ChainID"`
+       Reqs  []*CrossTransactionReq
+}
+
+func (c *CrossTransaction) MarshalJSON() ([]byte, error) {
+       var status string
+       switch c.Status {
+       case common.CrossTxPendingStatus:
+               status = common.CrossTxPendingStatusLabel
+       case common.CrossTxCompletedStatus:
+               status = common.CrossTxCompletedStatusLabel
+       default:
+               return nil, errors.New("unknown cross-chain tx status")
+       }
+
+       return json.Marshal(&struct {
+               FromChain         string                 `json:"from_chain"`
+               SourceBlockHeight uint64                 `json:"source_block_height"`
+               SourceBlockHash   string                 `json:"source_block_hash"`
+               SourceTxIndex     uint64                 `json:"source_tx_index"`
+               SourceTxHash      string                 `json:"source_tx_hash"`
+               DestBlockHeight   uint64                 `json:"dest_block_height"`
+               DestBlockHash     string                 `json:"dest_block_hash"`
+               DestTxIndex       uint64                 `json:"dest_tx_index"`
+               DestTxHash        string                 `json:"dest_tx_hash"`
+               Status            string                 `json:"status"`
+               Reqs              []*CrossTransactionReq `json:"crosschain_requests"`
+       }{
+               FromChain:         c.Chain.Name,
+               SourceBlockHeight: c.SourceBlockHeight,
+               SourceBlockHash:   c.SourceBlockHash,
+               SourceTxIndex:     c.SourceTxIndex,
+               SourceTxHash:      c.SourceTxHash,
+               DestBlockHeight:   uint64(c.DestBlockHeight.Int64),
+               DestBlockHash:     c.DestBlockHash.String,
+               DestTxIndex:       uint64(c.DestTxIndex.Int64),
+               DestTxHash:        c.DestTxHash.String,
+               Status:            status,
+               Reqs:              c.Reqs,
+       })
 }