m.Handle("/get-transaction", jsonHandler(a.getTransaction))
m.Handle("/list-transactions", jsonHandler(a.listTransactions))
- m.Handle("/get-unconfirmed-transaction", jsonHandler(a.getUnconfirmedTx))
- m.Handle("/list-unconfirmed-transactions", jsonHandler(a.listUnconfirmedTxs))
-
m.Handle("/list-balances", jsonHandler(a.listBalances))
m.Handle("/list-unspent-outputs", jsonHandler(a.listUnspentOutputs))
m.Handle("/submit-transaction", jsonHandler(a.submit))
m.Handle("/estimate-transaction-gas", jsonHandler(a.estimateTxGas))
- m.Handle("/get-mempool-transaction", jsonHandler(a.getMemPoolTx))
- m.Handle("/list-mempool-transactions", jsonHandler(a.listMemPoolTxs))
+ m.Handle("/get-unconfirmed-transaction", jsonHandler(a.getUnconfirmedTx))
+ m.Handle("/list-unconfirmed-transactions", jsonHandler(a.listUnconfirmedTxs))
m.Handle("/decode-raw-transaction", jsonHandler(a.decodeRawTransaction))
m.Handle("/get-block-hash", jsonHandler(a.getBestBlockHash))
func (a *API) getTransaction(ctx context.Context, txInfo struct {
TxID string `json:"tx_id"`
}) Response {
- transaction, err := a.wallet.GetTransactionByTxID(txInfo.TxID)
+ transaction, err := a.wallet.GetTransaction(txInfo.TxID)
if err != nil {
log.Errorf("getTransaction error: %v", err)
return NewErrorResponse(err)
// POST /list-transactions
func (a *API) listTransactions(ctx context.Context, filter struct {
- ID string `json:"id"`
- AccountID string `json:"account_id"`
- Detail bool `json:"detail"`
+ ID string `json:"id"`
+ AccountID string `json:"account_id"`
+ Detail bool `json:"detail"`
+ Unconfirmed bool `json:"unconfirmed"`
}) Response {
transactions := []*query.AnnotatedTx{}
var err error
+ var transaction *query.AnnotatedTx
- if filter.AccountID != "" {
- transactions, err = a.wallet.GetTransactionsByAccountID(filter.AccountID)
+ if filter.ID != "" {
+ if filter.Unconfirmed {
+ transaction, err = a.wallet.GetUnconfirmedTxByTxID(filter.ID)
+ } else {
+ transaction, err = a.wallet.GetTransactionByTxID(filter.ID)
+ }
+
+ if err != nil {
+ log.Errorf("GetTransaction: %v", err)
+ return NewErrorResponse(err)
+ }
+ transactions = []*query.AnnotatedTx{transaction}
} else {
- transactions, err = a.wallet.GetTransactionsByTxID(filter.ID)
+ if filter.Unconfirmed {
+ transactions, err = a.wallet.GetUnconfirmedTxs(filter.AccountID)
+ } else {
+ transactions, err = a.wallet.GetTransactions(filter.AccountID)
+ }
}
if err != nil {
}
// POST /get-unconfirmed-transaction
-func (a *API) getUnconfirmedTx(ctx context.Context, txInfo struct {
- TxID string `json:"tx_id"`
-}) Response {
- transaction, err := a.wallet.GetUnconfirmedTxByTxID(txInfo.TxID)
- if err != nil {
- log.Errorf("getTransaction error: %v", err)
- return NewErrorResponse(err)
- }
-
- return NewSuccessResponse(transaction)
-}
-
-// POST /list-unconfirmed-transactions
-func (a *API) listUnconfirmedTxs(ctx context.Context, filter struct {
- AccountID string `json:"account_id"`
-}) Response {
- transactions := []*query.AnnotatedTx{}
- var err error
-
- transactions, err = a.wallet.GetUnconfirmedTxs(filter.AccountID)
- if err != nil {
- log.Errorf("listTransactions: %v", err)
- return NewErrorResponse(err)
- }
-
- return NewSuccessResponse(transactions)
-}
-
-// POST /get-mempool-transaction
-func (a *API) getMemPoolTx(ctx context.Context, filter struct {
+func (a *API) getUnconfirmedTx(ctx context.Context, filter struct {
TxID chainjson.HexBytes `json:"tx_id"`
}) Response {
var tmpTxID [32]byte
TxIDs []bc.Hash `json:"tx_ids"`
}
-// POST /list-mempool-transactions
-func (a *API) listMemPoolTxs(ctx context.Context) Response {
+// POST /list-unconfirmed-transactions
+func (a *API) listUnconfirmedTxs(ctx context.Context) Response {
txIDs := []bc.Hash{}
txPool := a.chain.GetTxPool()
BytomcliCmd.AddCommand(getUnconfirmedTransactionCmd)
BytomcliCmd.AddCommand(listUnconfirmedTransactionsCmd)
-
- BytomcliCmd.AddCommand(getMemPoolTransactionCmd)
- BytomcliCmd.AddCommand(listMemPoolTransactionsCmd)
BytomcliCmd.AddCommand(decodeRawTransactionCmd)
BytomcliCmd.AddCommand(listUnspentOutputsCmd)
getTransactionCmd.Name(),
listTransactionsCmd.Name(),
-
- getUnconfirmedTransactionCmd.Name(),
- listUnconfirmedTransactionsCmd.Name(),
-
listUnspentOutputsCmd.Name(),
listBalancesCmd.Name(),
}
listTransactionsCmd.PersistentFlags().StringVar(&txID, "id", "", "transaction id")
listTransactionsCmd.PersistentFlags().StringVar(&account, "account_id", "", "account id")
listTransactionsCmd.PersistentFlags().BoolVar(&detail, "detail", false, "list transactions details")
-
- listUnconfirmedTransactionsCmd.PersistentFlags().StringVar(&account, "account_id", "", "account id")
}
var (
Short: "list unconfirmed transactions hashes",
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
- filter := struct {
- AccountID string `json:"account_id"`
- }{AccountID: account}
-
- data, exitCode := util.ClientCall("/list-unconfirmed-transactions", &filter)
- if exitCode != util.Success {
- os.Exit(exitCode)
- }
-
- printJSONList(data)
- },
-}
-
-var getMemPoolTransactionCmd = &cobra.Command{
- Use: "get-mempool-transaction <hash>",
- Short: "get mempool transaction by matching the given transaction hash",
- Args: cobra.ExactArgs(1),
- Run: func(cmd *cobra.Command, args []string) {
- txID, err := hex.DecodeString(args[0])
- if err != nil {
- jww.ERROR.Println(err)
- os.Exit(util.ErrLocalExe)
- }
-
- txInfo := &struct {
- TxID chainjson.HexBytes `json:"tx_id"`
- }{TxID: txID}
-
- data, exitCode := util.ClientCall("/get-mempool-transaction", txInfo)
- if exitCode != util.Success {
- os.Exit(exitCode)
- }
-
- printJSON(data)
- },
-}
-
-var listMemPoolTransactionsCmd = &cobra.Command{
- Use: "list-mempool-transactions",
- Short: "list mempool transactions hashes",
- Args: cobra.NoArgs,
- Run: func(cmd *cobra.Command, args []string) {
- data, exitCode := util.ClientCall("/list-mempool-transactions")
+ data, exitCode := util.ClientCall("/list-unconfirmed-transactions")
if exitCode != util.Success {
os.Exit(exitCode)
}
"github.com/bytom/protocol/bc/types"
)
+var (
+ // ErrNotFoundTx means errors occurred in actions
+ ErrNotFoundTx = errors.New("not found transaction in the wallet db")
+)
+
type rawOutput struct {
OutputID bc.Hash
bc.AssetAmount
return annotatedTxs
}
+// GetTransaction search confirmed or unconfirmed transaction by txID
+func (w *Wallet) GetTransaction(txID string) (*query.AnnotatedTx, error) {
+ annotatedTx, err := w.GetTransactionByTxID(txID)
+ if errors.Root(err) != ErrNotFoundTx {
+ return nil, err
+ }
+
+ annotatedTx, err = w.GetUnconfirmedTxByTxID(txID)
+ if err != nil {
+ return nil, err
+ }
+
+ return annotatedTx, nil
+}
+
// GetTransactionByTxID get transaction by txID
func (w *Wallet) GetTransactionByTxID(txID string) (*query.AnnotatedTx, error) {
formatKey := w.DB.Get(calcTxIndexKey(txID))
if formatKey == nil {
- return nil, fmt.Errorf("No transaction(tx_id=%s) ", txID)
+ return nil, errors.WithData(ErrNotFoundTx, "not found tx=%s from blockchain", txID)
}
annotatedTx := &query.AnnotatedTx{}
return annotatedTx, nil
}
-// GetTransactionsByTxID get account txs by account tx ID
-func (w *Wallet) GetTransactionsByTxID(txID string) ([]*query.AnnotatedTx, error) {
- annotatedTxs := []*query.AnnotatedTx{}
- formatKey := ""
-
- if txID != "" {
- rawFormatKey := w.DB.Get(calcTxIndexKey(txID))
- if rawFormatKey == nil {
- return nil, fmt.Errorf("No transaction(txid=%s) ", txID)
- }
- formatKey = string(rawFormatKey)
- }
-
- txIter := w.DB.IteratorPrefix(calcAnnotatedKey(formatKey))
- defer txIter.Release()
- for txIter.Next() {
- annotatedTx := &query.AnnotatedTx{}
- if err := json.Unmarshal(txIter.Value(), annotatedTx); err != nil {
- return nil, err
- }
- annotateTxsAsset(w, []*query.AnnotatedTx{annotatedTx})
- annotatedTxs = append([]*query.AnnotatedTx{annotatedTx}, annotatedTxs...)
- }
-
- return annotatedTxs, nil
-}
-
// GetTransactionsSummary get transactions summary
func (w *Wallet) GetTransactionsSummary(transactions []*query.AnnotatedTx) []TxSummary {
Txs := []TxSummary{}
return false
}
-// GetTransactionsByAccountID get account txs by account ID
-func (w *Wallet) GetTransactionsByAccountID(accountID string) ([]*query.AnnotatedTx, error) {
+// GetTransactions get all walletDB transactions, and filter transactions by accountID optional
+func (w *Wallet) GetTransactions(accountID string) ([]*query.AnnotatedTx, error) {
annotatedTxs := []*query.AnnotatedTx{}
+ annotatedAccTxs := []*query.AnnotatedTx{}
txIter := w.DB.IteratorPrefix([]byte(TxPrefix))
defer txIter.Release()
return nil, err
}
+ annotateTxsAsset(w, []*query.AnnotatedTx{annotatedTx})
+ annotatedTxs = append(annotatedTxs, annotatedTx)
if findTransactionsByAccount(annotatedTx, accountID) {
- annotateTxsAsset(w, []*query.AnnotatedTx{annotatedTx})
- annotatedTxs = append(annotatedTxs, annotatedTx)
+ annotatedAccTxs = append(annotatedAccTxs, annotatedTx)
}
}
+ if accountID != "" {
+ return annotatedAccTxs, nil
+ }
return annotatedTxs, nil
}
assetAlias := *targetAsset.Alias
balances = append(balances, AccountBalance{
- Alias: alias,
- AccountID: id,
- AssetID: assetID,
- AssetAlias: assetAlias,
- Amount: accBalance[id][assetID],
+ Alias: alias,
+ AccountID: id,
+ AssetID: assetID,
+ AssetAlias: assetAlias,
+ Amount: accBalance[id][assetID],
AssetDefinition: targetAsset.DefinitionMap,
})
}
log "github.com/sirupsen/logrus"
"github.com/bytom/blockchain/query"
+ "github.com/bytom/errors"
"github.com/bytom/protocol/bc/types"
)
func (w *Wallet) GetUnconfirmedTxByTxID(txID string) (*query.AnnotatedTx, error) {
annotatedTx := &query.AnnotatedTx{}
txInfo := w.DB.Get(calcUnconfirmedKey(txID))
+ if txInfo == nil {
+ return nil, errors.WithData(ErrNotFoundTx, "not found tx=%s from txpool", txID)
+ }
+
if err := json.Unmarshal(txInfo, annotatedTx); err != nil {
return nil, err
}
t.Fatal(err)
}
- want, err := w.GetTransactionsByTxID(tx.ID.String())
- if len(want) != 1 {
+ if _, err := w.GetTransactionByTxID(tx.ID.String()); err != nil {
t.Fatal(err)
}
- wants, err := w.GetTransactionsByTxID("")
+ wants, err := w.GetTransactions("")
if len(wants) != 1 {
t.Fatal(err)
}
func mockWallet(walletDB dbm.DB, account *account.Manager, asset *asset.Registry, chain *protocol.Chain) *Wallet {
wallet := &Wallet{
- DB: walletDB,
- AccountMgr: account,
- AssetReg: asset,
- chain: chain,
+ DB: walletDB,
+ AccountMgr: account,
+ AssetReg: asset,
+ chain: chain,
}
return wallet
}