@@ -13,6 +13,7 @@ import (
13
13
"github.com/bytom/blockchain/pseudohsm"
14
14
"github.com/bytom/blockchain/signers"
15
15
"github.com/bytom/blockchain/txbuilder"
16
+ "github.com/bytom/common"
16
17
"github.com/bytom/consensus"
17
18
"github.com/bytom/crypto/ed25519/chainkd"
18
19
"github.com/bytom/errors"
@@ -603,3 +604,91 @@ func TestStateForScope(t *testing.T) {
603
604
t .Fatal ("state for scope test err" )
604
605
}
605
606
}
607
+
608
+ func bip44ContractIndexKey (accountID string , change bool ) []byte {
609
+ contractIndexPrefix := []byte ("ContractIndex" )
610
+ key := append (contractIndexPrefix , accountID ... )
611
+ if change {
612
+ return append (key , []byte {1 }... )
613
+ }
614
+ return append (key , []byte {0 }... )
615
+ }
616
+
617
+ func TestContractIndexResidue (t * testing.T ) {
618
+ dirPath , err := ioutil .TempDir ("." , "" )
619
+ if err != nil {
620
+ t .Fatal (err )
621
+ }
622
+ defer os .RemoveAll (dirPath )
623
+
624
+ testDB := dbm .NewDB ("testdb" , "leveldb" , dirPath )
625
+ hsm , err := pseudohsm .New (dirPath )
626
+ if err != nil {
627
+ t .Fatal (err )
628
+ }
629
+
630
+ xpub1 , _ , err := hsm .XCreate ("test_pub1" , "password" , "en" )
631
+ if err != nil {
632
+ t .Fatal (err )
633
+ }
634
+
635
+ contractIndexResidue := uint64 (5 )
636
+ acctMgr := account .NewManager (testDB , nil )
637
+ recoveryMgr := newRecoveryManager (testDB , acctMgr )
638
+ acct := & account.Account {ID : "testA" , Alias : "test1" , Signer : & signers.Signer {XPubs : []chainkd.XPub {xpub1 .XPub }, KeyIndex : 1 , DeriveRule : signers .BIP0044 }}
639
+
640
+ cp1 := & account.CtrlProgram {AccountID : acct .ID , Address : "address1" , KeyIndex : 10 , Change : false }
641
+
642
+ setContractIndexKey := func (acctMgr * account.Manager , accountID string , change bool ) {
643
+ testDB .Set (bip44ContractIndexKey (accountID , change ), common .Unit64ToBytes (contractIndexResidue ))
644
+ }
645
+
646
+ delAccount := func (acctMgr * account.Manager , accountID string , change bool ) {
647
+ acctMgr .DeleteAccount (accountID )
648
+ }
649
+
650
+ recoveryMgr .state .XPubsStatus = newBranchRecoveryState (acctRecoveryWindow )
651
+ recoveryMgr .state .XPubs = []chainkd.XPub {xpub1 .XPub }
652
+ recoveryMgr .state .stateForScope (acct )
653
+
654
+ cases := []struct {
655
+ acct * account.Account
656
+ cp * account.CtrlProgram
657
+ preProcess func (acctMgr * account.Manager , accountID string , change bool )
658
+ err error
659
+ wantCPNum uint64
660
+ }{
661
+ {acct , cp1 , setContractIndexKey , nil , 5 },
662
+ {acct , cp1 , delAccount , nil , 10 },
663
+ }
664
+
665
+ for _ , c := range cases {
666
+ if c .preProcess != nil {
667
+ c .preProcess (acctMgr , c .acct .ID , c .cp .Change )
668
+ }
669
+
670
+ if err := acctMgr .SaveAccount (acct ); err != nil {
671
+ t .Fatal ("ReportFound test err:" , err )
672
+ }
673
+
674
+ if err := recoveryMgr .reportFound (c .acct , c .cp ); err != c .err {
675
+ t .Fatal ("ContractIndexResidue test err:" , err , c .acct .ID )
676
+ }
677
+ cps , err := acctMgr .ListControlProgram ()
678
+ if err != nil {
679
+ t .Fatal ("list control program err:" , err )
680
+ }
681
+
682
+ cpNum := uint64 (0 )
683
+ for _ , cp := range cps {
684
+ if cp .Address == "" || cp .AccountID != c .acct .ID {
685
+ continue
686
+ }
687
+ cpNum ++
688
+ }
689
+
690
+ if cpNum != c .wantCPNum {
691
+ t .Fatal ("Test contract index residue cp num err want:" , c .wantCPNum , " got:" , cpNum )
692
+ }
693
+ }
694
+ }
0 commit comments