Skip to content

Commit

Permalink
Add store
Browse files Browse the repository at this point in the history
  • Loading branch information
SpontaneousOverthrow committed Nov 20, 2023
1 parent f4d468b commit 39685da
Show file tree
Hide file tree
Showing 5 changed files with 669 additions and 0 deletions.
226 changes: 226 additions & 0 deletions utils/store/distributed.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
package store

import (
"context"
"fmt"
"regexp"

"github.com/p2p-org/dkc/utils/crypto/bls"
"github.com/pkg/errors"
"github.com/spf13/viper"
e2wallet "github.com/wealdtech/go-eth2-wallet"
types "github.com/wealdtech/go-eth2-wallet-types/v2"
"golang.org/x/exp/maps"
)

type Peers map[uint64]string
type Threshold uint32
type DistributedStore struct {
Type string
Path string
Store map[uint64]types.Store
Peers Peers
Threshold Threshold
Passphrases [][]byte
Ctx context.Context
}

func (s *DistributedStore) Create() error {
for id, peer := range s.Peers {
res, err := regexp.Compile(`:.*`)
if err != nil {
return err
}
store, err := createStore(s.Path + "/" + res.ReplaceAllString(peer, ""))
if err != nil {
return err
}
s.Store[id] = store
}

return nil
}

func (s *DistributedStore) GetWalletsAccountsMap() (WalletAccountsMap, error) {
// We assume that all distributed wallets in the store have the same accounts
peers := maps.Values(s.Peers)
res, err := regexp.Compile(`:.*`)
if err != nil {
return nil, err
}
wa, err := getWalletsAccountsMap(s.Ctx, s.Path+"/"+res.ReplaceAllString(peers[0], ""))
if err != nil {
return nil, err
}

return wa, nil
}

func (s *DistributedStore) CreateWallet(name string) error {
for _, store := range s.Store {
err := e2wallet.UseStore(store)
if err != nil {
return err
}
_, err = e2wallet.CreateWallet(name, e2wallet.WithType(s.Type))
if err != nil {
return err
}
}
return nil
}

func (s *DistributedStore) GetPK(w string, a string) ([]byte, error) {
accounts := map[uint64][]byte{}
res, err := regexp.Compile(`:.*`)
if err != nil {
return nil, err
}

for id, peer := range s.Peers {
wallet, err := getWallet(s.Path+"/"+res.ReplaceAllString(peer, ""), w)
if err != nil {
return nil, err
}
err = wallet.(types.WalletLocker).Unlock(s.Ctx, nil)
if err != nil {
return nil, errors.Wrap(err, "test")
}

defer func() {
err = wallet.(types.WalletLocker).Lock(s.Ctx)
}()

account, err := wallet.(types.WalletAccountByNameProvider).AccountByName(s.Ctx, a)
if err != nil {
return nil, err
}

key, err := getAccountPK(account, s.Ctx, s.Passphrases)
if err != nil {
return nil, err
}

accounts[id] = key

}
key, err := bls.Combine(s.Ctx, accounts)
if err != nil {
return nil, err
}
return key, nil
}

func (s *DistributedStore) SavePKToWallet(w string, a []byte, n string) error {
res, err := regexp.Compile(`:.*`)
if err != nil {
return err
}
// Spliting PK to shards and get Public and Private Keys for each shard
masterSKs, masterPKs, err := bls.Split(s.Ctx, a, uint32(s.Threshold))
if err != nil {
return err
}

peersIDs := maps.Keys(s.Peers)
participants, err := bls.SetupParticipants(masterSKs, masterPKs, peersIDs, len(s.Peers))
if err != nil {
return err
}

for id, peer := range s.Peers {
wallet, err := getWallet(s.Path+"/"+res.ReplaceAllString(peer, ""), w)
if err != nil {
return err
}
err = wallet.(types.WalletLocker).Unlock(s.Ctx, nil)
if err != nil {
return errors.Wrap(err, "test")
}

defer func() {
err = wallet.(types.WalletLocker).Lock(s.Ctx)
}()

_, err = wallet.(types.WalletDistributedAccountImporter).ImportDistributedAccount(
s.Ctx,
n,
participants[id],
uint32(s.Threshold),
masterPKs,
s.Peers,
// Always use the firts password
s.Passphrases[0],
)
if err != nil {
return err
}
}

return nil
}

func newDistributedStore(t string) (DistributedStore, error) {
s := DistributedStore{}
//Parse Wallet Type
wt := viper.GetString(fmt.Sprintf("%s.wallet.type", t))

s.Type = wt

//Parse Store Path
storePath := viper.GetString(fmt.Sprintf("%s.store.path", t))
if storePath == "" {
return s, errors.New("timeout is required")
}
s.Path = storePath

//Parse Passphrases
passphrases, err := getAccountsPasswords(viper.GetString(fmt.Sprintf("%s.wallet.passphrases.path", t)))
if err != nil {
return s, err
}
if len(passphrases) == 0 {
return s, errors.New("timeout is requried")
}
s.Passphrases = passphrases

//Parse Peers
var peers Peers
err = viper.UnmarshalKey(fmt.Sprintf("%s.wallet.peers", t), &peers)
if err != nil {
return s, err
}

//Peers list must be >= 2
if len(peers) < 2 {
return s, errors.New("timeout is required")
}
s.Peers = peers

//Parse Threshold
var threshold Threshold
err = viper.UnmarshalKey(fmt.Sprintf("%s.wallet.threshold", t), &threshold)
if err != nil {
return s, err
}

//Check number of peers and threshold
if uint32(threshold) <= uint32(len(peers)/2) {
return s, errors.New("timeout is required")
}
if uint32(threshold) > uint32(len(peers)) {
return s, errors.New("timeout is required")
}

s.Threshold = threshold

return s, nil
}

func (s *DistributedStore) GetPath() string {
return s.Path
}

func (s *DistributedStore) GetType() string {
return s.Type
}
105 changes: 105 additions & 0 deletions utils/store/hd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package store

import (
"context"
"fmt"

"github.com/pkg/errors"
"github.com/spf13/viper"
e2wallet "github.com/wealdtech/go-eth2-wallet"
types "github.com/wealdtech/go-eth2-wallet-types/v2"
)

type HDStore struct {
Type string
Store types.Store
Path string
Passphrases [][]byte
Wallets map[string][]string
Ctx context.Context
}

func (s *HDStore) Create() error {
store, err := createStore(s.Path)
if err != nil {
return err
}

s.Store = store

return nil
}
func (s *HDStore) GetWalletsAccountsMap() (WalletAccountsMap, error) {
wa, err := getWalletsAccountsMap(s.Ctx, s.Path)
if err != nil {
return nil, err
}

return wa, nil
}

func (s *HDStore) CreateWallet(name string) (types.Wallet, error) {
err := e2wallet.UseStore(s.Store)
if err != nil {
return nil, err
}
wallet, err := e2wallet.CreateWallet(name, e2wallet.WithType(s.Type))
if err != nil {
return nil, errors.Wrap(err, "test")
}
return wallet, nil
}

func (s *HDStore) GetPK(w string, a string) ([]byte, error) {
wallet, err := getWallet(s.Path, w)
if err != nil {
return nil, err
}
account, err := wallet.(types.WalletAccountByNameProvider).AccountByName(s.Ctx, a)
if err != nil {
return nil, err
}

key, err := getAccountPK(account, s.Ctx, s.Passphrases)
if err != nil {
return nil, err
}

return key, nil
}

func (s *HDStore) GetPath() string {
return s.Path
}

func (s *HDStore) GetType() string {
return s.Type
}

func newHDStore(t string) (HDStore, error) {
s := HDStore{}
//Parse Wallet Type
wt := viper.GetString(fmt.Sprintf("%s.wallet.type", t))
s.Type = wt

//Parse Store Path
storePath := viper.GetString(fmt.Sprintf("%s.store.path", t))
if storePath == "" {
return s, errors.New("timeout is required")
}
s.Path = storePath

//Parse Passphrases
passphrases, err := getAccountsPasswords(
viper.GetString(fmt.Sprintf("%s.wallet.passphrases.path", t)),
)
if err != nil {
return s, errors.New("timeout is required")
}
if len(passphrases) == 0 {
return s, errors.New("timeout is requried")
}
s.Passphrases = passphrases

return s, nil
}
Loading

0 comments on commit 39685da

Please sign in to comment.