From f90cfda2e63a90eb9ec6874b21c96b134177681f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 4 Sep 2020 22:17:28 +0200 Subject: [PATCH] wallet: Add interface layer --- chain/gen/gen.go | 20 ++--- chain/gen/mining.go | 4 +- chain/messagepool/messagepool_test.go | 24 +++--- chain/messagepool/repub_test.go | 5 +- chain/messagepool/selection_test.go | 44 +++++----- chain/stmgr/forks_test.go | 4 +- chain/sync_test.go | 2 +- chain/types/mock/chain.go | 4 +- chain/vectors/gen/main.go | 9 +- chain/wallet/interface.go | 27 ++++++ chain/wallet/key.go | 81 ++++++++++++++++++ chain/wallet/wallet.go | 114 +++++++------------------- cmd/lotus-keygen/main.go | 4 +- cmd/lotus-shed/keyinfo.go | 2 +- markets/storageadapter/client.go | 4 +- node/builder.go | 4 +- node/impl/full/state.go | 2 +- node/impl/full/wallet.go | 45 ++-------- 18 files changed, 214 insertions(+), 185 deletions(-) create mode 100644 chain/wallet/interface.go create mode 100644 chain/wallet/key.go diff --git a/chain/gen/gen.go b/chain/gen/gen.go index 551c3703f..4ba127ce9 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -68,7 +68,7 @@ type ChainGen struct { GetMessages func(*ChainGen) ([]*types.SignedMessage, error) - w *wallet.Wallet + w *wallet.LocalWallet eppProvs map[address.Address]WinningPoStProver Miners []address.Address @@ -151,14 +151,14 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) { return nil, xerrors.Errorf("creating memrepo wallet failed: %w", err) } - banker, err := w.GenerateKey(crypto.SigTypeSecp256k1) + banker, err := w.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { return nil, xerrors.Errorf("failed to generate banker key: %w", err) } receievers := make([]address.Address, msgsPerBlock) for r := range receievers { - receievers[r], err = w.GenerateKey(crypto.SigTypeBLS) + receievers[r], err = w.WalletNew(context.Background(), crypto.SigTypeBLS) if err != nil { return nil, xerrors.Errorf("failed to generate receiver key: %w", err) } @@ -188,11 +188,11 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) { return nil, err } - mk1, err := w.Import(k1) + mk1, err := w.WalletImport(context.Background(), k1) if err != nil { return nil, err } - mk2, err := w.Import(k2) + mk2, err := w.WalletImport(context.Background(), k2) if err != nil { return nil, err } @@ -372,7 +372,7 @@ func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m add return nil, nil, nil, xerrors.Errorf("get miner worker: %w", err) } - vrfout, err := ComputeVRF(ctx, cg.w.Sign, worker, ticketRand) + vrfout, err := ComputeVRF(ctx, cg.w.WalletSign, worker, ticketRand) if err != nil { return nil, nil, nil, xerrors.Errorf("compute VRF: %w", err) } @@ -501,7 +501,7 @@ func (cg *ChainGen) Banker() address.Address { return cg.banker } -func (cg *ChainGen) Wallet() *wallet.Wallet { +func (cg *ChainGen) Wallet() *wallet.LocalWallet { return cg.w } @@ -523,7 +523,7 @@ func getRandomMessages(cg *ChainGen) ([]*types.SignedMessage, error) { GasPremium: types.NewInt(0), } - sig, err := cg.w.Sign(context.TODO(), cg.banker, msg.Cid().Bytes()) + sig, err := cg.w.WalletSign(context.TODO(), cg.banker, msg.Cid().Bytes()) if err != nil { return nil, err } @@ -554,7 +554,7 @@ type MiningCheckAPI interface { } type mca struct { - w *wallet.Wallet + w *wallet.LocalWallet sm *stmgr.StateManager pv ffiwrapper.Verifier bcn beacon.RandomBeacon @@ -583,7 +583,7 @@ func (mca mca) MinerGetBaseInfo(ctx context.Context, maddr address.Address, epoc } func (mca mca) WalletSign(ctx context.Context, a address.Address, v []byte) (*crypto.Signature, error) { - return mca.w.Sign(ctx, a, v) + return mca.w.WalletSign(ctx, a, v) } type WinningPoStProver interface { diff --git a/chain/gen/mining.go b/chain/gen/mining.go index 260c96808..a9ac47a60 100644 --- a/chain/gen/mining.go +++ b/chain/gen/mining.go @@ -19,7 +19,7 @@ import ( "github.com/filecoin-project/lotus/lib/sigs/bls" ) -func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.Wallet, bt *api.BlockTemplate) (*types.FullBlock, error) { +func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.LocalWallet, bt *api.BlockTemplate) (*types.FullBlock, error) { pts, err := sm.ChainStore().LoadTipSet(bt.Parents) if err != nil { @@ -131,7 +131,7 @@ func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.Wal return nil, xerrors.Errorf("failed to get signing bytes for block: %w", err) } - sig, err := w.Sign(ctx, waddr, nosigbytes) + sig, err := w.WalletSign(ctx, waddr, nosigbytes) if err != nil { return nil, xerrors.Errorf("failed to sign new block: %w", err) } diff --git a/chain/messagepool/messagepool_test.go b/chain/messagepool/messagepool_test.go index 484c72746..cf77f3fb0 100644 --- a/chain/messagepool/messagepool_test.go +++ b/chain/messagepool/messagepool_test.go @@ -221,7 +221,7 @@ func TestMessagePool(t *testing.T) { a := tma.nextBlock() - sender, err := w.GenerateKey(crypto.SigTypeBLS) + sender, err := w.WalletNew(context.Background(), crypto.SigTypeBLS) if err != nil { t.Fatal(err) } @@ -262,7 +262,7 @@ func TestMessagePoolMessagesInEachBlock(t *testing.T) { a := tma.nextBlock() - sender, err := w.GenerateKey(crypto.SigTypeBLS) + sender, err := w.WalletNew(context.Background(), crypto.SigTypeBLS) if err != nil { t.Fatal(err) } @@ -312,7 +312,7 @@ func TestRevertMessages(t *testing.T) { a := tma.nextBlock() b := tma.nextBlock() - sender, err := w.GenerateKey(crypto.SigTypeBLS) + sender, err := w.WalletNew(context.Background(), crypto.SigTypeBLS) if err != nil { t.Fatal(err) } @@ -375,7 +375,7 @@ func TestPruningSimple(t *testing.T) { a := tma.nextBlock() tma.applyBlock(t, a) - sender, err := w.GenerateKey(crypto.SigTypeBLS) + sender, err := w.WalletNew(context.Background(), crypto.SigTypeBLS) if err != nil { t.Fatal(err) } @@ -422,7 +422,7 @@ func TestLoadLocal(t *testing.T) { t.Fatal(err) } - a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1) + a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } @@ -432,7 +432,7 @@ func TestLoadLocal(t *testing.T) { t.Fatal(err) } - a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1) + a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } @@ -494,7 +494,7 @@ func TestClearAll(t *testing.T) { t.Fatal(err) } - a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1) + a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } @@ -504,7 +504,7 @@ func TestClearAll(t *testing.T) { t.Fatal(err) } - a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1) + a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } @@ -548,7 +548,7 @@ func TestClearNonLocal(t *testing.T) { t.Fatal(err) } - a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1) + a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } @@ -558,7 +558,7 @@ func TestClearNonLocal(t *testing.T) { t.Fatal(err) } - a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1) + a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } @@ -609,7 +609,7 @@ func TestUpdates(t *testing.T) { t.Fatal(err) } - a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1) + a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } @@ -619,7 +619,7 @@ func TestUpdates(t *testing.T) { t.Fatal(err) } - a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1) + a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } diff --git a/chain/messagepool/repub_test.go b/chain/messagepool/repub_test.go index c89367f0e..2e3fa123f 100644 --- a/chain/messagepool/repub_test.go +++ b/chain/messagepool/repub_test.go @@ -1,6 +1,7 @@ package messagepool import ( + "context" "testing" "time" @@ -32,7 +33,7 @@ func TestRepubMessages(t *testing.T) { t.Fatal(err) } - a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1) + a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } @@ -42,7 +43,7 @@ func TestRepubMessages(t *testing.T) { t.Fatal(err) } - a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1) + a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } diff --git a/chain/messagepool/selection_test.go b/chain/messagepool/selection_test.go index a9ead3c01..ecbf08b13 100644 --- a/chain/messagepool/selection_test.go +++ b/chain/messagepool/selection_test.go @@ -29,7 +29,7 @@ func init() { MaxActorPendingMessages = 1000000 } -func makeTestMessage(w *wallet.Wallet, from, to address.Address, nonce uint64, gasLimit int64, gasPrice uint64) *types.SignedMessage { +func makeTestMessage(w *wallet.LocalWallet, from, to address.Address, nonce uint64, gasLimit int64, gasPrice uint64) *types.SignedMessage { msg := &types.Message{ From: from, To: to, @@ -40,7 +40,7 @@ func makeTestMessage(w *wallet.Wallet, from, to address.Address, nonce uint64, g GasFeeCap: types.NewInt(100 + gasPrice), GasPremium: types.NewInt(gasPrice), } - sig, err := w.Sign(context.TODO(), from, msg.Cid().Bytes()) + sig, err := w.WalletSign(context.TODO(), from, msg.Cid().Bytes()) if err != nil { panic(err) } @@ -70,7 +70,7 @@ func TestMessageChains(t *testing.T) { t.Fatal(err) } - a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1) + a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } @@ -80,7 +80,7 @@ func TestMessageChains(t *testing.T) { t.Fatal(err) } - a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1) + a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } @@ -308,7 +308,7 @@ func TestMessageChainSkipping(t *testing.T) { t.Fatal(err) } - a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1) + a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } @@ -318,7 +318,7 @@ func TestMessageChainSkipping(t *testing.T) { t.Fatal(err) } - a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1) + a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } @@ -384,7 +384,7 @@ func TestBasicMessageSelection(t *testing.T) { t.Fatal(err) } - a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1) + a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } @@ -394,7 +394,7 @@ func TestBasicMessageSelection(t *testing.T) { t.Fatal(err) } - a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1) + a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } @@ -528,7 +528,7 @@ func TestMessageSelectionTrimming(t *testing.T) { t.Fatal(err) } - a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1) + a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } @@ -538,7 +538,7 @@ func TestMessageSelectionTrimming(t *testing.T) { t.Fatal(err) } - a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1) + a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } @@ -591,7 +591,7 @@ func TestPriorityMessageSelection(t *testing.T) { t.Fatal(err) } - a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1) + a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } @@ -601,7 +601,7 @@ func TestPriorityMessageSelection(t *testing.T) { t.Fatal(err) } - a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1) + a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } @@ -670,7 +670,7 @@ func TestPriorityMessageSelection2(t *testing.T) { t.Fatal(err) } - a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1) + a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } @@ -680,7 +680,7 @@ func TestPriorityMessageSelection2(t *testing.T) { t.Fatal(err) } - a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1) + a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } @@ -740,7 +740,7 @@ func TestOptimalMessageSelection1(t *testing.T) { t.Fatal(err) } - a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1) + a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } @@ -750,7 +750,7 @@ func TestOptimalMessageSelection1(t *testing.T) { t.Fatal(err) } - a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1) + a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } @@ -807,7 +807,7 @@ func TestOptimalMessageSelection2(t *testing.T) { t.Fatal(err) } - a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1) + a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } @@ -817,7 +817,7 @@ func TestOptimalMessageSelection2(t *testing.T) { t.Fatal(err) } - a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1) + a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } @@ -883,7 +883,7 @@ func TestOptimalMessageSelection3(t *testing.T) { nActors := 10 // the actors var actors []address.Address - var wallets []*wallet.Wallet + var wallets []*wallet.LocalWallet for i := 0; i < nActors; i++ { w, err := wallet.NewWallet(wallet.NewMemKeyStore()) @@ -891,7 +891,7 @@ func TestOptimalMessageSelection3(t *testing.T) { t.Fatal(err) } - a, err := w.GenerateKey(crypto.SigTypeSecp256k1) + a, err := w.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } @@ -963,7 +963,7 @@ func testCompetitiveMessageSelection(t *testing.T, rng *rand.Rand, getPremium fu nActors := 300 // the actors var actors []address.Address - var wallets []*wallet.Wallet + var wallets []*wallet.LocalWallet for i := 0; i < nActors; i++ { w, err := wallet.NewWallet(wallet.NewMemKeyStore()) @@ -971,7 +971,7 @@ func testCompetitiveMessageSelection(t *testing.T, rng *rand.Rand, getPremium fu t.Fatal(err) } - a, err := w.GenerateKey(crypto.SigTypeSecp256k1) + a, err := w.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } diff --git a/chain/stmgr/forks_test.go b/chain/stmgr/forks_test.go index caa63c879..e5874d51d 100644 --- a/chain/stmgr/forks_test.go +++ b/chain/stmgr/forks_test.go @@ -174,7 +174,7 @@ func TestForkHeightTriggers(t *testing.T) { Params: enc, GasLimit: types.TestGasLimit, } - sig, err := cg.Wallet().Sign(ctx, cg.Banker(), m.Cid().Bytes()) + sig, err := cg.Wallet().WalletSign(ctx, cg.Banker(), m.Cid().Bytes()) if err != nil { t.Fatal(err) } @@ -202,7 +202,7 @@ func TestForkHeightTriggers(t *testing.T) { } nonce++ - sig, err := cg.Wallet().Sign(ctx, cg.Banker(), m.Cid().Bytes()) + sig, err := cg.Wallet().WalletSign(ctx, cg.Banker(), m.Cid().Bytes()) if err != nil { return nil, err } diff --git a/chain/sync_test.go b/chain/sync_test.go index cf1385baa..9a98b3b36 100644 --- a/chain/sync_test.go +++ b/chain/sync_test.go @@ -566,7 +566,7 @@ func TestDuplicateNonce(t *testing.T) { GasPremium: types.NewInt(0), } - sig, err := tu.g.Wallet().Sign(context.TODO(), tu.g.Banker(), msg.Cid().Bytes()) + sig, err := tu.g.Wallet().WalletSign(context.TODO(), tu.g.Banker(), msg.Cid().Bytes()) require.NoError(t, err) return &types.SignedMessage{ diff --git a/chain/types/mock/chain.go b/chain/types/mock/chain.go index 33b13d408..19b1352ad 100644 --- a/chain/types/mock/chain.go +++ b/chain/types/mock/chain.go @@ -21,7 +21,7 @@ func Address(i uint64) address.Address { return a } -func MkMessage(from, to address.Address, nonce uint64, w *wallet.Wallet) *types.SignedMessage { +func MkMessage(from, to address.Address, nonce uint64, w *wallet.LocalWallet) *types.SignedMessage { msg := &types.Message{ To: to, From: from, @@ -32,7 +32,7 @@ func MkMessage(from, to address.Address, nonce uint64, w *wallet.Wallet) *types. GasPremium: types.NewInt(1), } - sig, err := w.Sign(context.TODO(), from, msg.Cid().Bytes()) + sig, err := w.WalletSign(context.TODO(), from, msg.Cid().Bytes()) if err != nil { panic(err) } diff --git a/chain/vectors/gen/main.go b/chain/vectors/gen/main.go index ce8d137e8..631fb6ad1 100644 --- a/chain/vectors/gen/main.go +++ b/chain/vectors/gen/main.go @@ -1,6 +1,7 @@ package main import ( + "context" "encoding/json" "fmt" "math/rand" @@ -63,11 +64,11 @@ func MakeMessageSigningVectors() []vectors.MessageSigningVector { panic(err) } - blsk, err := w.GenerateKey(crypto.SigTypeBLS) + blsk, err := w.WalletNew(context.Background(), crypto.SigTypeBLS) if err != nil { panic(err) } - bki, err := w.Export(blsk) + bki, err := w.WalletExport(context.Background(), blsk) if err != nil { panic(err) } @@ -87,11 +88,11 @@ func MakeMessageSigningVectors() []vectors.MessageSigningVector { Signature: &bmsg.Signature, } - secpk, err := w.GenerateKey(crypto.SigTypeBLS) + secpk, err := w.WalletNew(context.Background(), crypto.SigTypeBLS) if err != nil { panic(err) } - ski, err := w.Export(secpk) + ski, err := w.WalletExport(context.Background(), secpk) if err != nil { panic(err) } diff --git a/chain/wallet/interface.go b/chain/wallet/interface.go new file mode 100644 index 000000000..9dc95a32c --- /dev/null +++ b/chain/wallet/interface.go @@ -0,0 +1,27 @@ +package wallet + +import ( + "context" + + "github.com/filecoin-project/go-address" + + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/specs-actors/actors/crypto" +) + +type Wallet interface { + WalletNew(context.Context, crypto.SigType) (address.Address, error) + WalletHas(context.Context, address.Address) (bool, error) + WalletList(context.Context) ([]address.Address, error) + WalletSign(context.Context, address.Address, []byte) (*crypto.Signature, error) + // nonce keeping done by wallet app + WalletSignMessage(context.Context, address.Address, *types.Message) (*types.SignedMessage, error) + WalletExport(context.Context, address.Address) (*types.KeyInfo, error) + WalletImport(context.Context, *types.KeyInfo) (address.Address, error) + WalletDelete(context.Context, address.Address) error +} + +type Default interface { + GetDefault() (address.Address, error) + SetDefault(a address.Address) error +} diff --git a/chain/wallet/key.go b/chain/wallet/key.go new file mode 100644 index 000000000..2d4ecafd7 --- /dev/null +++ b/chain/wallet/key.go @@ -0,0 +1,81 @@ +package wallet + +import ( + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/specs-actors/actors/crypto" + + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/lib/sigs" +) + +func GenerateKey(typ crypto.SigType) (*Key, error) { + pk, err := sigs.Generate(typ) + if err != nil { + return nil, err + } + ki := types.KeyInfo{ + Type: kstoreSigType(typ), + PrivateKey: pk, + } + return NewKey(ki) +} + +type Key struct { + types.KeyInfo + + PublicKey []byte + Address address.Address +} + +func NewKey(keyinfo types.KeyInfo) (*Key, error) { + k := &Key{ + KeyInfo: keyinfo, + } + + var err error + k.PublicKey, err = sigs.ToPublic(ActSigType(k.Type), k.PrivateKey) + if err != nil { + return nil, err + } + + switch k.Type { + case KTSecp256k1: + k.Address, err = address.NewSecp256k1Address(k.PublicKey) + if err != nil { + return nil, xerrors.Errorf("converting Secp256k1 to address: %w", err) + } + case KTBLS: + k.Address, err = address.NewBLSAddress(k.PublicKey) + if err != nil { + return nil, xerrors.Errorf("converting BLS to address: %w", err) + } + default: + return nil, xerrors.Errorf("unknown key type") + } + return k, nil + +} + +func kstoreSigType(typ crypto.SigType) string { + switch typ { + case crypto.SigTypeBLS: + return KTBLS + case crypto.SigTypeSecp256k1: + return KTSecp256k1 + default: + return "" + } +} + +func ActSigType(typ string) crypto.SigType { + switch typ { + case KTBLS: + return crypto.SigTypeBLS + case KTSecp256k1: + return crypto.SigTypeSecp256k1 + default: + return 0 + } +} diff --git a/chain/wallet/wallet.go b/chain/wallet/wallet.go index 9c069d819..7fdea8963 100644 --- a/chain/wallet/wallet.go +++ b/chain/wallet/wallet.go @@ -29,15 +29,15 @@ const ( KTSecp256k1 = "secp256k1" ) -type Wallet struct { +type LocalWallet struct { keys map[address.Address]*Key keystore types.KeyStore lk sync.Mutex } -func NewWallet(keystore types.KeyStore) (*Wallet, error) { - w := &Wallet{ +func NewWallet(keystore types.KeyStore) (*LocalWallet, error) { + w := &LocalWallet{ keys: make(map[address.Address]*Key), keystore: keystore, } @@ -45,18 +45,18 @@ func NewWallet(keystore types.KeyStore) (*Wallet, error) { return w, nil } -func KeyWallet(keys ...*Key) *Wallet { +func KeyWallet(keys ...*Key) *LocalWallet { m := make(map[address.Address]*Key) for _, key := range keys { m[key.Address] = key } - return &Wallet{ + return &LocalWallet{ keys: m, } } -func (w *Wallet) Sign(ctx context.Context, addr address.Address, msg []byte) (*crypto.Signature, error) { +func (w *LocalWallet) WalletSign(ctx context.Context, addr address.Address, msg []byte) (*crypto.Signature, error) { ki, err := w.findKey(addr) if err != nil { return nil, err @@ -68,7 +68,21 @@ func (w *Wallet) Sign(ctx context.Context, addr address.Address, msg []byte) (*c return sigs.Sign(ActSigType(ki.Type), ki.PrivateKey, msg) } -func (w *Wallet) findKey(addr address.Address) (*Key, error) { +func (w *LocalWallet) WalletSignMessage(ctx context.Context, k address.Address, msg *types.Message) (*types.SignedMessage, error) { + mcid := msg.Cid() + + sig, err := w.WalletSign(ctx, k, mcid.Bytes()) + if err != nil { + return nil, xerrors.Errorf("failed to sign message: %w", err) + } + + return &types.SignedMessage{ + Message: *msg, + Signature: *sig, + }, nil +} + +func (w *LocalWallet) findKey(addr address.Address) (*Key, error) { w.lk.Lock() defer w.lk.Unlock() @@ -96,7 +110,7 @@ func (w *Wallet) findKey(addr address.Address) (*Key, error) { return k, nil } -func (w *Wallet) Export(addr address.Address) (*types.KeyInfo, error) { +func (w *LocalWallet) WalletExport(ctx context.Context, addr address.Address) (*types.KeyInfo, error) { k, err := w.findKey(addr) if err != nil { return nil, xerrors.Errorf("failed to find key to export: %w", err) @@ -105,7 +119,7 @@ func (w *Wallet) Export(addr address.Address) (*types.KeyInfo, error) { return &k.KeyInfo, nil } -func (w *Wallet) Import(ki *types.KeyInfo) (address.Address, error) { +func (w *LocalWallet) WalletImport(ctx context.Context, ki *types.KeyInfo) (address.Address, error) { w.lk.Lock() defer w.lk.Unlock() @@ -121,7 +135,7 @@ func (w *Wallet) Import(ki *types.KeyInfo) (address.Address, error) { return k.Address, nil } -func (w *Wallet) ListAddrs() ([]address.Address, error) { +func (w *LocalWallet) WalletList(ctx context.Context) ([]address.Address, error) { all, err := w.keystore.List() if err != nil { return nil, xerrors.Errorf("listing keystore: %w", err) @@ -144,7 +158,7 @@ func (w *Wallet) ListAddrs() ([]address.Address, error) { return out, nil } -func (w *Wallet) GetDefault() (address.Address, error) { +func (w *LocalWallet) GetDefault() (address.Address, error) { w.lk.Lock() defer w.lk.Unlock() @@ -161,7 +175,7 @@ func (w *Wallet) GetDefault() (address.Address, error) { return k.Address, nil } -func (w *Wallet) SetDefault(a address.Address) error { +func (w *LocalWallet) SetDefault(a address.Address) error { w.lk.Lock() defer w.lk.Unlock() @@ -183,19 +197,7 @@ func (w *Wallet) SetDefault(a address.Address) error { return nil } -func GenerateKey(typ crypto.SigType) (*Key, error) { - pk, err := sigs.Generate(typ) - if err != nil { - return nil, err - } - ki := types.KeyInfo{ - Type: kstoreSigType(typ), - PrivateKey: pk, - } - return NewKey(ki) -} - -func (w *Wallet) GenerateKey(typ crypto.SigType) (address.Address, error) { +func (w *LocalWallet) WalletNew(ctx context.Context, typ crypto.SigType) (address.Address, error) { w.lk.Lock() defer w.lk.Unlock() @@ -223,7 +225,7 @@ func (w *Wallet) GenerateKey(typ crypto.SigType) (address.Address, error) { return k.Address, nil } -func (w *Wallet) HasKey(addr address.Address) (bool, error) { +func (w *LocalWallet) WalletHas(ctx context.Context, addr address.Address) (bool, error) { k, err := w.findKey(addr) if err != nil { return false, err @@ -231,7 +233,7 @@ func (w *Wallet) HasKey(addr address.Address) (bool, error) { return k != nil, nil } -func (w *Wallet) DeleteKey(addr address.Address) error { +func (w *LocalWallet) WalletDelete(ctx context.Context, addr address.Address) error { k, err := w.findKey(addr) if err != nil { return xerrors.Errorf("failed to delete key %s : %w", addr, err) @@ -248,60 +250,4 @@ func (w *Wallet) DeleteKey(addr address.Address) error { return nil } -type Key struct { - types.KeyInfo - - PublicKey []byte - Address address.Address -} - -func NewKey(keyinfo types.KeyInfo) (*Key, error) { - k := &Key{ - KeyInfo: keyinfo, - } - - var err error - k.PublicKey, err = sigs.ToPublic(ActSigType(k.Type), k.PrivateKey) - if err != nil { - return nil, err - } - - switch k.Type { - case KTSecp256k1: - k.Address, err = address.NewSecp256k1Address(k.PublicKey) - if err != nil { - return nil, xerrors.Errorf("converting Secp256k1 to address: %w", err) - } - case KTBLS: - k.Address, err = address.NewBLSAddress(k.PublicKey) - if err != nil { - return nil, xerrors.Errorf("converting BLS to address: %w", err) - } - default: - return nil, xerrors.Errorf("unknown key type") - } - return k, nil - -} - -func kstoreSigType(typ crypto.SigType) string { - switch typ { - case crypto.SigTypeBLS: - return KTBLS - case crypto.SigTypeSecp256k1: - return KTSecp256k1 - default: - return "" - } -} - -func ActSigType(typ string) crypto.SigType { - switch typ { - case KTBLS: - return crypto.SigTypeBLS - case KTSecp256k1: - return crypto.SigTypeSecp256k1 - default: - return 0 - } -} +var _ Wallet = &LocalWallet{} diff --git a/cmd/lotus-keygen/main.go b/cmd/lotus-keygen/main.go index 33124107e..8835a0928 100644 --- a/cmd/lotus-keygen/main.go +++ b/cmd/lotus-keygen/main.go @@ -40,12 +40,12 @@ func main() { return fmt.Errorf("unrecognized key type: %q", cctx.String("type")) } - kaddr, err := w.GenerateKey(kt) + kaddr, err := w.WalletNew(cctx.Context, kt) if err != nil { return err } - ki, err := w.Export(kaddr) + ki, err := w.WalletExport(cctx.Context, kaddr) if err != nil { return err } diff --git a/cmd/lotus-shed/keyinfo.go b/cmd/lotus-shed/keyinfo.go index f397bd4c7..b2ff97e4e 100644 --- a/cmd/lotus-shed/keyinfo.go +++ b/cmd/lotus-shed/keyinfo.go @@ -130,7 +130,7 @@ var keyinfoImportCmd = &cli.Command{ return err } - addr, err := w.Import(&keyInfo) + addr, err := w.WalletImport(cctx.Context, &keyInfo) if err != nil { return err } diff --git a/markets/storageadapter/client.go b/markets/storageadapter/client.go index 91fc6a054..03e5b5353 100644 --- a/markets/storageadapter/client.go +++ b/markets/storageadapter/client.go @@ -440,7 +440,7 @@ func (c *ClientNodeAdapter) SignProposal(ctx context.Context, signer address.Add return nil, err } - sig, err := c.Wallet.Sign(ctx, signer, buf) + sig, err := c.Wallet.WalletSign(ctx, signer, buf) if err != nil { return nil, err } @@ -524,7 +524,7 @@ func (c *ClientNodeAdapter) SignBytes(ctx context.Context, signer address.Addres return nil, err } - localSignature, err := c.Wallet.Sign(ctx, signer, b) + localSignature, err := c.Wallet.WalletSign(ctx, signer, b) if err != nil { return nil, err } diff --git a/node/builder.go b/node/builder.go index 5b6966cd4..7c3251df2 100644 --- a/node/builder.go +++ b/node/builder.go @@ -234,7 +234,9 @@ func Online() Option { Override(new(vm.SyscallBuilder), vm.Syscalls), Override(new(*store.ChainStore), modules.ChainStore), Override(new(*stmgr.StateManager), stmgr.NewStateManager), - Override(new(*wallet.Wallet), wallet.NewWallet), + Override(new(*wallet.LocalWallet), wallet.NewWallet), + Override(new(wallet.Wallet), From(new(*wallet.LocalWallet))), + Override(new(wallet.Default), From(new(*wallet.LocalWallet))), Override(new(dtypes.ChainGCLocker), blockstore.NewGCLocker), Override(new(dtypes.ChainGCBlockstore), modules.ChainGCBlockstore), diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 36721a93d..0e1aad27c 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -48,7 +48,7 @@ type StateAPI struct { // TODO: the wallet here is only needed because we have the MinerCreateBlock // API attached to the state API. It probably should live somewhere better - Wallet *wallet.Wallet + Wallet *wallet.LocalWallet ProofVerifier ffiwrapper.Verifier StateManager *stmgr.StateManager diff --git a/node/impl/full/wallet.go b/node/impl/full/wallet.go index 440f9642f..22b674737 100644 --- a/node/impl/full/wallet.go +++ b/node/impl/full/wallet.go @@ -20,19 +20,8 @@ type WalletAPI struct { fx.In StateManager *stmgr.StateManager - Wallet *wallet.Wallet -} - -func (a *WalletAPI) WalletNew(ctx context.Context, typ crypto.SigType) (address.Address, error) { - return a.Wallet.GenerateKey(typ) -} - -func (a *WalletAPI) WalletHas(ctx context.Context, addr address.Address) (bool, error) { - return a.Wallet.HasKey(addr) -} - -func (a *WalletAPI) WalletList(ctx context.Context) ([]address.Address, error) { - return a.Wallet.ListAddrs() + Default wallet.Default + wallet.Wallet } func (a *WalletAPI) WalletBalance(ctx context.Context, addr address.Address) (types.BigInt, error) { @@ -53,21 +42,15 @@ func (a *WalletAPI) WalletSign(ctx context.Context, k address.Address, msg []byt if err != nil { return nil, xerrors.Errorf("failed to resolve ID address: %w", keyAddr) } - return a.Wallet.Sign(ctx, keyAddr, msg) + return a.WalletSign(ctx, keyAddr, msg) } func (a *WalletAPI) WalletSignMessage(ctx context.Context, k address.Address, msg *types.Message) (*types.SignedMessage, error) { - mcid := msg.Cid() - - sig, err := a.WalletSign(ctx, k, mcid.Bytes()) + keyAddr, err := a.StateManager.ResolveToKeyAddress(ctx, k, nil) if err != nil { - return nil, xerrors.Errorf("failed to sign message: %w", err) + return nil, xerrors.Errorf("failed to resolve ID address: %w", keyAddr) } - - return &types.SignedMessage{ - Message: *msg, - Signature: *sig, - }, nil + return a.Wallet.WalletSignMessage(ctx, keyAddr, msg) } func (a *WalletAPI) WalletVerify(ctx context.Context, k address.Address, msg []byte, sig *crypto.Signature) bool { @@ -75,21 +58,9 @@ func (a *WalletAPI) WalletVerify(ctx context.Context, k address.Address, msg []b } func (a *WalletAPI) WalletDefaultAddress(ctx context.Context) (address.Address, error) { - return a.Wallet.GetDefault() + return a.Default.GetDefault() } func (a *WalletAPI) WalletSetDefault(ctx context.Context, addr address.Address) error { - return a.Wallet.SetDefault(addr) -} - -func (a *WalletAPI) WalletExport(ctx context.Context, addr address.Address) (*types.KeyInfo, error) { - return a.Wallet.Export(addr) -} - -func (a *WalletAPI) WalletImport(ctx context.Context, ki *types.KeyInfo) (address.Address, error) { - return a.Wallet.Import(ki) -} - -func (a *WalletAPI) WalletDelete(ctx context.Context, addr address.Address) error { - return a.Wallet.DeleteKey(addr) + return a.Default.SetDefault(addr) }