wallet: Add interface layer

This commit is contained in:
Łukasz Magiera 2020-09-04 22:17:28 +02:00
parent 52ce80f2b4
commit f90cfda2e6
18 changed files with 214 additions and 185 deletions

View File

@ -68,7 +68,7 @@ type ChainGen struct {
GetMessages func(*ChainGen) ([]*types.SignedMessage, error) GetMessages func(*ChainGen) ([]*types.SignedMessage, error)
w *wallet.Wallet w *wallet.LocalWallet
eppProvs map[address.Address]WinningPoStProver eppProvs map[address.Address]WinningPoStProver
Miners []address.Address Miners []address.Address
@ -151,14 +151,14 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
return nil, xerrors.Errorf("creating memrepo wallet failed: %w", err) 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 { if err != nil {
return nil, xerrors.Errorf("failed to generate banker key: %w", err) return nil, xerrors.Errorf("failed to generate banker key: %w", err)
} }
receievers := make([]address.Address, msgsPerBlock) receievers := make([]address.Address, msgsPerBlock)
for r := range receievers { for r := range receievers {
receievers[r], err = w.GenerateKey(crypto.SigTypeBLS) receievers[r], err = w.WalletNew(context.Background(), crypto.SigTypeBLS)
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed to generate receiver key: %w", err) return nil, xerrors.Errorf("failed to generate receiver key: %w", err)
} }
@ -188,11 +188,11 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
return nil, err return nil, err
} }
mk1, err := w.Import(k1) mk1, err := w.WalletImport(context.Background(), k1)
if err != nil { if err != nil {
return nil, err return nil, err
} }
mk2, err := w.Import(k2) mk2, err := w.WalletImport(context.Background(), k2)
if err != nil { if err != nil {
return nil, err 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) 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 { if err != nil {
return nil, nil, nil, xerrors.Errorf("compute VRF: %w", err) return nil, nil, nil, xerrors.Errorf("compute VRF: %w", err)
} }
@ -501,7 +501,7 @@ func (cg *ChainGen) Banker() address.Address {
return cg.banker return cg.banker
} }
func (cg *ChainGen) Wallet() *wallet.Wallet { func (cg *ChainGen) Wallet() *wallet.LocalWallet {
return cg.w return cg.w
} }
@ -523,7 +523,7 @@ func getRandomMessages(cg *ChainGen) ([]*types.SignedMessage, error) {
GasPremium: types.NewInt(0), 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 { if err != nil {
return nil, err return nil, err
} }
@ -554,7 +554,7 @@ type MiningCheckAPI interface {
} }
type mca struct { type mca struct {
w *wallet.Wallet w *wallet.LocalWallet
sm *stmgr.StateManager sm *stmgr.StateManager
pv ffiwrapper.Verifier pv ffiwrapper.Verifier
bcn beacon.RandomBeacon 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) { 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 { type WinningPoStProver interface {

View File

@ -19,7 +19,7 @@ import (
"github.com/filecoin-project/lotus/lib/sigs/bls" "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) pts, err := sm.ChainStore().LoadTipSet(bt.Parents)
if err != nil { 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) 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 { if err != nil {
return nil, xerrors.Errorf("failed to sign new block: %w", err) return nil, xerrors.Errorf("failed to sign new block: %w", err)
} }

View File

@ -221,7 +221,7 @@ func TestMessagePool(t *testing.T) {
a := tma.nextBlock() a := tma.nextBlock()
sender, err := w.GenerateKey(crypto.SigTypeBLS) sender, err := w.WalletNew(context.Background(), crypto.SigTypeBLS)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -262,7 +262,7 @@ func TestMessagePoolMessagesInEachBlock(t *testing.T) {
a := tma.nextBlock() a := tma.nextBlock()
sender, err := w.GenerateKey(crypto.SigTypeBLS) sender, err := w.WalletNew(context.Background(), crypto.SigTypeBLS)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -312,7 +312,7 @@ func TestRevertMessages(t *testing.T) {
a := tma.nextBlock() a := tma.nextBlock()
b := tma.nextBlock() b := tma.nextBlock()
sender, err := w.GenerateKey(crypto.SigTypeBLS) sender, err := w.WalletNew(context.Background(), crypto.SigTypeBLS)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -375,7 +375,7 @@ func TestPruningSimple(t *testing.T) {
a := tma.nextBlock() a := tma.nextBlock()
tma.applyBlock(t, a) tma.applyBlock(t, a)
sender, err := w.GenerateKey(crypto.SigTypeBLS) sender, err := w.WalletNew(context.Background(), crypto.SigTypeBLS)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -422,7 +422,7 @@ func TestLoadLocal(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1) a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -432,7 +432,7 @@ func TestLoadLocal(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1) a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -494,7 +494,7 @@ func TestClearAll(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1) a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -504,7 +504,7 @@ func TestClearAll(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1) a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -548,7 +548,7 @@ func TestClearNonLocal(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1) a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -558,7 +558,7 @@ func TestClearNonLocal(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1) a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -609,7 +609,7 @@ func TestUpdates(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1) a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -619,7 +619,7 @@ func TestUpdates(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1) a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -1,6 +1,7 @@
package messagepool package messagepool
import ( import (
"context"
"testing" "testing"
"time" "time"
@ -32,7 +33,7 @@ func TestRepubMessages(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1) a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -42,7 +43,7 @@ func TestRepubMessages(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1) a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -29,7 +29,7 @@ func init() {
MaxActorPendingMessages = 1000000 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{ msg := &types.Message{
From: from, From: from,
To: to, To: to,
@ -40,7 +40,7 @@ func makeTestMessage(w *wallet.Wallet, from, to address.Address, nonce uint64, g
GasFeeCap: types.NewInt(100 + gasPrice), GasFeeCap: types.NewInt(100 + gasPrice),
GasPremium: types.NewInt(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 { if err != nil {
panic(err) panic(err)
} }
@ -70,7 +70,7 @@ func TestMessageChains(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1) a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -80,7 +80,7 @@ func TestMessageChains(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1) a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -308,7 +308,7 @@ func TestMessageChainSkipping(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1) a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -318,7 +318,7 @@ func TestMessageChainSkipping(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1) a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -384,7 +384,7 @@ func TestBasicMessageSelection(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1) a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -394,7 +394,7 @@ func TestBasicMessageSelection(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1) a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -528,7 +528,7 @@ func TestMessageSelectionTrimming(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1) a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -538,7 +538,7 @@ func TestMessageSelectionTrimming(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1) a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -591,7 +591,7 @@ func TestPriorityMessageSelection(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1) a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -601,7 +601,7 @@ func TestPriorityMessageSelection(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1) a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -670,7 +670,7 @@ func TestPriorityMessageSelection2(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1) a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -680,7 +680,7 @@ func TestPriorityMessageSelection2(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1) a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -740,7 +740,7 @@ func TestOptimalMessageSelection1(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1) a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -750,7 +750,7 @@ func TestOptimalMessageSelection1(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1) a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -807,7 +807,7 @@ func TestOptimalMessageSelection2(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a1, err := w1.GenerateKey(crypto.SigTypeSecp256k1) a1, err := w1.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -817,7 +817,7 @@ func TestOptimalMessageSelection2(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a2, err := w2.GenerateKey(crypto.SigTypeSecp256k1) a2, err := w2.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -883,7 +883,7 @@ func TestOptimalMessageSelection3(t *testing.T) {
nActors := 10 nActors := 10
// the actors // the actors
var actors []address.Address var actors []address.Address
var wallets []*wallet.Wallet var wallets []*wallet.LocalWallet
for i := 0; i < nActors; i++ { for i := 0; i < nActors; i++ {
w, err := wallet.NewWallet(wallet.NewMemKeyStore()) w, err := wallet.NewWallet(wallet.NewMemKeyStore())
@ -891,7 +891,7 @@ func TestOptimalMessageSelection3(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
a, err := w.GenerateKey(crypto.SigTypeSecp256k1) a, err := w.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -963,7 +963,7 @@ func testCompetitiveMessageSelection(t *testing.T, rng *rand.Rand, getPremium fu
nActors := 300 nActors := 300
// the actors // the actors
var actors []address.Address var actors []address.Address
var wallets []*wallet.Wallet var wallets []*wallet.LocalWallet
for i := 0; i < nActors; i++ { for i := 0; i < nActors; i++ {
w, err := wallet.NewWallet(wallet.NewMemKeyStore()) w, err := wallet.NewWallet(wallet.NewMemKeyStore())
@ -971,7 +971,7 @@ func testCompetitiveMessageSelection(t *testing.T, rng *rand.Rand, getPremium fu
t.Fatal(err) t.Fatal(err)
} }
a, err := w.GenerateKey(crypto.SigTypeSecp256k1) a, err := w.WalletNew(context.Background(), crypto.SigTypeSecp256k1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -174,7 +174,7 @@ func TestForkHeightTriggers(t *testing.T) {
Params: enc, Params: enc,
GasLimit: types.TestGasLimit, 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 { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -202,7 +202,7 @@ func TestForkHeightTriggers(t *testing.T) {
} }
nonce++ 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 { if err != nil {
return nil, err return nil, err
} }

View File

@ -566,7 +566,7 @@ func TestDuplicateNonce(t *testing.T) {
GasPremium: types.NewInt(0), 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) require.NoError(t, err)
return &types.SignedMessage{ return &types.SignedMessage{

View File

@ -21,7 +21,7 @@ func Address(i uint64) address.Address {
return a 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{ msg := &types.Message{
To: to, To: to,
From: from, From: from,
@ -32,7 +32,7 @@ func MkMessage(from, to address.Address, nonce uint64, w *wallet.Wallet) *types.
GasPremium: types.NewInt(1), 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 { if err != nil {
panic(err) panic(err)
} }

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"math/rand" "math/rand"
@ -63,11 +64,11 @@ func MakeMessageSigningVectors() []vectors.MessageSigningVector {
panic(err) panic(err)
} }
blsk, err := w.GenerateKey(crypto.SigTypeBLS) blsk, err := w.WalletNew(context.Background(), crypto.SigTypeBLS)
if err != nil { if err != nil {
panic(err) panic(err)
} }
bki, err := w.Export(blsk) bki, err := w.WalletExport(context.Background(), blsk)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -87,11 +88,11 @@ func MakeMessageSigningVectors() []vectors.MessageSigningVector {
Signature: &bmsg.Signature, Signature: &bmsg.Signature,
} }
secpk, err := w.GenerateKey(crypto.SigTypeBLS) secpk, err := w.WalletNew(context.Background(), crypto.SigTypeBLS)
if err != nil { if err != nil {
panic(err) panic(err)
} }
ski, err := w.Export(secpk) ski, err := w.WalletExport(context.Background(), secpk)
if err != nil { if err != nil {
panic(err) panic(err)
} }

27
chain/wallet/interface.go Normal file
View File

@ -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
}

81
chain/wallet/key.go Normal file
View File

@ -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
}
}

View File

@ -29,15 +29,15 @@ const (
KTSecp256k1 = "secp256k1" KTSecp256k1 = "secp256k1"
) )
type Wallet struct { type LocalWallet struct {
keys map[address.Address]*Key keys map[address.Address]*Key
keystore types.KeyStore keystore types.KeyStore
lk sync.Mutex lk sync.Mutex
} }
func NewWallet(keystore types.KeyStore) (*Wallet, error) { func NewWallet(keystore types.KeyStore) (*LocalWallet, error) {
w := &Wallet{ w := &LocalWallet{
keys: make(map[address.Address]*Key), keys: make(map[address.Address]*Key),
keystore: keystore, keystore: keystore,
} }
@ -45,18 +45,18 @@ func NewWallet(keystore types.KeyStore) (*Wallet, error) {
return w, nil return w, nil
} }
func KeyWallet(keys ...*Key) *Wallet { func KeyWallet(keys ...*Key) *LocalWallet {
m := make(map[address.Address]*Key) m := make(map[address.Address]*Key)
for _, key := range keys { for _, key := range keys {
m[key.Address] = key m[key.Address] = key
} }
return &Wallet{ return &LocalWallet{
keys: m, 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) ki, err := w.findKey(addr)
if err != nil { if err != nil {
return nil, err 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) 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() w.lk.Lock()
defer w.lk.Unlock() defer w.lk.Unlock()
@ -96,7 +110,7 @@ func (w *Wallet) findKey(addr address.Address) (*Key, error) {
return k, nil 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) k, err := w.findKey(addr)
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed to find key to export: %w", err) 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 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() w.lk.Lock()
defer w.lk.Unlock() defer w.lk.Unlock()
@ -121,7 +135,7 @@ func (w *Wallet) Import(ki *types.KeyInfo) (address.Address, error) {
return k.Address, nil 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() all, err := w.keystore.List()
if err != nil { if err != nil {
return nil, xerrors.Errorf("listing keystore: %w", err) return nil, xerrors.Errorf("listing keystore: %w", err)
@ -144,7 +158,7 @@ func (w *Wallet) ListAddrs() ([]address.Address, error) {
return out, nil return out, nil
} }
func (w *Wallet) GetDefault() (address.Address, error) { func (w *LocalWallet) GetDefault() (address.Address, error) {
w.lk.Lock() w.lk.Lock()
defer w.lk.Unlock() defer w.lk.Unlock()
@ -161,7 +175,7 @@ func (w *Wallet) GetDefault() (address.Address, error) {
return k.Address, nil return k.Address, nil
} }
func (w *Wallet) SetDefault(a address.Address) error { func (w *LocalWallet) SetDefault(a address.Address) error {
w.lk.Lock() w.lk.Lock()
defer w.lk.Unlock() defer w.lk.Unlock()
@ -183,19 +197,7 @@ func (w *Wallet) SetDefault(a address.Address) error {
return nil return nil
} }
func GenerateKey(typ crypto.SigType) (*Key, error) { func (w *LocalWallet) WalletNew(ctx context.Context, typ crypto.SigType) (address.Address, 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) {
w.lk.Lock() w.lk.Lock()
defer w.lk.Unlock() defer w.lk.Unlock()
@ -223,7 +225,7 @@ func (w *Wallet) GenerateKey(typ crypto.SigType) (address.Address, error) {
return k.Address, nil 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) k, err := w.findKey(addr)
if err != nil { if err != nil {
return false, err return false, err
@ -231,7 +233,7 @@ func (w *Wallet) HasKey(addr address.Address) (bool, error) {
return k != nil, nil 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) k, err := w.findKey(addr)
if err != nil { if err != nil {
return xerrors.Errorf("failed to delete key %s : %w", addr, err) 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 return nil
} }
type Key struct { var _ Wallet = &LocalWallet{}
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
}
}

View File

@ -40,12 +40,12 @@ func main() {
return fmt.Errorf("unrecognized key type: %q", cctx.String("type")) 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 { if err != nil {
return err return err
} }
ki, err := w.Export(kaddr) ki, err := w.WalletExport(cctx.Context, kaddr)
if err != nil { if err != nil {
return err return err
} }

View File

@ -130,7 +130,7 @@ var keyinfoImportCmd = &cli.Command{
return err return err
} }
addr, err := w.Import(&keyInfo) addr, err := w.WalletImport(cctx.Context, &keyInfo)
if err != nil { if err != nil {
return err return err
} }

View File

@ -440,7 +440,7 @@ func (c *ClientNodeAdapter) SignProposal(ctx context.Context, signer address.Add
return nil, err return nil, err
} }
sig, err := c.Wallet.Sign(ctx, signer, buf) sig, err := c.Wallet.WalletSign(ctx, signer, buf)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -524,7 +524,7 @@ func (c *ClientNodeAdapter) SignBytes(ctx context.Context, signer address.Addres
return nil, err return nil, err
} }
localSignature, err := c.Wallet.Sign(ctx, signer, b) localSignature, err := c.Wallet.WalletSign(ctx, signer, b)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -234,7 +234,9 @@ func Online() Option {
Override(new(vm.SyscallBuilder), vm.Syscalls), Override(new(vm.SyscallBuilder), vm.Syscalls),
Override(new(*store.ChainStore), modules.ChainStore), Override(new(*store.ChainStore), modules.ChainStore),
Override(new(*stmgr.StateManager), stmgr.NewStateManager), 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.ChainGCLocker), blockstore.NewGCLocker),
Override(new(dtypes.ChainGCBlockstore), modules.ChainGCBlockstore), Override(new(dtypes.ChainGCBlockstore), modules.ChainGCBlockstore),

View File

@ -48,7 +48,7 @@ type StateAPI struct {
// TODO: the wallet here is only needed because we have the MinerCreateBlock // TODO: the wallet here is only needed because we have the MinerCreateBlock
// API attached to the state API. It probably should live somewhere better // API attached to the state API. It probably should live somewhere better
Wallet *wallet.Wallet Wallet *wallet.LocalWallet
ProofVerifier ffiwrapper.Verifier ProofVerifier ffiwrapper.Verifier
StateManager *stmgr.StateManager StateManager *stmgr.StateManager

View File

@ -20,19 +20,8 @@ type WalletAPI struct {
fx.In fx.In
StateManager *stmgr.StateManager StateManager *stmgr.StateManager
Wallet *wallet.Wallet Default wallet.Default
} 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()
} }
func (a *WalletAPI) WalletBalance(ctx context.Context, addr address.Address) (types.BigInt, error) { 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 { if err != nil {
return nil, xerrors.Errorf("failed to resolve ID address: %w", keyAddr) 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) { func (a *WalletAPI) WalletSignMessage(ctx context.Context, k address.Address, msg *types.Message) (*types.SignedMessage, error) {
mcid := msg.Cid() keyAddr, err := a.StateManager.ResolveToKeyAddress(ctx, k, nil)
sig, err := a.WalletSign(ctx, k, mcid.Bytes())
if err != 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 a.Wallet.WalletSignMessage(ctx, keyAddr, msg)
return &types.SignedMessage{
Message: *msg,
Signature: *sig,
}, nil
} }
func (a *WalletAPI) WalletVerify(ctx context.Context, k address.Address, msg []byte, sig *crypto.Signature) bool { 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) { 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 { func (a *WalletAPI) WalletSetDefault(ctx context.Context, addr address.Address) error {
return a.Wallet.SetDefault(addr) return a.Default.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)
} }