OSDN Git Service

extract api from blockchain (#478)
authorYongfeng LI <wliyongfeng@gmail.com>
Sat, 24 Mar 2018 08:19:44 +0000 (16:19 +0800)
committerPaladz <yzhu101@uottawa.ca>
Sat, 24 Mar 2018 08:19:44 +0000 (16:19 +0800)
26 files changed:
api/accesstokens.go [moved from blockchain/accesstokens.go with 98% similarity]
api/accounts.go [moved from blockchain/accounts.go with 99% similarity]
api/api.go [moved from blockchain/api.go with 96% similarity]
api/assets.go [moved from blockchain/assets.go with 98% similarity]
api/blockchain_reactor.go [new file with mode: 0644]
api/errors.go [moved from blockchain/errors.go with 99% similarity]
api/hsm.go [moved from blockchain/hsm.go with 99% similarity]
api/metrics.go [moved from blockchain/metrics.go with 98% similarity]
api/miner.go [new file with mode: 0644]
api/query.go [moved from blockchain/query.go with 99% similarity]
api/receivers.go [moved from blockchain/receivers.go with 97% similarity]
api/request.go [moved from blockchain/request.go with 98% similarity]
api/transact.go [new file with mode: 0644]
api/transact_test.go [moved from blockchain/transact_test.go with 99% similarity]
api/txfeeds.go [new file with mode: 0644]
api/types.go
api/wallet.go [moved from blockchain/wallet.go with 98% similarity]
blockchain/blockchain_reactor.go
blockchain/miner.go
blockchain/transact.go
blockchain/txfeeds.go
cmd/bytomcli/commands/key.go
cmd/bytomcli/commands/transaction.go
cmd/miner/main.go
node/node.go
util/util.go

similarity index 98%
rename from blockchain/accesstokens.go
rename to api/accesstokens.go
index 7ca971f..3754e09 100644 (file)
@@ -1,4 +1,4 @@
-package blockchain
+package api
 
 import (
        "context"
similarity index 99%
rename from blockchain/accounts.go
rename to api/accounts.go
index 42269d8..071fe0e 100644 (file)
@@ -1,4 +1,4 @@
-package blockchain
+package api
 
 import (
        "context"
similarity index 96%
rename from blockchain/api.go
rename to api/api.go
index 4da6e4e..2ddd718 100644 (file)
@@ -1,4 +1,4 @@
-package blockchain
+package api
 
 import (
        "crypto/tls"
@@ -12,6 +12,7 @@ import (
        cmn "github.com/tendermint/tmlibs/common"
 
        "github.com/bytom/accesstoken"
+       "github.com/bytom/blockchain"
        cfg "github.com/bytom/config"
        "github.com/bytom/dashboard"
        "github.com/bytom/errors"
@@ -32,7 +33,8 @@ const (
        // SUCCESS indicates the rpc calling is successful.
        SUCCESS = "success"
        // FAIL indicated the rpc calling is failed.
-       FAIL = "fail"
+       FAIL               = "fail"
+       crosscoreRPCPrefix = "/rpc/"
 )
 
 // Response describes the response standard.
@@ -68,7 +70,7 @@ func (wh *waitHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
 }
 
 type API struct {
-       bcr     *BlockchainReactor
+       bcr     *blockchain.BlockchainReactor
        wallet  *wallet.Wallet
        chain   *protocol.Chain
        server  *http.Server
@@ -126,11 +128,11 @@ func (a *API) StartServer(address string) {
        }()
 }
 
-func NewAPI(bcr *BlockchainReactor, config *cfg.Config) *API {
+func NewAPI(bcr *blockchain.BlockchainReactor, wallet *wallet.Wallet, chain *protocol.Chain, config *cfg.Config) *API {
        api := &API{
                bcr:    bcr,
-               wallet: bcr.wallet,
-               chain:  bcr.chain,
+               wallet: wallet,
+               chain:  chain,
        }
        api.buildHandler()
        api.initServer(config)
similarity index 98%
rename from blockchain/assets.go
rename to api/assets.go
index e16480e..ff18e84 100644 (file)
@@ -1,4 +1,4 @@
-package blockchain
+package api
 
 import (
        "context"
diff --git a/api/blockchain_reactor.go b/api/blockchain_reactor.go
new file mode 100644 (file)
index 0000000..20972a9
--- /dev/null
@@ -0,0 +1,185 @@
+package api
+
+import (
+       log "github.com/sirupsen/logrus"
+
+       "github.com/bytom/blockchain/query"
+       "github.com/bytom/wallet"
+       "github.com/bytom/consensus"
+       "github.com/bytom/consensus/difficulty"
+       chainjson "github.com/bytom/encoding/json"
+       "github.com/bytom/protocol/bc"
+       "github.com/bytom/protocol/bc/types"
+)
+
+// return network infomation
+func (a *API) getNetInfo() Response {
+       return NewSuccessResponse(a.bcr.GetNodeInfo())
+}
+
+// return best block hash
+func (a *API) getBestBlockHash() Response {
+       blockHash := map[string]string{"blockHash": a.chain.BestBlockHash().String()}
+       return NewSuccessResponse(blockHash)
+}
+
+// return block header by hash
+func (a *API) getBlockHeaderByHash(strHash string) Response {
+       hash := bc.Hash{}
+       if err := hash.UnmarshalText([]byte(strHash)); err != nil {
+               log.WithField("error", err).Error("Error occurs when transforming string hash to hash struct")
+               return NewErrorResponse(err)
+       }
+       block, err := a.chain.GetBlockByHash(&hash)
+       if err != nil {
+               log.WithField("error", err).Error("Fail to get block by hash")
+               return NewErrorResponse(err)
+       }
+
+       bcBlock := types.MapBlock(block)
+       return NewSuccessResponse(bcBlock.BlockHeader)
+}
+
+// BlockTx is the tx struct for getBlock func
+type BlockTx struct {
+       ID         bc.Hash                  `json:"id"`
+       Version    uint64                   `json:"version"`
+       Size       uint64                   `json:"size"`
+       TimeRange  uint64                   `json:"time_range"`
+       Inputs     []*query.AnnotatedInput  `json:"inputs"`
+       Outputs    []*query.AnnotatedOutput `json:"outputs"`
+       StatusFail bool                     `json:"status_fail"`
+}
+
+// GetBlockReq is used to handle getBlock req
+type GetBlockReq struct {
+       BlockHeight uint64             `json:"block_height"`
+       BlockHash   chainjson.HexBytes `json:"block_hash"`
+}
+
+// GetBlockResp is the resp for getBlock api
+type GetBlockResp struct {
+       Hash                   *bc.Hash   `json:"hash"`
+       Size                   uint64     `json:"size"`
+       Version                uint64     `json:"version"`
+       Height                 uint64     `json:"height"`
+       PreviousBlockHash      *bc.Hash   `json:"previous_block_hash"`
+       Timestamp              uint64     `json:"timestamp"`
+       Nonce                  uint64     `json:"nonce"`
+       Bits                   uint64     `json:"bits"`
+       Difficulty             string     `json:"difficulty"`
+       TransactionsMerkleRoot *bc.Hash   `json:"transaction_merkle_root"`
+       TransactionStatusHash  *bc.Hash   `json:"transaction_status_hash"`
+       Transactions           []*BlockTx `json:"transactions"`
+}
+
+// return block by hash
+func (a *API) getBlock(ins GetBlockReq) Response {
+       var err error
+       block := &types.Block{}
+       if len(ins.BlockHash) == 32 {
+               b32 := [32]byte{}
+               copy(b32[:], ins.BlockHash)
+               hash := bc.NewHash(b32)
+               block, err = a.chain.GetBlockByHash(&hash)
+       } else {
+               block, err = a.chain.GetBlockByHeight(ins.BlockHeight)
+       }
+       if err != nil {
+               return NewErrorResponse(err)
+       }
+
+       blockHash := block.Hash()
+       txStatus, err := a.chain.GetTransactionStatus(&blockHash)
+       rawBlock, err := block.MarshalText()
+       if err != nil {
+               return NewErrorResponse(err)
+       }
+
+       resp := &GetBlockResp{
+               Hash:                   &blockHash,
+               Size:                   uint64(len(rawBlock)),
+               Version:                block.Version,
+               Height:                 block.Height,
+               PreviousBlockHash:      &block.PreviousBlockHash,
+               Timestamp:              block.Timestamp,
+               Nonce:                  block.Nonce,
+               Bits:                   block.Bits,
+               Difficulty:             difficulty.CompactToBig(block.Bits).String(),
+               TransactionsMerkleRoot: &block.TransactionsMerkleRoot,
+               TransactionStatusHash:  &block.TransactionStatusHash,
+               Transactions:           []*BlockTx{},
+       }
+
+       for i, orig := range block.Transactions {
+               tx := &BlockTx{
+                       ID:        orig.ID,
+                       Version:   orig.Version,
+                       Size:      orig.SerializedSize,
+                       TimeRange: orig.TimeRange,
+                       Inputs:    []*query.AnnotatedInput{},
+                       Outputs:   []*query.AnnotatedOutput{},
+               }
+               tx.StatusFail, err = txStatus.GetStatus(i)
+               if err != nil {
+                       NewSuccessResponse(resp)
+               }
+
+               for i := range orig.Inputs {
+                       tx.Inputs = append(tx.Inputs, wallet.BuildAnnotatedInput(orig, uint32(i)))
+               }
+               for i := range orig.Outputs {
+                       tx.Outputs = append(tx.Outputs, wallet.BuildAnnotatedOutput(orig, i))
+               }
+               resp.Transactions = append(resp.Transactions, tx)
+       }
+       return NewSuccessResponse(resp)
+}
+
+// return block transactions count by hash
+func (a *API) getBlockTransactionsCountByHash(strHash string) Response {
+       hash := bc.Hash{}
+       if err := hash.UnmarshalText([]byte(strHash)); err != nil {
+               log.WithField("error", err).Error("Error occurs when transforming string hash to hash struct")
+               return NewErrorResponse(err)
+       }
+
+       legacyBlock, err := a.chain.GetBlockByHash(&hash)
+       if err != nil {
+               log.WithField("error", err).Error("Fail to get block by hash")
+               return NewErrorResponse(err)
+       }
+
+       count := map[string]int{"count": len(legacyBlock.Transactions)}
+       return NewSuccessResponse(count)
+}
+
+// return block transactions count by height
+func (a *API) getBlockTransactionsCountByHeight(height uint64) Response {
+       legacyBlock, err := a.chain.GetBlockByHeight(height)
+       if err != nil {
+               log.WithField("error", err).Error("Fail to get block by hash")
+               return NewErrorResponse(err)
+       }
+
+       count := map[string]int{"count": len(legacyBlock.Transactions)}
+       return NewSuccessResponse(count)
+}
+
+// return current block count
+func (a *API) getBlockCount() Response {
+       blockHeight := map[string]uint64{"block_count": a.chain.Height()}
+       return NewSuccessResponse(blockHeight)
+}
+
+// return is in mining or not
+func (a *API) isMining() Response {
+       IsMining := map[string]bool{"isMining": a.bcr.IsMining()}
+       return NewSuccessResponse(IsMining)
+}
+
+// return gasRate
+func (a *API) gasRate() Response {
+       gasrate := map[string]int64{"gasRate": consensus.VMGasRate}
+       return NewSuccessResponse(gasrate)
+}
similarity index 99%
rename from blockchain/errors.go
rename to api/errors.go
index 1a0909c..9d617a1 100644 (file)
@@ -1,4 +1,4 @@
-package blockchain
+package api
 
 import (
        "context"
similarity index 99%
rename from blockchain/hsm.go
rename to api/hsm.go
index 36635af..694073e 100644 (file)
@@ -1,4 +1,4 @@
-package blockchain
+package api
 
 import (
        "context"
similarity index 98%
rename from blockchain/metrics.go
rename to api/metrics.go
index 202364c..3ead8a7 100644 (file)
@@ -1,4 +1,4 @@
-package blockchain
+package api
 
 import (
        "expvar"
diff --git a/api/miner.go b/api/miner.go
new file mode 100644 (file)
index 0000000..9bafba4
--- /dev/null
@@ -0,0 +1,34 @@
+package api
+
+import (
+       "context"
+
+       "github.com/bytom/protocol/bc/types"
+)
+
+func (a *API) getWork() Response {
+       work, err := a.bcr.GetWork()
+       if err != nil {
+               return NewErrorResponse(err)
+       }
+       return NewSuccessResponse(work)
+}
+
+func (a *API) submitWork(bh *types.BlockHeader) Response {
+       return NewSuccessResponse(a.bcr.SubmitWork(bh))
+}
+
+func (a *API) getBlockHeaderByHeight(ctx context.Context, req struct {
+       Height uint64 `json:"block_height"`
+}) Response {
+       block, err := a.chain.GetBlockByHeight(req.Height)
+       if err != nil {
+               return NewErrorResponse(err)
+       }
+
+       resp := &BlockHeaderByHeight{
+               BlockHeader: &block.BlockHeader,
+               Reward:      block.Transactions[0].Outputs[0].Amount,
+       }
+       return NewSuccessResponse(resp)
+}
similarity index 99%
rename from blockchain/query.go
rename to api/query.go
index 364da93..defcaee 100755 (executable)
@@ -1,4 +1,4 @@
-package blockchain
+package api
 
 import (
        "context"
similarity index 97%
rename from blockchain/receivers.go
rename to api/receivers.go
index 04c8f5c..a7dfcab 100755 (executable)
@@ -1,4 +1,4 @@
-package blockchain
+package api
 
 import (
        "context"
similarity index 98%
rename from blockchain/request.go
rename to api/request.go
index 843a381..60980b6 100644 (file)
@@ -1,4 +1,4 @@
-package blockchain
+package api
 
 import (
        "context"
diff --git a/api/transact.go b/api/transact.go
new file mode 100644 (file)
index 0000000..58b9652
--- /dev/null
@@ -0,0 +1,187 @@
+package api
+
+import (
+       "context"
+       "encoding/json"
+       "fmt"
+       "time"
+
+       log "github.com/sirupsen/logrus"
+
+       "github.com/bytom/blockchain/txbuilder"
+       "github.com/bytom/errors"
+       "github.com/bytom/net/http/reqid"
+       "github.com/bytom/protocol/bc"
+       "github.com/bytom/protocol/bc/types"
+)
+
+var defaultTxTTL = 5 * time.Minute
+
+func (a *API) actionDecoder(action string) (func([]byte) (txbuilder.Action, error), bool) {
+       var decoder func([]byte) (txbuilder.Action, error)
+       switch action {
+       case "control_account":
+               decoder = a.wallet.AccountMgr.DecodeControlAction
+       case "control_address":
+               decoder = txbuilder.DecodeControlAddressAction
+       case "control_program":
+               decoder = txbuilder.DecodeControlProgramAction
+       case "control_receiver":
+               decoder = txbuilder.DecodeControlReceiverAction
+       case "issue":
+               decoder = a.wallet.AssetReg.DecodeIssueAction
+       case "retire":
+               decoder = txbuilder.DecodeRetireAction
+       case "spend_account":
+               decoder = a.wallet.AccountMgr.DecodeSpendAction
+       case "spend_account_unspent_output":
+               decoder = a.wallet.AccountMgr.DecodeSpendUTXOAction
+       default:
+               return nil, false
+       }
+       return decoder, true
+}
+
+func mergeActions(req *BuildRequest) []map[string]interface{} {
+       actions := make([]map[string]interface{}, 0)
+       actionMap := make(map[string]map[string]interface{})
+
+       for _, m := range req.Actions {
+               if actionType := m["type"].(string); actionType != "spend_account" {
+                       actions = append(actions, m)
+                       continue
+               }
+
+               actionKey := m["asset_id"].(string) + m["account_id"].(string)
+               amountNumber := m["amount"].(json.Number)
+               amount, _ := amountNumber.Int64()
+
+               if tmpM, ok := actionMap[actionKey]; ok {
+                       tmpNumber, _ := tmpM["amount"].(json.Number)
+                       tmpAmount, _ := tmpNumber.Int64()
+                       tmpM["amount"] = json.Number(fmt.Sprintf("%v", tmpAmount+amount))
+               } else {
+                       actionMap[actionKey] = m
+                       actions = append(actions, m)
+               }
+       }
+
+       return actions
+}
+
+func (a *API) buildSingle(ctx context.Context, req *BuildRequest) (*txbuilder.Template, error) {
+       err := a.filterAliases(ctx, req)
+       if err != nil {
+               return nil, err
+       }
+       reqActions := mergeActions(req)
+       actions := make([]txbuilder.Action, 0, len(reqActions))
+       for i, act := range reqActions {
+               typ, ok := act["type"].(string)
+               if !ok {
+                       return nil, errors.WithDetailf(errBadActionType, "no action type provided on action %d", i)
+               }
+               decoder, ok := a.actionDecoder(typ)
+               if !ok {
+                       return nil, errors.WithDetailf(errBadActionType, "unknown action type %q on action %d", typ, i)
+               }
+
+               // Remarshal to JSON, the action may have been modified when we
+               // filtered aliases.
+               b, err := json.Marshal(act)
+               if err != nil {
+                       return nil, err
+               }
+               action, err := decoder(b)
+               if err != nil {
+                       return nil, errors.WithDetailf(errBadAction, "%s on action %d", err.Error(), i)
+               }
+               actions = append(actions, action)
+       }
+
+       ttl := req.TTL.Duration
+       if ttl == 0 {
+               ttl = defaultTxTTL
+       }
+       maxTime := time.Now().Add(ttl)
+
+       tpl, err := txbuilder.Build(ctx, req.Tx, actions, maxTime, req.TimeRange)
+       if errors.Root(err) == txbuilder.ErrAction {
+               // append each of the inner errors contained in the data.
+               var Errs string
+               for _, innerErr := range errors.Data(err)["actions"].([]error) {
+                       Errs = Errs + "<" + innerErr.Error() + ">"
+               }
+               err = errors.New(err.Error() + "-" + Errs)
+       }
+       if err != nil {
+               return nil, err
+       }
+
+       // ensure null is never returned for signing instructions
+       if tpl.SigningInstructions == nil {
+               tpl.SigningInstructions = []*txbuilder.SigningInstruction{}
+       }
+       return tpl, nil
+}
+
+// POST /build-transaction
+func (a *API) build(ctx context.Context, buildReqs *BuildRequest) Response {
+       subctx := reqid.NewSubContext(ctx, reqid.New())
+
+       tmpl, err := a.buildSingle(subctx, buildReqs)
+       if err != nil {
+               return NewErrorResponse(err)
+       }
+
+       return NewSuccessResponse(tmpl)
+}
+
+func (a *API) submitSingle(ctx context.Context, tpl *txbuilder.Template) (map[string]string, error) {
+       if tpl.Transaction == nil {
+               return nil, errors.Wrap(txbuilder.ErrMissingRawTx)
+       }
+
+       if err := txbuilder.FinalizeTx(ctx, a.chain, tpl.Transaction); err != nil {
+               return nil, errors.Wrapf(err, "tx %s", tpl.Transaction.ID.String())
+       }
+
+       return map[string]string{"tx_id": tpl.Transaction.ID.String()}, nil
+}
+
+type submitTxResp struct {
+       TxID *bc.Hash `json:"tx_id"`
+}
+
+// POST /submit-transaction
+func (a *API) submit(ctx context.Context, ins struct {
+       Tx types.Tx `json:"raw_transaction"`
+}) Response {
+       if err := txbuilder.FinalizeTx(ctx, a.chain, &ins.Tx); err != nil {
+               return NewErrorResponse(err)
+       }
+
+       log.WithField("tx_id", ins.Tx.ID).Info("submit single tx")
+       return NewSuccessResponse(&submitTxResp{TxID: &ins.Tx.ID})
+}
+
+// POST /sign-submit-transaction
+func (a *API) signSubmit(ctx context.Context, x struct {
+       Password []string           `json:"password"`
+       Txs      txbuilder.Template `json:"transaction"`
+}) Response {
+       if err := txbuilder.Sign(ctx, &x.Txs, nil, x.Password[0], a.pseudohsmSignTemplate); err != nil {
+               log.WithField("build err", err).Error("fail on sign transaction.")
+               return NewErrorResponse(err)
+       }
+       log.Info("Sign Transaction complete.")
+
+       txID, err := a.submitSingle(nil, &x.Txs)
+       if err != nil {
+               log.WithField("err", err).Error("submit single tx")
+               return NewErrorResponse(err)
+       }
+
+       log.WithField("tx_id", txID["tx_id"]).Info("submit single tx")
+       return NewSuccessResponse(txID)
+}
similarity index 99%
rename from blockchain/transact_test.go
rename to api/transact_test.go
index dfd6bd6..0b40079 100644 (file)
@@ -1,4 +1,4 @@
-package blockchain
+package api
 
 import (
        "encoding/json"
diff --git a/api/txfeeds.go b/api/txfeeds.go
new file mode 100644 (file)
index 0000000..c115336
--- /dev/null
@@ -0,0 +1,92 @@
+package api
+
+import (
+       "context"
+       "encoding/json"
+
+       log "github.com/sirupsen/logrus"
+
+       "github.com/bytom/blockchain/txfeed"
+)
+
+// POST /create-txfeed
+func (a *API) createTxFeed(ctx context.Context, in struct {
+       Alias  string `json:"alias"`
+       Filter string `json:"filter"`
+}) Response {
+       if err := a.bcr.TxFeedTracker.Create(ctx, in.Alias, in.Filter); err != nil {
+               log.WithField("error", err).Error("Add TxFeed Failed")
+               return NewErrorResponse(err)
+       }
+       return NewSuccessResponse(nil)
+}
+
+// POST /get-transaction-feed
+func (a *API) getTxFeed(ctx context.Context, in struct {
+       Alias string `json:"alias,omitempty"`
+}) Response {
+       var tmpTxFeed interface{}
+       rawTxfeed, err := a.bcr.GetTxFeedByAlias(ctx, in.Alias)
+       if err != nil {
+               return NewErrorResponse(err)
+       }
+       err = json.Unmarshal(rawTxfeed, &tmpTxFeed)
+       if err != nil {
+               return NewErrorResponse(err)
+       }
+       data := map[string]interface{}{"txfeed": tmpTxFeed}
+       return NewSuccessResponse(data)
+}
+
+// POST /delete-transaction-feed
+func (a *API) deleteTxFeed(ctx context.Context, in struct {
+       Alias string `json:"alias,omitempty"`
+}) Response {
+       if err := a.bcr.TxFeedTracker.Delete(ctx, in.Alias); err != nil {
+               return NewErrorResponse(err)
+       }
+       return NewSuccessResponse(nil)
+}
+
+// POST /update-transaction-feed
+func (a *API) updateTxFeed(ctx context.Context, in struct {
+       Alias  string `json:"alias"`
+       Filter string `json:"filter"`
+}) Response {
+       if err := a.bcr.TxFeedTracker.Delete(ctx, in.Alias); err != nil {
+               return NewErrorResponse(err)
+       }
+       if err := a.bcr.TxFeedTracker.Create(ctx, in.Alias, in.Filter); err != nil {
+               log.WithField("error", err).Error("Update TxFeed Failed")
+               return NewErrorResponse(err)
+       }
+       return NewSuccessResponse(nil)
+}
+
+func (a *API) getTxFeeds() ([]txfeed.TxFeed, error) {
+       txFeed := txfeed.TxFeed{}
+       txFeeds := make([]txfeed.TxFeed, 0)
+
+       iter := a.bcr.TxFeedTracker.DB.Iterator()
+       defer iter.Release()
+
+       for iter.Next() {
+               if err := json.Unmarshal(iter.Value(), &txFeed); err != nil {
+                       return nil, err
+               }
+               txFeeds = append(txFeeds, txFeed)
+       }
+
+       return txFeeds, nil
+}
+
+// listTxFeeds is an http handler for listing txfeeds. It does not take a filter.
+// POST /list-transaction-feeds
+func (a *API) listTxFeeds(ctx context.Context) Response {
+       txFeeds, err := a.getTxFeeds()
+       if err != nil {
+               return NewErrorResponse(err)
+       }
+
+       return NewSuccessResponse(txFeeds)
+}
index b7a5218..72f6ace 100644 (file)
@@ -1,7 +1,6 @@
 package api
 
 import (
-       "github.com/bytom/protocol/bc"
        "github.com/bytom/protocol/bc/types"
 )
 
@@ -10,18 +9,3 @@ type BlockHeaderByHeight struct {
        BlockHeader *types.BlockHeader `json:"block_header"`
        Reward      uint64             `json:"reward"`
 }
-
-// GetWorkResp is resp struct for API
-type GetWorkResp struct {
-       BlockHeader *types.BlockHeader `json:"block_header"`
-       Seed        *bc.Hash           `json:"seed"`
-}
-
-type NetInfo struct {
-       Listening    bool   `json:"listening"`
-       Syncing      bool   `json:"syncing"`
-       Mining       bool   `json:"mining"`
-       PeerCount    int    `json:"peer_count"`
-       CurrentBlock uint64 `json:"current_block"`
-       HighestBlock uint64 `json:"highest_block"`
-}
similarity index 98%
rename from blockchain/wallet.go
rename to api/wallet.go
index faee816..1519170 100644 (file)
@@ -1,4 +1,4 @@
-package blockchain
+package api
 
 import (
        "bytes"
index 4108efe..19f9dda 100644 (file)
@@ -1,20 +1,16 @@
 package blockchain
 
-import (
-       log "github.com/sirupsen/logrus"
-
-       "github.com/bytom/api"
-       "github.com/bytom/blockchain/query"
-       "github.com/bytom/wallet"
-       "github.com/bytom/consensus"
-       "github.com/bytom/consensus/difficulty"
-       chainjson "github.com/bytom/encoding/json"
-       "github.com/bytom/protocol/bc"
-       "github.com/bytom/protocol/bc/types"
-)
+type NetInfo struct {
+       Listening    bool   `json:"listening"`
+       Syncing      bool   `json:"syncing"`
+       Mining       bool   `json:"mining"`
+       PeerCount    int    `json:"peer_count"`
+       CurrentBlock uint64 `json:"current_block"`
+       HighestBlock uint64 `json:"highest_block"`
+}
 
-func (bcr *BlockchainReactor) GetNodeInfo() *api.NetInfo {
-       return &api.NetInfo{
+func (bcr *BlockchainReactor) GetNodeInfo() *NetInfo {
+       return &NetInfo{
                Listening:    bcr.sw.IsListening(),
                Syncing:      bcr.blockKeeper.IsCaughtUp(),
                Mining:       bcr.mining.IsMining(),
@@ -27,175 +23,3 @@ func (bcr *BlockchainReactor) GetNodeInfo() *api.NetInfo {
 func (bcr *BlockchainReactor) IsMining() bool {
        return bcr.mining.IsMining()
 }
-
-// return network infomation
-func (a *API) getNetInfo() Response {
-       return NewSuccessResponse(a.bcr.GetNodeInfo())
-}
-
-// return best block hash
-func (a *API) getBestBlockHash() Response {
-       blockHash := map[string]string{"blockHash": a.chain.BestBlockHash().String()}
-       return NewSuccessResponse(blockHash)
-}
-
-// return block header by hash
-func (a *API) getBlockHeaderByHash(strHash string) Response {
-       hash := bc.Hash{}
-       if err := hash.UnmarshalText([]byte(strHash)); err != nil {
-               log.WithField("error", err).Error("Error occurs when transforming string hash to hash struct")
-               return NewErrorResponse(err)
-       }
-       block, err := a.chain.GetBlockByHash(&hash)
-       if err != nil {
-               log.WithField("error", err).Error("Fail to get block by hash")
-               return NewErrorResponse(err)
-       }
-
-       bcBlock := types.MapBlock(block)
-       return NewSuccessResponse(bcBlock.BlockHeader)
-}
-
-// BlockTx is the tx struct for getBlock func
-type BlockTx struct {
-       ID         bc.Hash                  `json:"id"`
-       Version    uint64                   `json:"version"`
-       Size       uint64                   `json:"size"`
-       TimeRange  uint64                   `json:"time_range"`
-       Inputs     []*query.AnnotatedInput  `json:"inputs"`
-       Outputs    []*query.AnnotatedOutput `json:"outputs"`
-       StatusFail bool                     `json:"status_fail"`
-}
-
-// GetBlockReq is used to handle getBlock req
-type GetBlockReq struct {
-       BlockHeight uint64             `json:"block_height"`
-       BlockHash   chainjson.HexBytes `json:"block_hash"`
-}
-
-// GetBlockResp is the resp for getBlock api
-type GetBlockResp struct {
-       Hash                   *bc.Hash   `json:"hash"`
-       Size                   uint64     `json:"size"`
-       Version                uint64     `json:"version"`
-       Height                 uint64     `json:"height"`
-       PreviousBlockHash      *bc.Hash   `json:"previous_block_hash"`
-       Timestamp              uint64     `json:"timestamp"`
-       Nonce                  uint64     `json:"nonce"`
-       Bits                   uint64     `json:"bits"`
-       Difficulty             string     `json:"difficulty"`
-       TransactionsMerkleRoot *bc.Hash   `json:"transaction_merkle_root"`
-       TransactionStatusHash  *bc.Hash   `json:"transaction_status_hash"`
-       Transactions           []*BlockTx `json:"transactions"`
-}
-
-// return block by hash
-func (a *API) getBlock(ins GetBlockReq) Response {
-       var err error
-       block := &types.Block{}
-       if len(ins.BlockHash) == 32 {
-               b32 := [32]byte{}
-               copy(b32[:], ins.BlockHash)
-               hash := bc.NewHash(b32)
-               block, err = a.chain.GetBlockByHash(&hash)
-       } else {
-               block, err = a.chain.GetBlockByHeight(ins.BlockHeight)
-       }
-       if err != nil {
-               return NewErrorResponse(err)
-       }
-
-       blockHash := block.Hash()
-       txStatus, err := a.chain.GetTransactionStatus(&blockHash)
-       rawBlock, err := block.MarshalText()
-       if err != nil {
-               return NewErrorResponse(err)
-       }
-
-       resp := &GetBlockResp{
-               Hash:                   &blockHash,
-               Size:                   uint64(len(rawBlock)),
-               Version:                block.Version,
-               Height:                 block.Height,
-               PreviousBlockHash:      &block.PreviousBlockHash,
-               Timestamp:              block.Timestamp,
-               Nonce:                  block.Nonce,
-               Bits:                   block.Bits,
-               Difficulty:             difficulty.CompactToBig(block.Bits).String(),
-               TransactionsMerkleRoot: &block.TransactionsMerkleRoot,
-               TransactionStatusHash:  &block.TransactionStatusHash,
-               Transactions:           []*BlockTx{},
-       }
-
-       for i, orig := range block.Transactions {
-               tx := &BlockTx{
-                       ID:        orig.ID,
-                       Version:   orig.Version,
-                       Size:      orig.SerializedSize,
-                       TimeRange: orig.TimeRange,
-                       Inputs:    []*query.AnnotatedInput{},
-                       Outputs:   []*query.AnnotatedOutput{},
-               }
-               tx.StatusFail, err = txStatus.GetStatus(i)
-               if err != nil {
-                       NewSuccessResponse(resp)
-               }
-
-               for i := range orig.Inputs {
-                       tx.Inputs = append(tx.Inputs, wallet.BuildAnnotatedInput(orig, uint32(i)))
-               }
-               for i := range orig.Outputs {
-                       tx.Outputs = append(tx.Outputs, wallet.BuildAnnotatedOutput(orig, i))
-               }
-               resp.Transactions = append(resp.Transactions, tx)
-       }
-       return NewSuccessResponse(resp)
-}
-
-// return block transactions count by hash
-func (a *API) getBlockTransactionsCountByHash(strHash string) Response {
-       hash := bc.Hash{}
-       if err := hash.UnmarshalText([]byte(strHash)); err != nil {
-               log.WithField("error", err).Error("Error occurs when transforming string hash to hash struct")
-               return NewErrorResponse(err)
-       }
-
-       legacyBlock, err := a.chain.GetBlockByHash(&hash)
-       if err != nil {
-               log.WithField("error", err).Error("Fail to get block by hash")
-               return NewErrorResponse(err)
-       }
-
-       count := map[string]int{"count": len(legacyBlock.Transactions)}
-       return NewSuccessResponse(count)
-}
-
-// return block transactions count by height
-func (a *API) getBlockTransactionsCountByHeight(height uint64) Response {
-       legacyBlock, err := a.chain.GetBlockByHeight(height)
-       if err != nil {
-               log.WithField("error", err).Error("Fail to get block by hash")
-               return NewErrorResponse(err)
-       }
-
-       count := map[string]int{"count": len(legacyBlock.Transactions)}
-       return NewSuccessResponse(count)
-}
-
-// return current block count
-func (a *API) getBlockCount() Response {
-       blockHeight := map[string]uint64{"block_count": a.chain.Height()}
-       return NewSuccessResponse(blockHeight)
-}
-
-// return is in mining or not
-func (a *API) isMining() Response {
-       IsMining := map[string]bool{"isMining": a.bcr.IsMining()}
-       return NewSuccessResponse(IsMining)
-}
-
-// return gasRate
-func (a *API) gasRate() Response {
-       gasrate := map[string]int64{"gasRate": consensus.VMGasRate}
-       return NewSuccessResponse(gasrate)
-}
index a8d2c5d..4f7bea0 100644 (file)
@@ -1,13 +1,17 @@
 package blockchain
 
 import (
-       "context"
-
-       "github.com/bytom/api"
+       "github.com/bytom/protocol/bc"
        "github.com/bytom/protocol/bc/types"
 )
 
-func (bcr *BlockchainReactor) GetWork() (*api.GetWorkResp, error) {
+// GetWorkResp is resp struct for API
+type GetWorkResp struct {
+       BlockHeader *types.BlockHeader `json:"block_header"`
+       Seed        *bc.Hash           `json:"seed"`
+}
+
+func (bcr *BlockchainReactor) GetWork() (*GetWorkResp, error) {
        bh, err := bcr.miningPool.GetWork()
        if err != nil {
                return nil, err
@@ -18,7 +22,7 @@ func (bcr *BlockchainReactor) GetWork() (*api.GetWorkResp, error) {
                return nil, err
        }
 
-       return &api.GetWorkResp{
+       return &GetWorkResp{
                BlockHeader: bh,
                Seed:        seed,
        }, nil
@@ -27,30 +31,3 @@ func (bcr *BlockchainReactor) GetWork() (*api.GetWorkResp, error) {
 func (bcr *BlockchainReactor) SubmitWork(bh *types.BlockHeader) bool {
        return bcr.miningPool.SubmitWork(bh)
 }
-
-func (a *API) getWork() Response {
-       work, err := a.bcr.GetWork()
-       if err != nil {
-               return NewErrorResponse(err)
-       }
-       return NewSuccessResponse(work)
-}
-
-func (a *API) submitWork(bh *types.BlockHeader) Response {
-       return NewSuccessResponse(a.bcr.SubmitWork(bh))
-}
-
-func (a *API) getBlockHeaderByHeight(ctx context.Context, req struct {
-       Height uint64 `json:"block_height"`
-}) Response {
-       block, err := a.chain.GetBlockByHeight(req.Height)
-       if err != nil {
-               return NewErrorResponse(err)
-       }
-
-       resp := &api.BlockHeaderByHeight{
-               BlockHeader: &block.BlockHeader,
-               Reward:      block.Transactions[0].Outputs[0].Amount,
-       }
-       return NewSuccessResponse(resp)
-}
index ae41457..4a254aa 100644 (file)
@@ -2,153 +2,14 @@ package blockchain
 
 import (
        "context"
-       "encoding/json"
-       "fmt"
-       "time"
 
        log "github.com/sirupsen/logrus"
 
        "github.com/bytom/blockchain/txbuilder"
        "github.com/bytom/errors"
-       "github.com/bytom/net/http/reqid"
-       "github.com/bytom/protocol/bc"
        "github.com/bytom/protocol/bc/types"
 )
 
-var defaultTxTTL = 5 * time.Minute
-
-func (a *API) actionDecoder(action string) (func([]byte) (txbuilder.Action, error), bool) {
-       var decoder func([]byte) (txbuilder.Action, error)
-       switch action {
-       case "control_account":
-               decoder = a.wallet.AccountMgr.DecodeControlAction
-       case "control_address":
-               decoder = txbuilder.DecodeControlAddressAction
-       case "control_program":
-               decoder = txbuilder.DecodeControlProgramAction
-       case "control_receiver":
-               decoder = txbuilder.DecodeControlReceiverAction
-       case "issue":
-               decoder = a.wallet.AssetReg.DecodeIssueAction
-       case "retire":
-               decoder = txbuilder.DecodeRetireAction
-       case "spend_account":
-               decoder = a.wallet.AccountMgr.DecodeSpendAction
-       case "spend_account_unspent_output":
-               decoder = a.wallet.AccountMgr.DecodeSpendUTXOAction
-       default:
-               return nil, false
-       }
-       return decoder, true
-}
-
-func mergeActions(req *BuildRequest) []map[string]interface{} {
-       actions := make([]map[string]interface{}, 0)
-       actionMap := make(map[string]map[string]interface{})
-
-       for _, m := range req.Actions {
-               if actionType := m["type"].(string); actionType != "spend_account" {
-                       actions = append(actions, m)
-                       continue
-               }
-
-               actionKey := m["asset_id"].(string) + m["account_id"].(string)
-               amountNumber := m["amount"].(json.Number)
-               amount, _ := amountNumber.Int64()
-
-               if tmpM, ok := actionMap[actionKey]; ok {
-                       tmpNumber, _ := tmpM["amount"].(json.Number)
-                       tmpAmount, _ := tmpNumber.Int64()
-                       tmpM["amount"] = json.Number(fmt.Sprintf("%v", tmpAmount+amount))
-               } else {
-                       actionMap[actionKey] = m
-                       actions = append(actions, m)
-               }
-       }
-
-       return actions
-}
-
-func (a *API) buildSingle(ctx context.Context, req *BuildRequest) (*txbuilder.Template, error) {
-       err := a.filterAliases(ctx, req)
-       if err != nil {
-               return nil, err
-       }
-       reqActions := mergeActions(req)
-       actions := make([]txbuilder.Action, 0, len(reqActions))
-       for i, act := range reqActions {
-               typ, ok := act["type"].(string)
-               if !ok {
-                       return nil, errors.WithDetailf(errBadActionType, "no action type provided on action %d", i)
-               }
-               decoder, ok := a.actionDecoder(typ)
-               if !ok {
-                       return nil, errors.WithDetailf(errBadActionType, "unknown action type %q on action %d", typ, i)
-               }
-
-               // Remarshal to JSON, the action may have been modified when we
-               // filtered aliases.
-               b, err := json.Marshal(act)
-               if err != nil {
-                       return nil, err
-               }
-               action, err := decoder(b)
-               if err != nil {
-                       return nil, errors.WithDetailf(errBadAction, "%s on action %d", err.Error(), i)
-               }
-               actions = append(actions, action)
-       }
-
-       ttl := req.TTL.Duration
-       if ttl == 0 {
-               ttl = defaultTxTTL
-       }
-       maxTime := time.Now().Add(ttl)
-
-       tpl, err := txbuilder.Build(ctx, req.Tx, actions, maxTime, req.TimeRange)
-       if errors.Root(err) == txbuilder.ErrAction {
-               // append each of the inner errors contained in the data.
-               var Errs string
-               for _, innerErr := range errors.Data(err)["actions"].([]error) {
-                       Errs = Errs + "<" + innerErr.Error() + ">"
-               }
-               err = errors.New(err.Error() + "-" + Errs)
-       }
-       if err != nil {
-               return nil, err
-       }
-
-       // ensure null is never returned for signing instructions
-       if tpl.SigningInstructions == nil {
-               tpl.SigningInstructions = []*txbuilder.SigningInstruction{}
-       }
-       return tpl, nil
-}
-
-// POST /build-transaction
-func (a *API) build(ctx context.Context, buildReqs *BuildRequest) Response {
-       subctx := reqid.NewSubContext(ctx, reqid.New())
-
-       tmpl, err := a.buildSingle(subctx, buildReqs)
-       if err != nil {
-               return NewErrorResponse(err)
-       }
-
-       return NewSuccessResponse(tmpl)
-}
-
-func (a *API) submitSingle(ctx context.Context, tpl *txbuilder.Template) (map[string]string, error) {
-       if tpl.Transaction == nil {
-               return nil, errors.Wrap(txbuilder.ErrMissingRawTx)
-       }
-
-       if err := txbuilder.FinalizeTx(ctx, a.chain, tpl.Transaction); err != nil {
-               return nil, errors.Wrapf(err, "tx %s", tpl.Transaction.ID.String())
-       }
-
-       return map[string]string{"tx_id": tpl.Transaction.ID.String()}, nil
-}
-
 // finalizeTxWait calls FinalizeTx and then waits for confirmation of
 // the transaction.  A nil error return means the transaction is
 // confirmed on the blockchain.  ErrRejected means a conflicting tx is
@@ -215,40 +76,3 @@ func (bcr *BlockchainReactor) waitForTxInBlock(ctx context.Context, tx *types.Tx
                }
        }
 }
-
-type submitTxResp struct {
-       TxID *bc.Hash `json:"tx_id"`
-}
-
-// POST /submit-transaction
-func (a *API) submit(ctx context.Context, ins struct {
-       Tx types.Tx `json:"raw_transaction"`
-}) Response {
-       if err := txbuilder.FinalizeTx(ctx, a.chain, &ins.Tx); err != nil {
-               return NewErrorResponse(err)
-       }
-
-       log.WithField("tx_id", ins.Tx.ID).Info("submit single tx")
-       return NewSuccessResponse(&submitTxResp{TxID: &ins.Tx.ID})
-}
-
-// POST /sign-submit-transaction
-func (a *API) signSubmit(ctx context.Context, x struct {
-       Password []string           `json:"password"`
-       Txs      txbuilder.Template `json:"transaction"`
-}) Response {
-       if err := txbuilder.Sign(ctx, &x.Txs, nil, x.Password[0], a.pseudohsmSignTemplate); err != nil {
-               log.WithField("build err", err).Error("fail on sign transaction.")
-               return NewErrorResponse(err)
-       }
-       log.Info("Sign Transaction complete.")
-
-       txID, err := a.submitSingle(nil, &x.Txs)
-       if err != nil {
-               log.WithField("err", err).Error("submit single tx")
-               return NewErrorResponse(err)
-       }
-
-       log.WithField("tx_id", txID["tx_id"]).Info("submit single tx")
-       return NewSuccessResponse(txID)
-}
index 3d8207b..4e9ce30 100644 (file)
@@ -4,25 +4,10 @@ import (
        "context"
        "encoding/json"
 
-       log "github.com/sirupsen/logrus"
-
-       "github.com/bytom/blockchain/txfeed"
        "github.com/bytom/errors"
 )
 
-// POST /create-txfeed
-func (a *API) createTxFeed(ctx context.Context, in struct {
-       Alias  string `json:"alias"`
-       Filter string `json:"filter"`
-}) Response {
-       if err := a.bcr.TxFeedTracker.Create(ctx, in.Alias, in.Filter); err != nil {
-               log.WithField("error", err).Error("Add TxFeed Failed")
-               return NewErrorResponse(err)
-       }
-       return NewSuccessResponse(nil)
-}
-
-func (bcr *BlockchainReactor) getTxFeedByAlias(ctx context.Context, filter string) ([]byte, error) {
+func (bcr *BlockchainReactor) GetTxFeedByAlias(ctx context.Context, filter string) ([]byte, error) {
        jf, err := json.Marshal(filter)
        if err != nil {
                return nil, err
@@ -35,73 +20,3 @@ func (bcr *BlockchainReactor) getTxFeedByAlias(ctx context.Context, filter strin
 
        return value, nil
 }
-
-// POST /get-transaction-feed
-func (a *API) getTxFeed(ctx context.Context, in struct {
-       Alias string `json:"alias,omitempty"`
-}) Response {
-       var tmpTxFeed interface{}
-       rawTxfeed, err := a.bcr.getTxFeedByAlias(ctx, in.Alias)
-       if err != nil {
-               return NewErrorResponse(err)
-       }
-       err = json.Unmarshal(rawTxfeed, &tmpTxFeed)
-       if err != nil {
-               return NewErrorResponse(err)
-       }
-       data := map[string]interface{}{"txfeed": tmpTxFeed}
-       return NewSuccessResponse(data)
-}
-
-// POST /delete-transaction-feed
-func (a *API) deleteTxFeed(ctx context.Context, in struct {
-       Alias string `json:"alias,omitempty"`
-}) Response {
-       if err := a.bcr.TxFeedTracker.Delete(ctx, in.Alias); err != nil {
-               return NewErrorResponse(err)
-       }
-       return NewSuccessResponse(nil)
-}
-
-// POST /update-transaction-feed
-func (a *API) updateTxFeed(ctx context.Context, in struct {
-       Alias  string `json:"alias"`
-       Filter string `json:"filter"`
-}) Response {
-       if err := a.bcr.TxFeedTracker.Delete(ctx, in.Alias); err != nil {
-               return NewErrorResponse(err)
-       }
-       if err := a.bcr.TxFeedTracker.Create(ctx, in.Alias, in.Filter); err != nil {
-               log.WithField("error", err).Error("Update TxFeed Failed")
-               return NewErrorResponse(err)
-       }
-       return NewSuccessResponse(nil)
-}
-
-func (a *API) getTxFeeds() ([]txfeed.TxFeed, error) {
-       txFeed := txfeed.TxFeed{}
-       txFeeds := make([]txfeed.TxFeed, 0)
-
-       iter := a.bcr.TxFeedTracker.DB.Iterator()
-       defer iter.Release()
-
-       for iter.Next() {
-               if err := json.Unmarshal(iter.Value(), &txFeed); err != nil {
-                       return nil, err
-               }
-               txFeeds = append(txFeeds, txFeed)
-       }
-
-       return txFeeds, nil
-}
-
-// listTxFeeds is an http handler for listing txfeeds. It does not take a filter.
-// POST /list-transaction-feeds
-func (a *API) listTxFeeds(ctx context.Context) Response {
-       txFeeds, err := a.getTxFeeds()
-       if err != nil {
-               return NewErrorResponse(err)
-       }
-
-       return NewSuccessResponse(txFeeds)
-}
index b2c0d64..cb9a8f2 100644 (file)
@@ -9,7 +9,7 @@ import (
        "github.com/spf13/cobra"
        jww "github.com/spf13/jwalterweatherman"
 
-       "github.com/bytom/blockchain"
+       "github.com/bytom/api"
        "github.com/bytom/crypto/ed25519/chainkd"
        "github.com/bytom/util"
 )
@@ -128,7 +128,7 @@ var importPrivateCmd = &cobra.Command{
        Short: "Import the private key",
        Args:  cobra.ExactArgs(5),
        Run: func(cmd *cobra.Command, args []string) {
-               var params blockchain.KeyImportParams
+               var params api.KeyImportParams
                params.KeyAlias = args[0]
                params.XPrv = args[1]
                params.Password = args[3]
index 2e284c4..edab496 100644 (file)
@@ -8,7 +8,7 @@ import (
        "github.com/spf13/cobra"
        jww "github.com/spf13/jwalterweatherman"
 
-       "github.com/bytom/blockchain"
+       "github.com/bytom/api"
        "github.com/bytom/blockchain/txbuilder"
        "github.com/bytom/protocol/bc/types"
        "github.com/bytom/util"
@@ -146,7 +146,7 @@ var buildTransactionCmd = &cobra.Command{
                        os.Exit(util.ErrLocalExe)
                }
 
-               var buildReq blockchain.BuildRequest
+               var buildReq api.BuildRequest
                if err := json.Unmarshal([]byte(buildReqStr), &buildReq); err != nil {
                        jww.ERROR.Println(err)
                        os.Exit(util.ErrLocalExe)
index 2f65a10..ecccf3e 100644 (file)
@@ -5,7 +5,7 @@ import (
        "fmt"
        "os"
 
-       "github.com/bytom/api"
+       "github.com/bytom/blockchain"
        "github.com/bytom/consensus/difficulty"
        "github.com/bytom/protocol/bc"
        "github.com/bytom/protocol/bc/types"
@@ -61,7 +61,7 @@ func main() {
                fmt.Println(err)
                os.Exit(1)
        }
-       resp := &api.GetWorkResp{}
+       resp := &blockchain.GetWorkResp{}
        if err = json.Unmarshal(rawData, resp); err != nil {
                fmt.Println(err)
                os.Exit(1)
index 502034e..904fde9 100755 (executable)
@@ -13,14 +13,15 @@ import (
        cmn "github.com/tendermint/tmlibs/common"
        dbm "github.com/tendermint/tmlibs/db"
 
+       "github.com/bytom/api"
+       "github.com/bytom/crypto/ed25519/chainkd"
+       bc "github.com/bytom/blockchain"
        "github.com/bytom/accesstoken"
        "github.com/bytom/account"
        "github.com/bytom/asset"
-       bc "github.com/bytom/blockchain"
        "github.com/bytom/blockchain/pseudohsm"
        "github.com/bytom/blockchain/txfeed"
        cfg "github.com/bytom/config"
-       "github.com/bytom/crypto/ed25519/chainkd"
        "github.com/bytom/database/leveldb"
        "github.com/bytom/env"
        "github.com/bytom/p2p"
@@ -51,7 +52,8 @@ type Node struct {
        bcReactor    *bc.BlockchainReactor
        wallet       *w.Wallet
        accessTokens *accesstoken.CredentialStore
-       api          *bc.API
+       api          *api.API
+       chain        *protocol.Chain
 }
 
 func NewNode(config *cfg.Config) *Node {
@@ -162,6 +164,7 @@ func NewNode(config *cfg.Config) *Node {
                bcReactor:    bcReactor,
                accessTokens: accessTokens,
                wallet:       wallet,
+               chain:        chain,
        }
        node.BaseService = *cmn.NewBaseService(nil, "Node", node)
 
@@ -210,7 +213,7 @@ func lanchWebBroser(lanch bool) {
 }
 
 func (n *Node) initAndstartApiServer() {
-       n.api = bc.NewAPI(n.bcReactor, n.config)
+       n.api = api.NewAPI(n.bcReactor, n.wallet, n.chain, n.config)
 
        listenAddr := env.String("LISTEN", n.config.ApiAddress)
        n.api.StartServer(*listenAddr)
index b15bcae..5b072f9 100644 (file)
@@ -8,6 +8,7 @@ import (
        "strings"
        "time"
 
+       "github.com/bytom/api"
        "github.com/bytom/blockchain"
        "github.com/bytom/blockchain/rpc"
        "github.com/bytom/env"
@@ -76,7 +77,7 @@ func MustRPCClient() *rpc.Client {
 // Wrapper rpc call api.
 func ClientCall(path string, req ...interface{}) (interface{}, int) {
 
-       var response = &blockchain.Response{}
+       var response = &api.Response{}
        var request interface{}
 
        if req != nil {
@@ -87,7 +88,7 @@ func ClientCall(path string, req ...interface{}) (interface{}, int) {
        client.Call(context.Background(), path, request, response)
 
        switch response.Status {
-       case blockchain.FAIL:
+       case api.FAIL:
                jww.ERROR.Println(response.Msg)
                return nil, ErrRemote
        case "":