OSDN Git Service

Dev fix control (#1462)
authorChengcheng Zhang <943420582@qq.com>
Thu, 15 Nov 2018 07:05:25 +0000 (15:05 +0800)
committerPaladz <yzhu101@uottawa.ca>
Thu, 15 Nov 2018 07:05:25 +0000 (15:05 +0800)
* fix deleteaccount

* delete utxo

* update

* delete tx

* add make install

* add some functions

* update

* add DeleteAccout in wallet

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

Makefile
account/accounts.go
account/accounts_test.go
api/accounts.go
cmd/bytomcli/commands/account.go
consensus/general.go
wallet/wallet.go

index f5f2a75..1e442fe 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -37,7 +37,7 @@ BYTOMCLI_RELEASE64 := bytomcli-$(VERSION)-$(GOOS)_amd64
 BYTOM_RELEASE32 := bytom-$(VERSION)-$(GOOS)_386
 BYTOM_RELEASE64 := bytom-$(VERSION)-$(GOOS)_amd64
 
-all: test target release-all
+all: test target release-all install
 
 bytomd:
        @echo "Building bytomd to cmd/bytomd/bytomd"
index 957aad8..6325a66 100644 (file)
@@ -55,6 +55,7 @@ var (
        ErrDeriveRule      = errors.New("invalid key derive rule")
        ErrContractIndex   = errors.New("exceed the maximum addresses per account")
        ErrAccountIndex    = errors.New("exceed the maximum accounts per xpub")
+       ErrFindTransaction = errors.New("no transaction")
 )
 
 // ContractKey account control promgram store prefix
@@ -299,13 +300,55 @@ func (m *Manager) CreateBatchAddresses(accountID string, change bool, stopIndex
        return nil
 }
 
-// DeleteAccount deletes the account's ID or alias matching accountInfo.
-func (m *Manager) DeleteAccount(aliasOrID string) (err error) {
-       account := &Account{}
-       if account, err = m.FindByAlias(aliasOrID); err != nil {
-               if account, err = m.FindByID(aliasOrID); err != nil {
+// deleteAccountControlPrograms deletes control program matching accountID
+func (m *Manager) deleteAccountControlPrograms(accountID string) error {
+       cps, err := m.ListControlProgram()
+       if err != nil {
+               return err
+       }
+
+       var hash common.Hash
+       for _, cp := range cps {
+               if cp.AccountID == accountID {
+                       sha3pool.Sum256(hash[:], cp.ControlProgram)
+                       m.db.Delete(ContractKey(hash))
+               }
+       }
+       return nil
+}
+
+// deleteAccountUtxos deletes utxos matching accountID
+func (m *Manager) deleteAccountUtxos(accountID string) error {
+       accountUtxoIter := m.db.IteratorPrefix([]byte(UTXOPreFix))
+       defer accountUtxoIter.Release()
+       for accountUtxoIter.Next() {
+               accountUtxo := &UTXO{}
+               if err := json.Unmarshal(accountUtxoIter.Value(), accountUtxo); err != nil {
                        return err
                }
+
+               if accountID == accountUtxo.AccountID {
+                       m.db.Delete(StandardUTXOKey(accountUtxo.OutputID))
+               }
+       }
+       return nil
+}
+
+// DeleteAccount deletes the account's ID or alias matching account ID.
+func (m *Manager) DeleteAccount(accountID string) (err error) {
+       m.accountMu.Lock()
+       defer m.accountMu.Unlock()
+
+       account, err := m.FindByID(accountID)
+       if err != nil {
+               return err
+       }
+
+       if err := m.deleteAccountControlPrograms(accountID); err != nil {
+               return err
+       }
+       if err := m.deleteAccountUtxos(accountID); err != nil {
+               return err
        }
 
        m.cacheMu.Lock()
index 9088be0..7e4137d 100644 (file)
@@ -128,10 +128,6 @@ func TestDeleteAccount(t *testing.T) {
                testutil.FatalErr(t, err)
        }
 
-       if err = m.DeleteAccount(account1.Alias); err != nil {
-               testutil.FatalErr(t, err)
-       }
-
        found, err := m.FindByID(account1.ID)
        if err != nil {
                t.Errorf("expected account %v should be deleted", found)
index d8e5661..613215a 100644 (file)
@@ -58,10 +58,22 @@ type AccountInfo struct {
 }
 
 // POST /delete-account
-func (a *API) deleteAccount(ctx context.Context, in AccountInfo) Response {
-       if err := a.wallet.AccountMgr.DeleteAccount(in.Info); err != nil {
+func (a *API) deleteAccount(ctx context.Context, filter struct {
+       AccountID    string `json:"account_id"`
+       AccountAlias string `json:"account_alias"`
+}) Response {
+       accountID := filter.AccountID
+       if filter.AccountAlias != "" {
+               acc, err := a.wallet.AccountMgr.FindByAlias(filter.AccountAlias)
+               if err != nil {
+                       return NewErrorResponse(err)
+               }
+               accountID = acc.ID
+       }
+       if err := a.wallet.DeleteAccount(accountID); err != nil {
                return NewErrorResponse(err)
        }
+
        return NewSuccessResponse(nil)
 }
 
index 2bb79e9..ac26b7d 100644 (file)
@@ -21,6 +21,9 @@ func init() {
        listAccountsCmd.PersistentFlags().StringVar(&accountID, "id", "", "account ID")
        listAccountsCmd.PersistentFlags().StringVar(&accountAlias, "alias", "", "account alias")
 
+       deleteAccountCmd.PersistentFlags().StringVar(&accountID, "id", "", "account ID")
+       deleteAccountCmd.PersistentFlags().StringVar(&accountAlias, "alias", "", "account alias")
+
        listAddressesCmd.PersistentFlags().StringVar(&accountID, "id", "", "account ID")
        listAddressesCmd.PersistentFlags().StringVar(&accountAlias, "alias", "", "account alias")
 
@@ -116,15 +119,16 @@ var listAccountsCmd = &cobra.Command{
 }
 
 var deleteAccountCmd = &cobra.Command{
-       Use:   "delete-account <accountID|alias>",
+       Use:   "delete-account <[accountAlias]|[accountID]>",
        Short: "Delete the existing account",
-       Args:  cobra.ExactArgs(1),
+       Args:  cobra.NoArgs,
        Run: func(cmd *cobra.Command, args []string) {
-               accountInfo := &struct {
-                       AccountInfo string `json:"account_info"`
-               }{AccountInfo: args[0]}
+               var ins = struct {
+                       AccountID    string `json:"account_id"`
+                       AccountAlias string `json:"account_alias"`
+               }{AccountID: accountID, AccountAlias: accountAlias}
 
-               if _, exitCode := util.ClientCall("/delete-account", accountInfo); exitCode != util.Success {
+               if _, exitCode := util.ClientCall("/delete-account", &ins); exitCode != util.Success {
                        os.Exit(exitCode)
                }
 
index 51155aa..931db8c 100644 (file)
@@ -130,6 +130,8 @@ var TestNetParams = Params{
                {10303, bc.NewHash([32]byte{0x3e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c})},
                {40000, bc.NewHash([32]byte{0x6b, 0x13, 0x9a, 0x5b, 0x76, 0x77, 0x9b, 0xd4, 0x1c, 0xec, 0x53, 0x68, 0x44, 0xbf, 0xf4, 0x48, 0x94, 0x3d, 0x16, 0xe3, 0x9b, 0x2e, 0xe8, 0xa1, 0x0f, 0xa0, 0xbc, 0x7d, 0x2b, 0x17, 0x55, 0xfc})},
                {78000, bc.NewHash([32]byte{0xa9, 0x03, 0xc0, 0x0c, 0x62, 0x1a, 0x3d, 0x00, 0x7f, 0xd8, 0x5d, 0x51, 0xba, 0x43, 0xe4, 0xd0, 0xe3, 0xc5, 0xd4, 0x8f, 0x30, 0xb5, 0x5f, 0xa5, 0x77, 0x62, 0xd8, 0x8b, 0x11, 0x81, 0x5f, 0xb4})},
+               {82000, bc.NewHash([32]byte{0x56, 0xb1, 0xba, 0x23, 0x69, 0x5c, 0x8f, 0x51, 0x4e, 0x23, 0xc0, 0xae, 0xaa, 0x25, 0x08, 0xc5, 0x85, 0xf3, 0x7c, 0xd1, 0xc6, 0x15, 0xa2, 0x51, 0xda, 0x79, 0x4f, 0x08, 0x13, 0x66, 0xc9, 0x85})},
+               {83200, bc.NewHash([32]byte{0xb4, 0x6f, 0xc5, 0xcf, 0xa3, 0x3d, 0xe1, 0x11, 0x71, 0x68, 0x40, 0x68, 0x0c, 0xe7, 0x4c, 0xaf, 0x5a, 0x11, 0xfe, 0x82, 0xbc, 0x36, 0x88, 0x0f, 0xbd, 0x04, 0xf0, 0xc4, 0x86, 0xd4, 0xd6, 0xd5})},
        },
 }
 
index 25f433a..50c0a18 100644 (file)
@@ -194,6 +194,42 @@ func (w *Wallet) RescanBlocks() {
        }
 }
 
+// deleteAccountTxs deletes all txs in wallet
+func (w *Wallet) deleteAccountTxs() {
+       storeBatch := w.DB.NewBatch()
+
+       txIter := w.DB.IteratorPrefix([]byte(TxPrefix))
+       defer txIter.Release()
+
+       for txIter.Next() {
+               storeBatch.Delete(txIter.Key())
+       }
+
+       txIndexIter := w.DB.IteratorPrefix([]byte(TxIndexPrefix))
+       defer txIndexIter.Release()
+
+       for txIndexIter.Next() {
+               storeBatch.Delete(txIndexIter.Key())
+       }
+
+       storeBatch.Write()
+}
+
+// DeleteAccount deletes account matching accountID, then rescan wallet
+func (w *Wallet) DeleteAccount(accountID string) (err error) {
+       w.rw.Lock()
+       defer w.rw.Unlock()
+
+       w.deleteAccountTxs()
+
+       if err := w.AccountMgr.DeleteAccount(accountID); err != nil {
+               return err
+       }
+
+       w.RescanBlocks()
+       return nil
+}
+
 func (w *Wallet) getRescanNotification() {
        select {
        case <-w.rescanCh: