OSDN Git Service

feat(federation): add address in /list-txs (#224)
authorHAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
Wed, 26 Jun 2019 10:19:15 +0000 (18:19 +0800)
committerPaladz <yzhu101@uottawa.ca>
Wed, 26 Jun 2019 10:19:15 +0000 (18:19 +0800)
* add addresses

* add add add

* main listener address

* sidechain listener address

* update docs

docs/federation/README-en.md
docs/federation/federation.sql
federation/synchron/mainchain_keeper.go
federation/synchron/sidechain_keeper.go
wallet/annotated.go

index 00eb5ac..ff5628f 100644 (file)
@@ -85,8 +85,6 @@ To list cross-chain transactions and filter the transactions.
 
 ##### Parameters
 
-<!--  -->
-
 Optional:
 
 - `Object` - *filter*, transactions filter.
@@ -107,16 +105,20 @@ Optional:
 
 - `String` - *source_chain_name*, source chain name of the cross-chain transaction.
 - `Integer` - *source_block_height*, block height of the cross-chain transaction on the source chain.
+- `Integer` - *source_block_timestamp*, block timestamp 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`.
+- `Integer` - *dest_block_timestamp*, block timestamp 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.
+    + `String` - *from_address*, source address.
+    + `String` - *to_address*, destination address.
     + `Object` - *asset*, asset detail.
         * `String` - *asset_id*, asset id string.
 
@@ -138,10 +140,12 @@ curl -X POST 127.0.0.1:3000/api/v1/federation/list-crosschain-txs -d '{}'
       {
         "source_chain_name":"bytom",
         "source_block_height":174,
+        "source_block_timestamp":1561457348,
         "source_block_hash":"569a3a5a43910ea634a947fd092bb3085359db451235ae59c20daab4e4b0d274",
         "source_tx_index":1,
         "source_tx_hash":"584d1dcc4dfe741bb3ae5b193896b08db469169e6fd76098eac132af628a3183",
         "dest_block_height":0,
+        "dest_block_timestamp":0,
         "dest_block_hash":"",
         "dest_tx_index":0,
         "dest_tx_hash":"",
@@ -149,6 +153,8 @@ curl -X POST 127.0.0.1:3000/api/v1/federation/list-crosschain-txs -d '{}'
         "crosschain_requests":[
           {
             "amount":1000000,
+            "from_address":"bm1qf872k7nr8pwjt4afx60m2wwz5hwj2tu4jaxm9g",
+            "to_address":"vp1qf872k7nr8pwjt4afx60m2wwz5hwj2tu4eukxq7",
             "asset":{
               "asset_id":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
             }
index dad8c5c..6e95bf2 100644 (file)
@@ -85,6 +85,8 @@ CREATE TABLE `cross_transaction_reqs` (
   `asset_id` int(11) NOT NULL,
   `asset_amount` bigint(20) DEFAULT '0',
   `script` varchar(128) NOT NULL,
+  `from_address` varchar(128) NOT NULL DEFAULT '',
+  `to_address` varchar(128) NOT NULL DEFAULT '',
   `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
   `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
   PRIMARY KEY (`id`),
index b777037..3b4da04 100644 (file)
@@ -7,12 +7,14 @@ import (
        "fmt"
        "time"
 
-       "github.com/bytom/consensus"
+       btmConsensus "github.com/bytom/consensus"
        btmBc "github.com/bytom/protocol/bc"
        "github.com/bytom/protocol/bc/types"
        "github.com/jinzhu/gorm"
        log "github.com/sirupsen/logrus"
 
+       vaporConsensus "github.com/vapor/consensus"
+       "github.com/vapor/consensus/segwit"
        "github.com/vapor/errors"
        "github.com/vapor/federation/common"
        "github.com/vapor/federation/config"
@@ -21,6 +23,7 @@ import (
        "github.com/vapor/federation/service"
        "github.com/vapor/federation/util"
        "github.com/vapor/protocol/bc"
+       "github.com/vapor/wallet"
 )
 
 type mainchainKeeper struct {
@@ -207,8 +210,23 @@ func (m *mainchainKeeper) processDepositTx(chain *orm.Chain, block *types.Block,
 }
 
 func (m *mainchainKeeper) getCrossChainReqs(crossTransactionID uint64, tx *types.Tx, statusFail bool) ([]*orm.CrossTransactionReq, error) {
+       var fromAddress, toAddress string
        // assume inputs are from an identical owner
-       script := hex.EncodeToString(tx.Inputs[0].ControlProgram())
+       prog := tx.Inputs[0].ControlProgram()
+       script := hex.EncodeToString(prog)
+       switch {
+       case segwit.IsP2WPKHScript(prog):
+               if pubHash, err := segwit.GetHashFromStandardProg(prog); err == nil {
+                       fromAddress = wallet.BuildP2PKHAddress(pubHash, &vaporConsensus.MainNetParams)
+                       toAddress = wallet.BuildP2PKHAddress(pubHash, &vaporConsensus.VaporNetParams)
+               }
+       case segwit.IsP2WSHScript(prog):
+               if scriptHash, err := segwit.GetHashFromStandardProg(prog); err == nil {
+                       fromAddress = wallet.BuildP2SHAddress(scriptHash, &vaporConsensus.MainNetParams)
+                       toAddress = wallet.BuildP2SHAddress(scriptHash, &vaporConsensus.VaporNetParams)
+               }
+       }
+
        reqs := []*orm.CrossTransactionReq{}
        for i, rawOutput := range tx.Outputs {
                // check valid deposit
@@ -216,7 +234,7 @@ func (m *mainchainKeeper) getCrossChainReqs(crossTransactionID uint64, tx *types
                        continue
                }
 
-               if statusFail && *rawOutput.OutputCommitment.AssetAmount.AssetId != *consensus.BTMAssetID {
+               if statusFail && *rawOutput.OutputCommitment.AssetAmount.AssetId != *btmConsensus.BTMAssetID {
                        continue
                }
 
@@ -231,6 +249,8 @@ func (m *mainchainKeeper) getCrossChainReqs(crossTransactionID uint64, tx *types
                        AssetID:            asset.ID,
                        AssetAmount:        rawOutput.OutputCommitment.AssetAmount.Amount,
                        Script:             script,
+                       FromAddress:        fromAddress,
+                       ToAddress:          toAddress,
                }
                reqs = append(reqs, req)
        }
index 0e28ec1..8c53816 100644 (file)
@@ -10,6 +10,7 @@ import (
        log "github.com/sirupsen/logrus"
 
        "github.com/vapor/consensus"
+       "github.com/vapor/consensus/segwit"
        "github.com/vapor/errors"
        "github.com/vapor/federation/common"
        "github.com/vapor/federation/config"
@@ -18,6 +19,7 @@ import (
        "github.com/vapor/federation/service"
        "github.com/vapor/protocol/bc"
        "github.com/vapor/protocol/bc/types"
+       "github.com/vapor/wallet"
 )
 
 type sidechainKeeper struct {
@@ -223,6 +225,19 @@ func (s *sidechainKeeper) processWithdrawalTx(chain *orm.Chain, block *types.Blo
 }
 
 func (s *sidechainKeeper) getCrossChainReqs(crossTransactionID uint64, tx *types.Tx, statusFail bool) ([]*orm.CrossTransactionReq, error) {
+       var fromAddress string
+       inputCP := tx.Inputs[0].ControlProgram()
+       switch {
+       case segwit.IsP2WPKHScript(inputCP):
+               if pubHash, err := segwit.GetHashFromStandardProg(inputCP); err == nil {
+                       fromAddress = wallet.BuildP2PKHAddress(pubHash, &consensus.VaporNetParams)
+               }
+       case segwit.IsP2WSHScript(inputCP):
+               if scriptHash, err := segwit.GetHashFromStandardProg(inputCP); err == nil {
+                       fromAddress = wallet.BuildP2SHAddress(scriptHash, &consensus.VaporNetParams)
+               }
+       }
+
        reqs := []*orm.CrossTransactionReq{}
        for i, rawOutput := range tx.Outputs {
                // check valid withdrawal
@@ -239,12 +254,27 @@ func (s *sidechainKeeper) getCrossChainReqs(crossTransactionID uint64, tx *types
                        return nil, err
                }
 
+               var toAddress string
+               outputCP := rawOutput.ControlProgram()
+               switch {
+               case segwit.IsP2WPKHScript(outputCP):
+                       if pubHash, err := segwit.GetHashFromStandardProg(outputCP); err == nil {
+                               toAddress = wallet.BuildP2PKHAddress(pubHash, &consensus.MainNetParams)
+                       }
+               case segwit.IsP2WSHScript(outputCP):
+                       if scriptHash, err := segwit.GetHashFromStandardProg(outputCP); err == nil {
+                               toAddress = wallet.BuildP2SHAddress(scriptHash, &consensus.MainNetParams)
+                       }
+               }
+
                req := &orm.CrossTransactionReq{
                        CrossTransactionID: crossTransactionID,
                        SourcePos:          uint64(i),
                        AssetID:            asset.ID,
                        AssetAmount:        rawOutput.OutputCommitment().AssetAmount.Amount,
                        Script:             hex.EncodeToString(rawOutput.ControlProgram()),
+                       FromAddress:        fromAddress,
+                       ToAddress:          toAddress,
                }
                reqs = append(reqs, req)
        }
index 746ac5a..db305e5 100644 (file)
@@ -220,18 +220,18 @@ func (w *Wallet) getAddressFromControlProgram(prog []byte, isMainchain bool) str
 
        if segwit.IsP2WPKHScript(prog) {
                if pubHash, err := segwit.GetHashFromStandardProg(prog); err == nil {
-                       return buildP2PKHAddress(pubHash, netParams)
+                       return BuildP2PKHAddress(pubHash, netParams)
                }
        } else if segwit.IsP2WSHScript(prog) {
                if scriptHash, err := segwit.GetHashFromStandardProg(prog); err == nil {
-                       return buildP2SHAddress(scriptHash, netParams)
+                       return BuildP2SHAddress(scriptHash, netParams)
                }
        }
 
        return ""
 }
 
-func buildP2PKHAddress(pubHash []byte, netParams *consensus.Params) string {
+func BuildP2PKHAddress(pubHash []byte, netParams *consensus.Params) string {
        address, err := common.NewAddressWitnessPubKeyHash(pubHash, netParams)
        if err != nil {
                return ""
@@ -240,7 +240,7 @@ func buildP2PKHAddress(pubHash []byte, netParams *consensus.Params) string {
        return address.EncodeAddress()
 }
 
-func buildP2SHAddress(scriptHash []byte, netParams *consensus.Params) string {
+func BuildP2SHAddress(scriptHash []byte, netParams *consensus.Params) string {
        address, err := common.NewAddressWitnessScriptHash(scriptHash, netParams)
        if err != nil {
                return ""