)
func init() {
+ //Error code 050 represents alias of key duplicated
errorFormatter.Errors[pseudohsm.ErrDuplicateKeyAlias] = httperror.Info{400, "BTM050", "Alias already exists"}
+ //Error code 801 represents query request format error
errorFormatter.Errors[pseudohsm.ErrInvalidAfter] = httperror.Info{400, "BTM801", "Invalid `after` in query"}
+ //Error code 802 represents query reponses too many
errorFormatter.Errors[pseudohsm.ErrTooManyAliasesToList] = httperror.Info{400, "BTM802", "Too many aliases to list"}
}
}
func (a *BlockchainReactor) pseudohsmSignTemplates(ctx context.Context, x struct {
- Auth string
- Txs []*txbuilder.Template `json:"transactions"`
- XPub chainkd.XPub `json:"xpubs"`
- XPrv chainkd.XPrv `json:"xprv"`
+ Auth string
+ Txs []*txbuilder.Template `json:"transactions"`
+ XPub chainkd.XPub `json:"xpubs"`
+ XPrv chainkd.XPrv `json:"xprv"`
}) interface{} {
resp := make([]interface{}, len(x.Txs))
var err error
derived := x.XPrv.Derive(path)
return derived.Sign(data[:]), nil
})
- }else{
+ } else {
err = txbuilder.Sign(ctx, tx, []chainkd.XPub{x.XPub}, x.Auth, a.pseudohsmSignTemplate)
}
"github.com/bytom/protocol"
"github.com/bytom/protocol/bc"
"github.com/bytom/protocol/bc/legacy"
+
dbm "github.com/tendermint/tmlibs/db"
)
Transactions: []*legacy.Tx{},
}
genesisBlock.UnmarshalText(consensus.InitBlock())
+ // tx pool init
txPool := protocol.NewTxPool()
- chain, err := protocol.NewChain(ctx, genesisBlock.Hash(), store, txPool, nil)
+ chain, err := protocol.NewChain(genesisBlock.Hash(), store, txPool)
if err != nil {
t.Fatal(err)
}
+
+ // add gensis block info
+ if err := chain.SaveBlock(genesisBlock); err != nil {
+ t.Fatal(err)
+ }
+ // parse block and apply
+ if err := chain.ConnectBlock(genesisBlock); err != nil {
+ t.Fatal(err)
+ }
+
accUTXODB := dbm.NewDB("accountutxos", config.DBBackend, config.DBDir())
pinStore = pin.NewStore(accUTXODB)
}
accountsDB := dbm.NewDB("account", config.DBBackend, config.DBDir())
accounts = account.NewManager(accountsDB, chain, pinStore)
+ //accounts.IndexAccounts(query.NewIndexer(accountsDB, chain))
assetsDB := dbm.NewDB("asset", config.DBBackend, config.DBDir())
assets = asset.NewRegistry(assetsDB, chain)
if err != nil {
t.Fatal(err)
}
+ //go accounts.ProcessBlocks(ctx)
+
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) {
sigBytes, err := hsm.XSign(xpub, path, data[:], password)
if err != nil {
})
fmt.Printf("###data: %v#####", *tmpl)
+ //err = txbuilder.FinalizeTx(ctx, chain, tmpl.Transaction)
+ //if err != nil {
+ // t.Fatal(err)
+ //}
/*
- c := prottest.NewChain(t)
- assets := asset.NewRegistry(db, c, pinStore)
- accounts å:= account.NewManager(db, c, pinStore)
- coretest.CreatePins(ctx, t, pinStore)
- accounts.IndexAccounts(query.NewIndexer(db, c, pinStore))
- go accounts.ProcessBlocks(ctx)
-
- coretest.SignTxTemplate(t, ctx, tmpl, &testutil.TestXPrv)
- err = txbuilder.FinalizeTx(ctx, c, g, tmpl.Transaction)
- if err != nil {
- t.Fatal(err)
- }
-
- // Make a block so that UTXOs from the above tx are available to spend.
- prottest.MakeBlock(t, c, g.PendingTxs())
- <-pinStore.PinWaiter(account.PinName, c.Height())
-
- xferSrc1 := accounts.NewSpendAction(bc.AssetAmount{AssetId: &asset1ID, Amount: 10}, acct1.ID, nil, nil)
- xferSrc2 := accounts.NewSpendAction(bc.AssetAmount{AssetId: &asset2ID, Amount: 20}, acct2.ID, nil, nil)
- xferDest1 := accounts.NewControlAction(bc.AssetAmount{AssetId: &asset2ID, Amount: 20}, acct1.ID, nil)
- xferDest2 := accounts.NewControlAction(bc.AssetAmount{AssetId: &asset1ID, Amount: 10}, acct2.ID, nil)
- tmpl, err = txbuilder.Build(ctx, nil, []txbuilder.Action{xferSrc1, xferSrc2, xferDest1, xferDest2}, time.Now().Add(time.Minute))
- if err != nil {
- t.Fatal(err)
- }
+ // generate block without nouce
+ b, err := mining.NewBlockTemplate(chain, txPool, []byte{})
+ if err != nil {
+ t.Fatal(err)
+ }
+ //calculate nonce
+ for i := uint64(0); i <= 10000000000000; i++ {
+ b.Nonce = i
+ hash := b.Hash()
+ if consensus.CheckProofOfWork(&hash, b.Bits) {
+ break
+ }
+ }
+ //block validation
+ if _, err = chain.ProcessBlock(b); err != nil {
+ t.Fatal(err)
+ }
+
+ <-pinStore.PinWaiter(account.PinName, chain.Height())
+
+ /*
+ c := prottest.NewChain(t)
+ assets := asset.NewRegistry(db, c, pinStore)
+ accounts å:= account.NewManager(db, c, pinStore)
+ coretest.CreatePins(ctx, t, pinStore)
+ accounts.IndexAccounts(query.NewIndexer(db, c, pinStore))
+ go accounts.ProcessBlocks(ctx)
+
+ coretest.SignTxTemplate(t, ctx, tmpl, &testutil.TestXPrv)
+ err = txbuilder.FinalizeTx(ctx, c, g, tmpl.Transaction)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ // Make a block so that UTXOs from the above tx are available to spend.
+ prottest.MakeBlock(t, c, g.PendingTxs())
+ <-pinStore.PinWaiter(account.PinName, c.Height())
+
+ xferSrc1 := accounts.NewSpendAction(bc.AssetAmount{AssetId: &asset1ID, Amount: 10}, acct1.ID, nil, nil)
+ xferSrc2 := accounts.NewSpendAction(bc.AssetAmount{AssetId: &asset2ID, Amount: 20}, acct2.ID, nil, nil)
+ xferDest1 := accounts.NewControlAction(bc.AssetAmount{AssetId: &asset2ID, Amount: 20}, acct1.ID, nil)
+ xferDest2 := accounts.NewControlAction(bc.AssetAmount{AssetId: &asset1ID, Amount: 10}, acct2.ID, nil)
+ tmpl, err = txbuilder.Build(ctx, nil, []txbuilder.Action{xferSrc1, xferSrc2, xferDest1, xferDest2}, time.Now().Add(time.Minute))
+ if err != nil {
+ t.Fatal(err)
+ }
*/
}
+++ /dev/null
-{"crypto":{"cipher":"aes-128-ctr","ciphertext":"a31b2d9f32e8a0c6aeac8214b002a200ab5aefbc781b79db1b636ca85dc56b312b0e8dc65d8aa6e1a3c7959abaeaab8ced6e912926b011095a1c2fc1c6a1157c","cipherparams":{"iv":"1eca36ed611bafe79e23cdae57cc5131"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":2,"p":1,"r":8,"salt":"705e2522e7261108060a5705355ef98976e9d5a4a7d0e6f4e2d56bfc87dfe122"},"mac":"3fff76fd2a85ef497f7f46634994c6e4ec1ca07ac1584ca9fffd35f27c758d3f"},"id":"0bc1fd55-6fda-4da2-996c-a7394af2f38b","type":"bytom_kd","version":1,"alias":"verylight","xpub":"2c8375f9212aa7946343dae4505aa49bb57ebebcec4f090418bdf30eb2ee8af483ad605a689ca238bbdf0df3be5a7eac06706b58ec4361137b650a23c41dcfbf"}
\ No newline at end of file
+++ /dev/null
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-package pseudohsm
-
-import (
- "bufio"
- "encoding/json"
- "fmt"
- "io/ioutil"
- "os"
- "path/filepath"
- "sort"
- "strings"
- "sync"
- "time"
-
- "github.com/bytom/common"
- log "github.com/sirupsen/logrus"
-
- _ "github.com/bytom/errors"
-)
-
-// Minimum amount of time between cache reloads. This limit applies if the platform does
-// not support change notifications. It also applies if the keystore directory does not
-// exist yet, the code will attempt to create a watcher at most this often.
-const minReloadInterval = 2 * time.Second
-
-type keysByFile []XPub
-
-func (s keysByFile) Len() int { return len(s) }
-func (s keysByFile) Less(i, j int) bool { return s[i].File < s[j].File }
-func (s keysByFile) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
-
-// AmbiguousAddrError is returned when attempting to unlock
-// an address for which more than one file exists.
-type AmbiguousAddrError struct {
- Addr common.Address
- Matches []XPub
-}
-
-func (err *AmbiguousAddrError) Error() string {
- files := ""
- for i, a := range err.Matches {
- files += a.File
- if i < len(err.Matches)-1 {
- files += ", "
- }
- }
- return fmt.Sprintf("multiple keys match address (%s)", files)
-}
-
-// addrCache is a live index of all keys in the keystore.
-type addrCache struct {
- keydir string
- watcher *watcher
- mu sync.Mutex
- all keysByFile
- byAddr map[common.Address][]XPub
- throttle *time.Timer
-}
-
-func newAddrCache(keydir string) *addrCache {
- ac := &addrCache{
- keydir: keydir,
- byAddr: make(map[common.Address][]XPub),
- }
- ac.watcher = newWatcher(ac)
- return ac
-}
-
-func (ac *addrCache) hasAddress(addr common.Address) bool {
- ac.maybeReload()
- ac.mu.Lock()
- defer ac.mu.Unlock()
- return len(ac.byAddr[addr]) > 0
-}
-
-func (ac *addrCache) add(newKey XPub) {
- ac.mu.Lock()
- defer ac.mu.Unlock()
-
- i := sort.Search(len(ac.all), func(i int) bool { return ac.all[i].File >= newKey.File })
- if i < len(ac.all) && ac.all[i] == newKey {
- return
- }
- // newKey is not in the cache.
- ac.all = append(ac.all, XPub{})
- copy(ac.all[i+1:], ac.all[i:])
- ac.all[i] = newKey
- ac.byAddr[newKey.Address] = append(ac.byAddr[newKey.Address], newKey)
-}
-
-func (ac *addrCache) keys() []XPub {
- ac.maybeReload()
- ac.mu.Lock()
- defer ac.mu.Unlock()
- cpy := make([]XPub, len(ac.all))
- copy(cpy, ac.all)
- return cpy
-}
-
-func (ac *addrCache) maybeReload() {
- ac.mu.Lock()
- defer ac.mu.Unlock()
-
- if ac.watcher.running {
- return // A watcher is running and will keep the cache up-to-date.
- }
-
- if ac.throttle == nil {
- ac.throttle = time.NewTimer(0)
- } else {
- select {
- case <-ac.throttle.C:
- default:
- return // The cache was reloaded recently.
- }
- }
- ac.watcher.start()
- ac.reload()
- ac.throttle.Reset(minReloadInterval)
-}
-
-// find returns the cached keys for address if there is a unique match.
-// The exact matching rules are explained by the documentation of Account.
-// Callers must hold ac.mu.
-func (ac *addrCache) find(xpub XPub) (XPub, error) {
- // Limit search to address candidates if possible.
- matches := ac.all
- if (xpub.Address != common.Address{}) {
- matches = ac.byAddr[xpub.Address]
- }
- if xpub.File != "" {
- // If only the basename is specified, complete the path.
- if !strings.ContainsRune(xpub.File, filepath.Separator) {
- xpub.File = filepath.Join(ac.keydir, xpub.File)
- }
- for i := range matches {
- if matches[i].File == xpub.File {
- return matches[i], nil
- }
- }
- if (xpub.Address == common.Address{}) {
- return XPub{}, ErrNoKey
- }
- }
- switch len(matches) {
- case 1:
- return matches[0], nil
- case 0:
- return XPub{}, ErrNoKey
- default:
- err := &AmbiguousAddrError{Addr: xpub.Address, Matches: make([]XPub, len(matches))}
- copy(err.Matches, matches)
- return XPub{}, err
- }
-}
-
-// reload caches addresses of existing key.
-// Callers must hold ac.mu.
-func (ac *addrCache) reload() {
- keys, err := ac.scan()
- if err != nil {
- log.WithField("error", err).Error("can't load keys")
- }
- ac.all = keys
- sort.Sort(ac.all)
- for k := range ac.byAddr {
- delete(ac.byAddr, k)
- }
- for _, k := range keys {
- ac.byAddr[k.Address] = append(ac.byAddr[k.Address], k)
- }
- log.WithField("cache has key", len(ac.all)).Info("reloaded keys")
-}
-
-func (ac *addrCache) scan() ([]XPub, error) {
- files, err := ioutil.ReadDir(ac.keydir)
- if err != nil {
- return nil, err
- }
- var (
- buf = new(bufio.Reader)
- keys []XPub
- keyJSON struct {
- Address common.Address `json:"address"`
- Alias string `json:"alias"`
- }
- )
- for _, fi := range files {
- path := filepath.Join(ac.keydir, fi.Name())
- if skipKeyFile(fi) {
- continue
- }
- fd, err := os.Open(path)
- if err != nil {
- log.WithField("error", err).Info("Os open file error")
- continue
- }
- buf.Reset(fd)
- // Parse the address.
- keyJSON.Address = common.Address{}
- err = json.NewDecoder(buf).Decode(&keyJSON)
- switch {
- case err != nil:
- log.WithFields(log.Fields{"path": path, "error":err,}).Error("Can't decode key")
- case (keyJSON.Address == common.Address{}):
- log.WithFields(log.Fields{"path": path}).Info("Can't decode key, missing or zero address")
- default:
- keys = append(keys, XPub{Address: keyJSON.Address, Alias: keyJSON.Alias, File: path})
- }
- fd.Close()
- }
- return keys, err
-}
-
-func (ac *addrCache) delete(removed XPub) {
- ac.mu.Lock()
- defer ac.mu.Unlock()
- ac.all = removeKey(ac.all, removed)
- if ba := removeKey(ac.byAddr[removed.Address], removed); len(ba) == 0 {
- delete(ac.byAddr, removed.Address)
- } else {
- ac.byAddr[removed.Address] = ba
- }
-}
-
-func removeKey(slice []XPub, elem XPub) []XPub {
- for i := range slice {
- if slice[i] == elem {
- return append(slice[:i], slice[i+1:]...)
- }
- }
- return slice
-}
-
-func skipKeyFile(fi os.FileInfo) bool {
- // Skip editor backups and UNIX-style hidden files.
- if strings.HasSuffix(fi.Name(), "~") || strings.HasPrefix(fi.Name(), ".") {
- return true
- }
- // Skip misc special files, directories (yes, symlinks too).
- if fi.IsDir() || fi.Mode()&os.ModeType != 0 {
- return true
- }
- return false
-}
-
-func (ac *addrCache) close() {
- ac.mu.Lock()
- ac.watcher.close()
- if ac.throttle != nil {
- ac.throttle.Stop()
- }
- ac.mu.Unlock()
-}