OSDN Git Service

init version for list-unspend-output support 0 confirmed utxo (#1129)
authorPaladz <yzhu101@uottawa.ca>
Tue, 10 Jul 2018 03:16:19 +0000 (11:16 +0800)
committerGitHub <noreply@github.com>
Tue, 10 Jul 2018 03:16:19 +0000 (11:16 +0800)
* init version for list-unspend-output support 0 confirmed utxo

* add unit test for list 0 confirmed utxo

account/accounts.go
account/utxo_keeper.go
api/query.go
wallet/indexer.go
wallet/utxo.go
wallet/utxo_test.go

index 9da0a8c..5990868 100644 (file)
@@ -14,6 +14,7 @@ import (
        "github.com/bytom/blockchain/txbuilder"
        "github.com/bytom/common"
        "github.com/bytom/consensus"
+       "github.com/bytom/consensus/segwit"
        "github.com/bytom/crypto"
        "github.com/bytom/crypto/ed25519/chainkd"
        "github.com/bytom/crypto/sha3pool"
@@ -361,6 +362,17 @@ func (m *Manager) ListControlProgram() ([]*CtrlProgram, error) {
        return cps, nil
 }
 
+func (m *Manager) ListUnconfirmedUtxo(isSmartContract bool) []*UTXO {
+       utxos := m.utxoKeeper.ListUnconfirmed()
+       result := []*UTXO{}
+       for _, utxo := range utxos {
+               if segwit.IsP2WScript(utxo.ControlProgram) != isSmartContract {
+                       result = append(result, utxo)
+               }
+       }
+       return result
+}
+
 // RemoveUnconfirmedUtxo remove utxos from the utxoKeeper
 func (m *Manager) RemoveUnconfirmedUtxo(hashes []*bc.Hash) {
        m.utxoKeeper.RemoveUnconfirmedUtxo(hashes)
index 0fc96bb..151c612 100644 (file)
@@ -87,6 +87,18 @@ func (uk *utxoKeeper) Cancel(rid uint64) {
        uk.mtx.Unlock()
 }
 
+// ListUnconfirmed return all the unconfirmed utxos
+func (uk *utxoKeeper) ListUnconfirmed() []*UTXO {
+       uk.mtx.Lock()
+       defer uk.mtx.Unlock()
+
+       utxos := []*UTXO{}
+       for _, utxo := range uk.unconfirmed {
+               utxos = append(utxos, utxo)
+       }
+       return utxos
+}
+
 func (uk *utxoKeeper) RemoveUnconfirmedUtxo(hashes []*bc.Hash) {
        uk.mtx.Lock()
        defer uk.mtx.Unlock()
index 131cc8b..632e83b 100644 (file)
@@ -236,9 +236,10 @@ func (a *API) decodeRawTransaction(ctx context.Context, ins struct {
 // POST /list-unspent-outputs
 func (a *API) listUnspentOutputs(ctx context.Context, filter struct {
        ID            string `json:"id"`
+       Unconfirmed   bool   `json:"unconfirmed"`
        SmartContract bool   `json:"smart_contract"`
 }) Response {
-       accountUTXOs := a.wallet.GetAccountUtxos(filter.ID, filter.SmartContract)
+       accountUTXOs := a.wallet.GetAccountUtxos(filter.ID, filter.Unconfirmed, filter.SmartContract)
 
        UTXOs := []query.AnnotatedUTXO{}
        for _, utxo := range accountUTXOs {
index ef252c4..313a41a 100644 (file)
@@ -239,7 +239,7 @@ func (w *Wallet) GetTransactions(accountID string) ([]*query.AnnotatedTx, error)
 
 // GetAccountBalances return all account balances
 func (w *Wallet) GetAccountBalances(id string) ([]AccountBalance, error) {
-       return w.indexBalances(w.GetAccountUtxos("", false))
+       return w.indexBalances(w.GetAccountUtxos("", false, false))
 }
 
 // AccountBalance account balance
index 338fddc..a07808e 100644 (file)
@@ -16,12 +16,17 @@ import (
 )
 
 // GetAccountUtxos return all account unspent outputs
-func (w *Wallet) GetAccountUtxos(id string, isSmartContract bool) []*account.UTXO {
+func (w *Wallet) GetAccountUtxos(id string, unconfirmed, isSmartContract bool) []*account.UTXO {
        prefix := account.UTXOPreFix
        if isSmartContract {
                prefix = account.SUTXOPrefix
        }
+
        accountUtxos := []*account.UTXO{}
+       if unconfirmed {
+               accountUtxos = w.AccountMgr.ListUnconfirmedUtxo(isSmartContract)
+       }
+
        accountUtxoIter := w.DB.IteratorPrefix([]byte(prefix + id))
        defer accountUtxoIter.Release()
 
index 47cbaa9..cb9b0d0 100644 (file)
@@ -22,14 +22,17 @@ func TestGetAccountUtxos(t *testing.T) {
        defer os.RemoveAll("temp")
 
        cases := []struct {
-               dbUtxos         map[string]*account.UTXO
-               id              string
-               isSmartContract bool
-               wantUtxos       []*account.UTXO
+               dbUtxos          map[string]*account.UTXO
+               unconfirmedUtxos []*account.UTXO
+               id               string
+               unconfirmed      bool
+               isSmartContract  bool
+               wantUtxos        []*account.UTXO
        }{
                {
                        dbUtxos:         map[string]*account.UTXO{},
                        id:              "",
+                       unconfirmed:     false,
                        isSmartContract: false,
                        wantUtxos:       []*account.UTXO{},
                },
@@ -48,8 +51,9 @@ func TestGetAccountUtxos(t *testing.T) {
                                        OutputID: bc.Hash{V0: 4},
                                },
                        },
-                       id:              "",
-                       isSmartContract: false,
+                       unconfirmedUtxos: []*account.UTXO{},
+                       id:               "",
+                       isSmartContract:  false,
                        wantUtxos: []*account.UTXO{
                                &account.UTXO{OutputID: bc.Hash{V0: 1}},
                                &account.UTXO{OutputID: bc.Hash{V0: 2}},
@@ -71,7 +75,14 @@ func TestGetAccountUtxos(t *testing.T) {
                                        OutputID: bc.Hash{V0: 4},
                                },
                        },
+                       unconfirmedUtxos: []*account.UTXO{
+                               &account.UTXO{
+                                       OutputID:       bc.Hash{V0: 5},
+                                       ControlProgram: []byte("smart contract"),
+                               },
+                       },
                        id:              "",
+                       unconfirmed:     false,
                        isSmartContract: true,
                        wantUtxos: []*account.UTXO{
                                &account.UTXO{OutputID: bc.Hash{V0: 4}},
@@ -92,13 +103,84 @@ func TestGetAccountUtxos(t *testing.T) {
                                        OutputID: bc.Hash{V0: 2, V1: 2},
                                },
                        },
+                       unconfirmedUtxos: []*account.UTXO{
+                               &account.UTXO{
+                                       OutputID:       bc.Hash{V0: 6},
+                                       ControlProgram: []byte{0x51},
+                               },
+                       },
                        id:              "0000000000000002",
+                       unconfirmed:     false,
                        isSmartContract: false,
                        wantUtxos: []*account.UTXO{
                                &account.UTXO{OutputID: bc.Hash{V0: 2}},
                                &account.UTXO{OutputID: bc.Hash{V0: 2, V1: 2}},
                        },
                },
+               {
+                       dbUtxos: map[string]*account.UTXO{
+                               string(account.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{
+                                       OutputID: bc.Hash{V0: 3},
+                               },
+                               string(account.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{
+                                       OutputID: bc.Hash{V0: 4},
+                               },
+                       },
+                       unconfirmedUtxos: []*account.UTXO{
+                               &account.UTXO{
+                                       OutputID:       bc.Hash{V0: 5},
+                                       ControlProgram: []byte("smart contract"),
+                               },
+                               &account.UTXO{
+                                       OutputID:       bc.Hash{V0: 6},
+                                       ControlProgram: []byte{0x51},
+                               },
+                       },
+                       id:              "",
+                       unconfirmed:     true,
+                       isSmartContract: true,
+                       wantUtxos: []*account.UTXO{
+                               &account.UTXO{
+                                       OutputID:       bc.Hash{V0: 5},
+                                       ControlProgram: []byte("smart contract"),
+                               },
+                               &account.UTXO{
+                                       OutputID: bc.Hash{V0: 4},
+                               },
+                       },
+               },
+               {
+                       dbUtxos: map[string]*account.UTXO{
+                               string(account.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{
+                                       OutputID: bc.Hash{V0: 3},
+                               },
+                               string(account.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{
+                                       OutputID: bc.Hash{V0: 4},
+                               },
+                       },
+                       unconfirmedUtxos: []*account.UTXO{
+                               &account.UTXO{
+                                       OutputID:       bc.Hash{V0: 5},
+                                       ControlProgram: []byte("smart contract"),
+                               },
+                               &account.UTXO{
+                                       OutputID:       bc.Hash{V0: 6},
+                                       ControlProgram: []byte{0x51},
+                               },
+                       },
+                       id:              "",
+                       unconfirmed:     true,
+                       isSmartContract: false,
+                       wantUtxos: []*account.UTXO{
+                               &account.UTXO{
+                                       OutputID:       bc.Hash{V0: 6},
+                                       ControlProgram: []byte{0x51},
+                               },
+                               &account.UTXO{
+                                       OutputID: bc.Hash{V0: 3},
+                               },
+                       },
+               },
        }
 
        w := &Wallet{DB: testDB}
@@ -111,7 +193,9 @@ func TestGetAccountUtxos(t *testing.T) {
                        testDB.Set([]byte(k), data)
                }
 
-               gotUtxos := w.GetAccountUtxos(c.id, c.isSmartContract)
+               w.AccountMgr = account.NewManager(testDB, nil)
+               w.AccountMgr.AddUnconfirmedUtxo(c.unconfirmedUtxos)
+               gotUtxos := w.GetAccountUtxos(c.id, c.unconfirmed, c.isSmartContract)
                if !testutil.DeepEqual(gotUtxos, c.wantUtxos) {
                        t.Errorf("case %d: got %v want %v", i, gotUtxos, c.wantUtxos)
                }