OSDN Git Service

a3bad8c9eb3f9d3e4159c91ab1933183efa55b5a
[bytom/bytom.git] / blockchain / hsm_test.go
1 package blockchain
2
3 import (
4         "context"
5         "fmt"
6         "io/ioutil"
7         "os"
8         "testing"
9         "time"
10
11         "github.com/bytom/blockchain/account"
12         "github.com/bytom/blockchain/asset"
13         "github.com/bytom/blockchain/pin"
14         "github.com/bytom/blockchain/pseudohsm"
15         "github.com/bytom/blockchain/txbuilder"
16         "github.com/bytom/blockchain/txdb"
17         cfg "github.com/bytom/config"
18         "github.com/bytom/consensus"
19         "github.com/bytom/crypto/ed25519/chainkd"
20         "github.com/bytom/protocol"
21         "github.com/bytom/protocol/bc"
22         "github.com/bytom/protocol/bc/legacy"
23
24         dbm "github.com/tendermint/tmlibs/db"
25 )
26
27 const dirPath = "pseudohsm/testdata/pseudo"
28
29 func TestHSM(t *testing.T) {
30         ctx := context.Background()
31
32         dir := tmpManager(t)
33         defer os.RemoveAll(dir)
34
35         config := cfg.DefaultConfig()
36         tc := dbm.NewDB("txdb", config.DBBackend, dir)
37         store := txdb.NewStore(tc)
38
39         var accounts *account.Manager
40         var assets *asset.Registry
41         var pinStore *pin.Store
42
43         genesisBlock := &legacy.Block{
44                 BlockHeader:  legacy.BlockHeader{},
45                 Transactions: []*legacy.Tx{},
46         }
47         genesisBlock.UnmarshalText(consensus.InitBlock())
48         // tx pool init
49         txPool := protocol.NewTxPool()
50         chain, err := protocol.NewChain(genesisBlock.Hash(), store, txPool)
51         if err != nil {
52                 t.Fatal(err)
53         }
54
55         // add gensis block info
56         if err := chain.SaveBlock(genesisBlock); err != nil {
57                 t.Fatal(err)
58         }
59         // parse block and apply
60         if err := chain.ConnectBlock(genesisBlock); err != nil {
61                 t.Fatal(err)
62         }
63
64         accUTXODB := dbm.NewDB("accountutxos", config.DBBackend, dir)
65         pinStore = pin.NewStore(accUTXODB)
66
67         err = pinStore.LoadAll(ctx)
68         if err != nil {
69                 t.Fatal(err)
70         }
71         accountsDB := dbm.NewDB("account", config.DBBackend, dir)
72         accounts = account.NewManager(accountsDB, chain, pinStore)
73         //accounts.IndexAccounts(query.NewIndexer(accountsDB, chain))
74
75         assetsDB := dbm.NewDB("asset", config.DBBackend, dir)
76         assets = asset.NewRegistry(assetsDB, chain)
77
78         hsm, err := pseudohsm.New(dirPath)
79         if err != nil {
80                 t.Fatal(err)
81         }
82         xpub1, err := hsm.XCreate("xpub1", "password")
83         if err != nil {
84                 t.Fatal(err)
85         }
86         xpub2, err := hsm.XCreate("xpub2", "password")
87         if err != nil {
88                 t.Fatal(err)
89         }
90
91         acct1, err := accounts.Create(ctx, []chainkd.XPub{xpub1.XPub}, 1, "acc1", nil, "")
92         if err != nil {
93                 t.Fatal(err)
94         }
95         acct2, err := accounts.Create(ctx, []chainkd.XPub{xpub2.XPub}, 1, "acc2", nil, "")
96         if err != nil {
97                 t.Fatal(err)
98         }
99
100         assetDef1 := map[string]interface{}{"foo": 1}
101         assetDef2 := map[string]interface{}{"foo": 2}
102
103         asset1, err := assets.Define(ctx, []chainkd.XPub{xpub1.XPub}, 1, assetDef1, "foo1", nil, "")
104         if err != nil {
105                 t.Fatal(err)
106         }
107         asset2, err := assets.Define(ctx, []chainkd.XPub{xpub2.XPub}, 1, assetDef2, "foo2", nil, "")
108         if err != nil {
109                 t.Fatal(err)
110         }
111
112         issue1 := txbuilder.Action(assets.NewIssueAction(bc.AssetAmount{AssetId: &asset1.AssetID, Amount: 100}, nil))
113         issue2 := txbuilder.Action(assets.NewIssueAction(bc.AssetAmount{AssetId: &asset2.AssetID, Amount: 200}, nil))
114         spend1 := accounts.NewControlAction(bc.AssetAmount{AssetId: &asset1.AssetID, Amount: 100}, acct1.ID, nil)
115         spend2 := accounts.NewControlAction(bc.AssetAmount{AssetId: &asset2.AssetID, Amount: 200}, acct2.ID, nil)
116
117         tmpl, err := txbuilder.Build(ctx, nil, []txbuilder.Action{issue1, issue2, spend1, spend2}, time.Now().Add(time.Minute))
118         if err != nil {
119                 t.Fatal(err)
120         }
121         //go accounts.ProcessBlocks(ctx)
122
123         err = txbuilder.Sign(ctx, tmpl, []chainkd.XPub{xpub1.XPub, xpub2.XPub}, "password", func(_ context.Context, xpub chainkd.XPub, path [][]byte, data [32]byte, password string) ([]byte, error) {
124                 sigBytes, err := hsm.XSign(xpub, path, data[:], password)
125                 if err != nil {
126                         return nil, nil
127                 }
128                 return sigBytes, err
129         })
130
131         fmt.Printf("###data: %v#####", *tmpl)
132         err = hsm.XDelete(xpub1.XPub, "password")
133         if err != nil {
134                 t.Fatal(err)
135         }
136         err = hsm.XDelete(xpub2.XPub, "password")
137         if err != nil {
138                 t.Fatal(err)
139         }
140
141         //err = txbuilder.FinalizeTx(ctx, chain, tmpl.Transaction)
142         //if err != nil {
143         //      t.Fatal(err)
144         //}
145         /*
146                 // generate block without nouce
147                 b, err := mining.NewBlockTemplate(chain, txPool, []byte{})
148                 if err != nil {
149                         t.Fatal(err)
150                 }
151                 //calculate nonce
152                 for i := uint64(0); i <= 10000000000000; i++ {
153                         b.Nonce = i
154                         hash := b.Hash()
155                         if consensus.CheckProofOfWork(&hash, b.Bits) {
156                                 break
157                         }
158                 }
159                 //block validation
160                 if _, err = chain.ProcessBlock(b); err != nil {
161                         t.Fatal(err)
162                 }
163
164                 <-pinStore.PinWaiter(account.PinName, chain.Height())
165
166                 /*
167                    c := prottest.NewChain(t)
168                    assets := asset.NewRegistry(db, c, pinStore)
169                    accounts å:= account.NewManager(db, c, pinStore)
170                    coretest.CreatePins(ctx, t, pinStore)
171                    accounts.IndexAccounts(query.NewIndexer(db, c, pinStore))
172                    go accounts.ProcessBlocks(ctx)
173
174                    coretest.SignTxTemplate(t, ctx, tmpl, &testutil.TestXPrv)
175                    err = txbuilder.FinalizeTx(ctx, c, g, tmpl.Transaction)
176                    if err != nil {
177                        t.Fatal(err)
178                    }
179
180                    // Make a block so that UTXOs from the above tx are available to spend.
181                    prottest.MakeBlock(t, c, g.PendingTxs())
182                    <-pinStore.PinWaiter(account.PinName, c.Height())
183
184                    xferSrc1 := accounts.NewSpendAction(bc.AssetAmount{AssetId: &asset1ID, Amount: 10}, acct1.ID, nil, nil)
185                    xferSrc2 := accounts.NewSpendAction(bc.AssetAmount{AssetId: &asset2ID, Amount: 20}, acct2.ID, nil, nil)
186                    xferDest1 := accounts.NewControlAction(bc.AssetAmount{AssetId: &asset2ID, Amount: 20}, acct1.ID, nil)
187                    xferDest2 := accounts.NewControlAction(bc.AssetAmount{AssetId: &asset1ID, Amount: 10}, acct2.ID, nil)
188                    tmpl, err = txbuilder.Build(ctx, nil, []txbuilder.Action{xferSrc1, xferSrc2, xferDest1, xferDest2}, time.Now().Add(time.Minute))
189                    if err != nil {
190                        t.Fatal(err)
191                    }
192         */
193 }
194
195 func tmpManager(t *testing.T) string {
196         d, err := ioutil.TempDir("", "bytom-keystore-test")
197         if err != nil {
198                 t.Fatal(err)
199         }
200         return d
201 }