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 01/15] 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) } From 780f6dba34afbb65f178d208fad8a3e636cf56a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 5 Sep 2020 21:36:32 +0200 Subject: [PATCH 02/15] Remote wallet backends --- .gitignore | 2 + .../wallet/interface.go => api/api_wallet.go | 10 +- api/apistruct/permissioned.go | 6 + api/apistruct/struct.go | 46 ++++++ api/client/client.go | 12 ++ chain/wallet/remotewallet/remote.go | 51 +++++++ chain/wallet/wallet.go | 8 +- cmd/lotus-wallet/logged.go | 68 +++++++++ cmd/lotus-wallet/main.go | 141 ++++++++++++++++++ go.sum | 3 + node/builder.go | 6 +- node/config/def.go | 5 + node/impl/full/wallet.go | 5 +- node/repo/fsrepo.go | 9 ++ 14 files changed, 360 insertions(+), 12 deletions(-) rename chain/wallet/interface.go => api/api_wallet.go (84%) create mode 100644 chain/wallet/remotewallet/remote.go create mode 100644 cmd/lotus-wallet/logged.go create mode 100644 cmd/lotus-wallet/main.go diff --git a/.gitignore b/.gitignore index 0424c1f24..a1d152294 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,8 @@ /lotus-fountain /lotus-stats /lotus-bench +/lotus-wallet +/lotus-pcr /bench.json /lotuspond/front/node_modules /lotuspond/front/build diff --git a/chain/wallet/interface.go b/api/api_wallet.go similarity index 84% rename from chain/wallet/interface.go rename to api/api_wallet.go index 9dc95a32c..06b00a75b 100644 --- a/chain/wallet/interface.go +++ b/api/api_wallet.go @@ -1,15 +1,14 @@ -package wallet +package api 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 { +type WalletAPI interface { WalletNew(context.Context, crypto.SigType) (address.Address, error) WalletHas(context.Context, address.Address) (bool, error) WalletList(context.Context) ([]address.Address, error) @@ -20,8 +19,3 @@ type Wallet interface { 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/api/apistruct/permissioned.go b/api/apistruct/permissioned.go index c93662733..86902d31b 100644 --- a/api/apistruct/permissioned.go +++ b/api/apistruct/permissioned.go @@ -36,3 +36,9 @@ func PermissionedWorkerAPI(a api.WorkerAPI) api.WorkerAPI { auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.Internal) return &out } + +func PermissionedWalletAPI(a api.WalletAPI) api.WalletAPI { + var out WalletStruct + auth.PermissionedProxy(AllPermissions, DefaultPerms, a, &out.Internal) + return &out +} diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index dff614001..5eb757c7b 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -336,6 +336,19 @@ type WorkerStruct struct { } } +type WalletStruct struct { + Internal struct { + WalletNew func(context.Context, crypto.SigType) (address.Address, error) `perm:"write"` + WalletHas func(context.Context, address.Address) (bool, error) `perm:"write"` + WalletList func(context.Context) ([]address.Address, error) `perm:"write"` + WalletSign func(context.Context, address.Address, []byte) (*crypto.Signature, error) `perm:"sign"` + WalletSignMessage func(context.Context, address.Address, *types.Message) (*types.SignedMessage, error) `perm:"sign"` + WalletExport func(context.Context, address.Address) (*types.KeyInfo, error) `perm:"admin"` + WalletImport func(context.Context, *types.KeyInfo) (address.Address, error) `perm:"admin"` + WalletDelete func(context.Context, address.Address) error `perm:"write"` + } +} + // CommonStruct func (c *CommonStruct) AuthVerify(ctx context.Context, token string) ([]auth.Permission, error) { @@ -1271,7 +1284,40 @@ func (w *WorkerStruct) Closing(ctx context.Context) (<-chan struct{}, error) { return w.Internal.Closing(ctx) } +func (c *WalletStruct) WalletNew(ctx context.Context, typ crypto.SigType) (address.Address, error) { + return c.Internal.WalletNew(ctx, typ) +} + +func (c *WalletStruct) WalletHas(ctx context.Context, addr address.Address) (bool, error) { + return c.Internal.WalletHas(ctx, addr) +} + +func (c *WalletStruct) WalletList(ctx context.Context) ([]address.Address, error) { + return c.Internal.WalletList(ctx) +} + +func (c *WalletStruct) WalletSign(ctx context.Context, k address.Address, msg []byte) (*crypto.Signature, error) { + return c.Internal.WalletSign(ctx, k, msg) +} + +func (c *WalletStruct) WalletSignMessage(ctx context.Context, k address.Address, msg *types.Message) (*types.SignedMessage, error) { + return c.Internal.WalletSignMessage(ctx, k, msg) +} + +func (c *WalletStruct) WalletExport(ctx context.Context, a address.Address) (*types.KeyInfo, error) { + return c.Internal.WalletExport(ctx, a) +} + +func (c *WalletStruct) WalletImport(ctx context.Context, ki *types.KeyInfo) (address.Address, error) { + return c.Internal.WalletImport(ctx, ki) +} + +func (c *WalletStruct) WalletDelete(ctx context.Context, addr address.Address) error { + return c.Internal.WalletDelete(ctx, addr) +} + var _ api.Common = &CommonStruct{} var _ api.FullNode = &FullNodeStruct{} var _ api.StorageMiner = &StorageMinerStruct{} var _ api.WorkerAPI = &WorkerStruct{} +var _ api.WalletAPI = &WalletStruct{} diff --git a/api/client/client.go b/api/client/client.go index cd915acf0..6e624bdd3 100644 --- a/api/client/client.go +++ b/api/client/client.go @@ -82,3 +82,15 @@ func NewWorkerRPC(ctx context.Context, addr string, requestHeader http.Header) ( return &res, closer, err } + +func NewWalletRPC(ctx context.Context, addr string, requestHeader http.Header) (api.WalletAPI, jsonrpc.ClientCloser, error) { + var res apistruct.WalletStruct + closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin", + []interface{}{ + &res.Internal, + }, + requestHeader, + ) + + return &res, closer, err +} diff --git a/chain/wallet/remotewallet/remote.go b/chain/wallet/remotewallet/remote.go new file mode 100644 index 000000000..712f270b4 --- /dev/null +++ b/chain/wallet/remotewallet/remote.go @@ -0,0 +1,51 @@ +package remotewallet + +import ( + "context" + "go.uber.org/fx" + "golang.org/x/xerrors" + "net/http" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/client" + "github.com/filecoin-project/lotus/node/modules/helpers" +) + +type RemoteWallet struct { + api.WalletAPI +} + +func SetupRemoteWallet(url string) func(mctx helpers.MetricsCtx, lc fx.Lifecycle) (*RemoteWallet, error) { + return func(mctx helpers.MetricsCtx, lc fx.Lifecycle) (*RemoteWallet, error) { + /*sp := strings.SplitN(env, ":", 2) + if len(sp) != 2 { + log.Warnf("invalid env(%s) value, missing token or address", envKey) + } else { + ma, err := multiaddr.NewMultiaddr(sp[1]) + if err != nil { + return APIInfo{}, xerrors.Errorf("could not parse multiaddr from env(%s): %w", envKey, err) + } + return APIInfo{ + Addr: ma, + Token: []byte(sp[0]), + }, nil + }*/ + + headers := http.Header{} + /*headers.Add("Authorization", "Bearer "+token)*/ + + wapi, closer, err := client.NewWalletRPC(mctx, url, headers) + if err != nil { + return nil, xerrors.Errorf("creating jsonrpc client: %w", err) + } + + lc.Append(fx.Hook{ + OnStop: func(ctx context.Context) error { + closer() + return nil + }, + }) + + return &RemoteWallet{wapi}, nil + } +} \ No newline at end of file diff --git a/chain/wallet/wallet.go b/chain/wallet/wallet.go index 7fdea8963..bcc8d07b1 100644 --- a/chain/wallet/wallet.go +++ b/chain/wallet/wallet.go @@ -12,6 +12,7 @@ import ( "github.com/filecoin-project/go-address" + "github.com/filecoin-project/lotus/api" _ "github.com/filecoin-project/lotus/lib/sigs/bls" // enable bls signatures _ "github.com/filecoin-project/lotus/lib/sigs/secp" // enable secp signatures @@ -36,6 +37,11 @@ type LocalWallet struct { lk sync.Mutex } +type Default interface { + GetDefault() (address.Address, error) + SetDefault(a address.Address) error +} + func NewWallet(keystore types.KeyStore) (*LocalWallet, error) { w := &LocalWallet{ keys: make(map[address.Address]*Key), @@ -250,4 +256,4 @@ func (w *LocalWallet) WalletDelete(ctx context.Context, addr address.Address) er return nil } -var _ Wallet = &LocalWallet{} +var _ api.WalletAPI = &LocalWallet{} diff --git a/cmd/lotus-wallet/logged.go b/cmd/lotus-wallet/logged.go new file mode 100644 index 000000000..e73daae90 --- /dev/null +++ b/cmd/lotus-wallet/logged.go @@ -0,0 +1,68 @@ +package main + +import ( + "context" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/specs-actors/actors/crypto" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/types" +) + +type LoggedWallet struct { + under api.WalletAPI +} + +func (c *LoggedWallet) WalletNew(ctx context.Context, typ crypto.SigType) (address.Address, error) { + n, err := typ.Name() + if err != nil { + return address.Address{}, err + } + + log.Infow("WalletNew", "type", n) + + return c.under.WalletNew(ctx, typ) +} + +func (c *LoggedWallet) WalletHas(ctx context.Context, addr address.Address) (bool, error) { + log.Infow("WalletHas", "address", addr) + + return c.under.WalletHas(ctx, addr) +} + +func (c *LoggedWallet) WalletList(ctx context.Context) ([]address.Address, error) { + log.Infow("WalletList") + + return c.under.WalletList(ctx) +} + +func (c *LoggedWallet) WalletSign(ctx context.Context, k address.Address, msg []byte) (*crypto.Signature, error) { + log.Infow("WalletSign", "address", k) + + return c.under.WalletSign(ctx, k, msg) +} + +func (c *LoggedWallet) WalletSignMessage(ctx context.Context, k address.Address, msg *types.Message) (*types.SignedMessage, error) { + log.Infow("WalletSignMessage", "address", k) + + return c.under.WalletSignMessage(ctx, k, msg) +} + +func (c *LoggedWallet) WalletExport(ctx context.Context, a address.Address) (*types.KeyInfo, error) { + log.Infow("WalletExport", "address", a) + + return c.under.WalletExport(ctx, a) +} + +func (c *LoggedWallet) WalletImport(ctx context.Context, ki *types.KeyInfo) (address.Address, error) { + log.Infow("WalletImport", "type", ki.Type) + + return c.under.WalletImport(ctx, ki) +} + +func (c *LoggedWallet) WalletDelete(ctx context.Context, addr address.Address) error { + log.Infow("WalletDelete", "address", addr) + + return c.under.WalletDelete(ctx, addr) +} \ No newline at end of file diff --git a/cmd/lotus-wallet/main.go b/cmd/lotus-wallet/main.go new file mode 100644 index 000000000..ae3580a59 --- /dev/null +++ b/cmd/lotus-wallet/main.go @@ -0,0 +1,141 @@ +package main + +import ( + "context" + "net" + "net/http" + "os" + + "github.com/gorilla/mux" + logging "github.com/ipfs/go-log/v2" + "github.com/urfave/cli/v2" + + "github.com/filecoin-project/go-jsonrpc" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/wallet" + lcli "github.com/filecoin-project/lotus/cli" + "github.com/filecoin-project/lotus/lib/lotuslog" + "github.com/filecoin-project/lotus/node/repo" +) + +var log = logging.Logger("main") + +const FlagWalletRepo = "wallet-repo" + +func main() { + lotuslog.SetupLogLevels() + + local := []*cli.Command{ + runCmd, + } + + app := &cli.App{ + Name: "lotus-wallet", + Usage: "Basic external wallet", + Version: build.UserVersion(), + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: FlagWalletRepo, + EnvVars: []string{"WALLET_PATH"}, + Value: "~/.lotuswallet", // TODO: Consider XDG_DATA_HOME + }, + }, + + Commands: local, + } + app.Setup() + + if err := app.Run(os.Args); err != nil { + log.Warnf("%+v", err) + return + } +} + +var runCmd = &cli.Command{ + Name: "run", + Usage: "Start lotus wallet", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "listen", + Usage: "host address and port the wallet api will listen on", + Value: "0.0.0.0:1777", + }, + }, + Action: func(cctx *cli.Context) error { + log.Info("Starting lotus wallet") + + ctx := lcli.ReqContext(cctx) + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + repoPath := cctx.String(FlagWalletRepo) + r, err := repo.NewFS(repoPath) + if err != nil { + return err + } + + ok, err := r.Exists() + if err != nil { + return err + } + if !ok { + if err := r.Init(repo.Worker); err != nil { + return err + } + } + + lr, err := r.Lock(repo.Wallet) + if err != nil { + return err + } + + ks, err := lr.KeyStore() + if err != nil { + return err + } + + w, err := wallet.NewWallet(ks) + if err != nil { + return err + } + + address := cctx.String("listen") + mux := mux.NewRouter() + + log.Info("Setting up API endpoint at " + address) + + rpcServer := jsonrpc.NewServer() + rpcServer.Register("Filecoin", &LoggedWallet{under: w}) + + mux.Handle("/rpc/v0", rpcServer) + mux.PathPrefix("/").Handler(http.DefaultServeMux) // pprof + + /*ah := &auth.Handler{ + Verify: nodeApi.AuthVerify, + Next: mux.ServeHTTP, + }*/ + + srv := &http.Server{ + Handler: mux, + BaseContext: func(listener net.Listener) context.Context { + return ctx + }, + } + + go func() { + <-ctx.Done() + log.Warn("Shutting down...") + if err := srv.Shutdown(context.TODO()); err != nil { + log.Errorf("shutting down RPC server failed: %s", err) + } + log.Warn("Graceful shutdown successful") + }() + + nl, err := net.Listen("tcp", address) + if err != nil { + return err + } + + return srv.Serve(nl) + }, +} diff --git a/go.sum b/go.sum index 0c525579e..ea7b3711e 100644 --- a/go.sum +++ b/go.sum @@ -65,9 +65,11 @@ github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia github.com/akavel/rsrc v0.8.0 h1:zjWn7ukO9Kc5Q62DOJCcxGpXC18RawVtYAGdz2aLlfw= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= @@ -1867,6 +1869,7 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/node/builder.go b/node/builder.go index 7c3251df2..b653fa429 100644 --- a/node/builder.go +++ b/node/builder.go @@ -40,6 +40,7 @@ import ( "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/vm" "github.com/filecoin-project/lotus/chain/wallet" + "github.com/filecoin-project/lotus/chain/wallet/remotewallet" sectorstorage "github.com/filecoin-project/lotus/extern/sector-storage" "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" "github.com/filecoin-project/lotus/extern/sector-storage/stores" @@ -235,7 +236,7 @@ func Online() Option { Override(new(*store.ChainStore), modules.ChainStore), Override(new(*stmgr.StateManager), stmgr.NewStateManager), Override(new(*wallet.LocalWallet), wallet.NewWallet), - Override(new(wallet.Wallet), From(new(*wallet.LocalWallet))), + Override(new(api.WalletAPI), From(new(*wallet.LocalWallet))), Override(new(wallet.Default), From(new(*wallet.LocalWallet))), Override(new(dtypes.ChainGCLocker), blockstore.NewGCLocker), @@ -419,6 +420,9 @@ func ConfigFullNode(c interface{}) Option { If(cfg.Metrics.HeadNotifs, Override(HeadMetricsKey, metrics.SendHeadNotifs(cfg.Metrics.Nickname)), ), + If(cfg.Wallet.RemoteBackend != "", + Override(new(api.WalletAPI), remotewallet.SetupRemoteWallet(cfg.Wallet.RemoteBackend)), + ), ) } diff --git a/node/config/def.go b/node/config/def.go index 9fee8895a..f5071ada5 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -22,6 +22,7 @@ type FullNode struct { Common Client Client Metrics Metrics + Wallet Wallet } // // Common @@ -105,6 +106,10 @@ type Client struct { IpfsUseForRetrieval bool } +type Wallet struct { + RemoteBackend string +} + func defCommon() Common { return Common{ API: API{ diff --git a/node/impl/full/wallet.go b/node/impl/full/wallet.go index 22b674737..263452cf3 100644 --- a/node/impl/full/wallet.go +++ b/node/impl/full/wallet.go @@ -10,6 +10,7 @@ import ( "github.com/filecoin-project/specs-actors/actors/abi/big" "github.com/filecoin-project/specs-actors/actors/crypto" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/wallet" @@ -21,7 +22,7 @@ type WalletAPI struct { StateManager *stmgr.StateManager Default wallet.Default - wallet.Wallet + api.WalletAPI } func (a *WalletAPI) WalletBalance(ctx context.Context, addr address.Address) (types.BigInt, error) { @@ -50,7 +51,7 @@ func (a *WalletAPI) WalletSignMessage(ctx context.Context, k address.Address, ms if err != nil { return nil, xerrors.Errorf("failed to resolve ID address: %w", keyAddr) } - return a.Wallet.WalletSignMessage(ctx, keyAddr, msg) + return a.WalletAPI.WalletSignMessage(ctx, keyAddr, msg) } func (a *WalletAPI) WalletVerify(ctx context.Context, k address.Address, msg []byte, sig *crypto.Signature) bool { diff --git a/node/repo/fsrepo.go b/node/repo/fsrepo.go index 14085d4ac..2b7fa9ed3 100644 --- a/node/repo/fsrepo.go +++ b/node/repo/fsrepo.go @@ -44,6 +44,7 @@ const ( FullNode RepoType = iota StorageMiner Worker + Wallet ) func defConfForType(t RepoType) interface{} { @@ -54,6 +55,8 @@ func defConfForType(t RepoType) interface{} { return config.DefaultStorageMiner() case Worker: return &struct{}{} + case Wallet: + return &struct{}{} default: panic(fmt.Sprintf("unknown RepoType(%d)", int(t))) } @@ -87,6 +90,12 @@ func (fsr *FsRepo) Exists() (bool, error) { notexist := os.IsNotExist(err) if notexist { err = nil + + _, err = os.Stat(filepath.Join(fsr.path, fsKeystore)) + notexist = os.IsNotExist(err) + if notexist { + err = nil + } } return !notexist, err } From 483510947096928612cadf6e3a91c1d6d466b13e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 9 Oct 2020 00:51:04 +0200 Subject: [PATCH 03/15] wallet: Post-merge fixes --- api/api_wallet.go | 3 ++- chain/messagesigner/messagesigner.go | 10 +++++----- chain/wallet/key.go | 2 +- chain/wallet/wallet.go | 2 +- cmd/lotus-wallet/logged.go | 2 +- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/api/api_wallet.go b/api/api_wallet.go index 06b00a75b..9c289ca95 100644 --- a/api/api_wallet.go +++ b/api/api_wallet.go @@ -4,8 +4,9 @@ import ( "context" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/crypto" + "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/specs-actors/actors/crypto" ) type WalletAPI interface { diff --git a/chain/messagesigner/messagesigner.go b/chain/messagesigner/messagesigner.go index ac94d6a3e..1240485b8 100644 --- a/chain/messagesigner/messagesigner.go +++ b/chain/messagesigner/messagesigner.go @@ -3,12 +3,12 @@ package messagesigner import ( "bytes" "context" + "github.com/filecoin-project/lotus/api" "sync" "github.com/filecoin-project/go-address" "github.com/filecoin-project/lotus/chain/messagepool" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/chain/wallet" "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" @@ -28,17 +28,17 @@ type mpoolAPI interface { // MessageSigner keeps track of nonces per address, and increments the nonce // when signing a message type MessageSigner struct { - wallet *wallet.Wallet + wallet api.WalletAPI lk sync.Mutex mpool mpoolAPI ds datastore.Batching } -func NewMessageSigner(wallet *wallet.Wallet, mpool *messagepool.MessagePool, ds dtypes.MetadataDS) *MessageSigner { +func NewMessageSigner(wallet api.WalletAPI, mpool *messagepool.MessagePool, ds dtypes.MetadataDS) *MessageSigner { return newMessageSigner(wallet, mpool, ds) } -func newMessageSigner(wallet *wallet.Wallet, mpool mpoolAPI, ds dtypes.MetadataDS) *MessageSigner { +func newMessageSigner(wallet api.WalletAPI, mpool mpoolAPI, ds dtypes.MetadataDS) *MessageSigner { ds = namespace.Wrap(ds, datastore.NewKey("/message-signer/")) return &MessageSigner{ wallet: wallet, @@ -61,7 +61,7 @@ func (ms *MessageSigner) SignMessage(ctx context.Context, msg *types.Message, cb // Sign the message with the nonce msg.Nonce = nonce - sig, err := ms.wallet.Sign(ctx, msg.From, msg.Cid().Bytes()) + sig, err := ms.wallet.WalletSign(ctx, msg.From, msg.Cid().Bytes()) if err != nil { return nil, xerrors.Errorf("failed to sign message: %w", err) } diff --git a/chain/wallet/key.go b/chain/wallet/key.go index 2d4ecafd7..4b746a17a 100644 --- a/chain/wallet/key.go +++ b/chain/wallet/key.go @@ -4,7 +4,7 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/specs-actors/actors/crypto" + "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/lib/sigs" diff --git a/chain/wallet/wallet.go b/chain/wallet/wallet.go index b4c846d37..5f501307f 100644 --- a/chain/wallet/wallet.go +++ b/chain/wallet/wallet.go @@ -152,7 +152,7 @@ func (w *LocalWallet) tryFind(addr address.Address) (types.KeyInfo, error) { return ki, nil } -func (w *LocalWallet) Export(ctx context.Context, 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) diff --git a/cmd/lotus-wallet/logged.go b/cmd/lotus-wallet/logged.go index e73daae90..4cdd62825 100644 --- a/cmd/lotus-wallet/logged.go +++ b/cmd/lotus-wallet/logged.go @@ -4,7 +4,7 @@ import ( "context" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/specs-actors/actors/crypto" + "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/types" From 114776f2c5e7beccd0dd865bfa9758e8239cdd10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 9 Oct 2020 01:04:59 +0200 Subject: [PATCH 04/15] wallet: Drop WalletSignMessage from WalletAPI --- api/api_wallet.go | 4 ++-- chain/wallet/wallet.go | 14 -------------- cmd/lotus-wallet/logged.go | 6 ------ node/impl/full/wallet.go | 15 +++++++++++++-- 4 files changed, 15 insertions(+), 24 deletions(-) diff --git a/api/api_wallet.go b/api/api_wallet.go index 9c289ca95..b3dbd5fa9 100644 --- a/api/api_wallet.go +++ b/api/api_wallet.go @@ -13,9 +13,9 @@ type WalletAPI 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 diff --git a/chain/wallet/wallet.go b/chain/wallet/wallet.go index 5f501307f..607380547 100644 --- a/chain/wallet/wallet.go +++ b/chain/wallet/wallet.go @@ -74,20 +74,6 @@ func (w *LocalWallet) WalletSign(ctx context.Context, addr address.Address, msg return sigs.Sign(ActSigType(ki.Type), ki.PrivateKey, msg) } -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() diff --git a/cmd/lotus-wallet/logged.go b/cmd/lotus-wallet/logged.go index 4cdd62825..adafb7cc5 100644 --- a/cmd/lotus-wallet/logged.go +++ b/cmd/lotus-wallet/logged.go @@ -43,12 +43,6 @@ func (c *LoggedWallet) WalletSign(ctx context.Context, k address.Address, msg [] return c.under.WalletSign(ctx, k, msg) } -func (c *LoggedWallet) WalletSignMessage(ctx context.Context, k address.Address, msg *types.Message) (*types.SignedMessage, error) { - log.Infow("WalletSignMessage", "address", k) - - return c.under.WalletSignMessage(ctx, k, msg) -} - func (c *LoggedWallet) WalletExport(ctx context.Context, a address.Address) (*types.KeyInfo, error) { log.Infow("WalletExport", "address", a) diff --git a/node/impl/full/wallet.go b/node/impl/full/wallet.go index 6252e12a4..13880a03a 100644 --- a/node/impl/full/wallet.go +++ b/node/impl/full/wallet.go @@ -3,10 +3,10 @@ package full import ( "context" - "github.com/filecoin-project/go-address" "go.uber.org/fx" "golang.org/x/xerrors" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/crypto" @@ -48,7 +48,18 @@ func (a *WalletAPI) WalletSignMessage(ctx context.Context, k address.Address, ms if err != nil { return nil, xerrors.Errorf("failed to resolve ID address: %w", keyAddr) } - return a.WalletAPI.WalletSignMessage(ctx, keyAddr, msg) + + mcid := msg.Cid() + + sig, err := a.WalletAPI.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 (a *WalletAPI) WalletVerify(ctx context.Context, k address.Address, msg []byte, sig *crypto.Signature) (bool, error) { From f3dc730b05c5ff9d7161a731594bbba3fc37b90f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 9 Oct 2020 01:27:38 +0200 Subject: [PATCH 05/15] wallet: Add metadata to WalletAPI.WalletSign --- api/api_wallet.go | 26 +++++++++++++++++++++++++- api/apistruct/struct.go | 6 +++--- chain/gen/gen.go | 16 +++++++++++++--- chain/gen/mining.go | 7 ++++--- chain/messagesigner/messagesigner.go | 11 ++++++++++- chain/wallet/wallet.go | 2 +- cmd/lotus-wallet/logged.go | 4 ++-- markets/storageadapter/client.go | 11 ++++++++--- node/impl/full/state.go | 16 +++++++--------- node/impl/full/wallet.go | 10 ++++++++-- 10 files changed, 81 insertions(+), 28 deletions(-) diff --git a/api/api_wallet.go b/api/api_wallet.go index b3dbd5fa9..82ef726a0 100644 --- a/api/api_wallet.go +++ b/api/api_wallet.go @@ -9,12 +9,36 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) +type MsgType string +const ( + MTUnknown = "unknown" + + // Signing message CID. MsgMeta.Extra contains raw cbor message bytes + MTChainMsg = "message" + + // Signing a blockheader. signing raw cbor block bytes (MsgMeta.Extra is empty) + MTBlock = "block" + + // Signing a deal proposal. signing raw cbor proposal bytes (MsgMeta.Extra is empty) + MTDealProposal = "dealproposal" + + // TODO: Deals, Vouchers, VRF +) + +type MsgMeta struct { + Type MsgType + + // Additional data related to what is signed. Should be verifiable with the + // signed bytes (e.g. CID(Extra).Bytes() == toSign) + Extra []byte +} + type WalletAPI 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) + WalletSign(ctx context.Context, signer address.Address, toSign []byte, meta MsgMeta) (*crypto.Signature, error) WalletExport(context.Context, address.Address) (*types.KeyInfo, error) WalletImport(context.Context, *types.KeyInfo) (address.Address, error) diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 01de13e61..81fce92b5 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -366,7 +366,7 @@ type WalletStruct struct { WalletNew func(context.Context, crypto.SigType) (address.Address, error) `perm:"write"` WalletHas func(context.Context, address.Address) (bool, error) `perm:"write"` WalletList func(context.Context) ([]address.Address, error) `perm:"write"` - WalletSign func(context.Context, address.Address, []byte) (*crypto.Signature, error) `perm:"sign"` + WalletSign func(context.Context, address.Address, []byte, api.MsgMeta) (*crypto.Signature, error) `perm:"sign"` WalletSignMessage func(context.Context, address.Address, *types.Message) (*types.SignedMessage, error) `perm:"sign"` WalletExport func(context.Context, address.Address) (*types.KeyInfo, error) `perm:"admin"` WalletImport func(context.Context, *types.KeyInfo) (address.Address, error) `perm:"admin"` @@ -1397,8 +1397,8 @@ func (c *WalletStruct) WalletList(ctx context.Context) ([]address.Address, error return c.Internal.WalletList(ctx) } -func (c *WalletStruct) WalletSign(ctx context.Context, k address.Address, msg []byte) (*crypto.Signature, error) { - return c.Internal.WalletSign(ctx, k, msg) +func (c *WalletStruct) WalletSign(ctx context.Context, k address.Address, msg []byte, meta api.MsgMeta) (*crypto.Signature, error) { + return c.Internal.WalletSign(ctx, k, msg, meta) } func (c *WalletStruct) WalletSignMessage(ctx context.Context, k address.Address, msg *types.Message) (*types.SignedMessage, error) { diff --git a/chain/gen/gen.go b/chain/gen/gen.go index ee93ef60e..70c303818 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -374,7 +374,13 @@ 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.WalletSign, worker, ticketRand) + sf := func(ctx context.Context, a address.Address, i []byte) (*crypto.Signature, error) { + return cg.w.WalletSign(ctx, a, i, api.MsgMeta{ + Type: api.MTUnknown, + }) + } + + vrfout, err := ComputeVRF(ctx, sf, worker, ticketRand) if err != nil { return nil, nil, nil, xerrors.Errorf("compute VRF: %w", err) } @@ -528,7 +534,9 @@ func getRandomMessages(cg *ChainGen) ([]*types.SignedMessage, error) { GasPremium: types.NewInt(0), } - sig, err := cg.w.WalletSign(context.TODO(), cg.banker, msg.Cid().Bytes()) + sig, err := cg.w.WalletSign(context.TODO(), cg.banker, msg.Cid().Bytes(), api.MsgMeta{ + Type: api.MTUnknown, // testing + }) if err != nil { return nil, err } @@ -588,7 +596,9 @@ 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.WalletSign(ctx, a, v) + return mca.w.WalletSign(ctx, a, v, api.MsgMeta{ + Type: api.MTUnknown, + }) } type WinningPoStProver interface { diff --git a/chain/gen/mining.go b/chain/gen/mining.go index 0c2f72590..37e8ca2c0 100644 --- a/chain/gen/mining.go +++ b/chain/gen/mining.go @@ -15,11 +15,10 @@ import ( "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/vm" - "github.com/filecoin-project/lotus/chain/wallet" "github.com/filecoin-project/lotus/lib/sigs/bls" ) -func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.LocalWallet, bt *api.BlockTemplate) (*types.FullBlock, error) { +func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w api.WalletAPI, bt *api.BlockTemplate) (*types.FullBlock, error) { pts, err := sm.ChainStore().LoadTipSet(bt.Parents) if err != nil { @@ -131,7 +130,9 @@ func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.Loc return nil, xerrors.Errorf("failed to get signing bytes for block: %w", err) } - sig, err := w.WalletSign(ctx, waddr, nosigbytes) + sig, err := w.WalletSign(ctx, waddr, nosigbytes, api.MsgMeta{ + Type: api.MTBlock, + }) if err != nil { return nil, xerrors.Errorf("failed to sign new block: %w", err) } diff --git a/chain/messagesigner/messagesigner.go b/chain/messagesigner/messagesigner.go index 1240485b8..c7948e42e 100644 --- a/chain/messagesigner/messagesigner.go +++ b/chain/messagesigner/messagesigner.go @@ -61,7 +61,16 @@ func (ms *MessageSigner) SignMessage(ctx context.Context, msg *types.Message, cb // Sign the message with the nonce msg.Nonce = nonce - sig, err := ms.wallet.WalletSign(ctx, msg.From, msg.Cid().Bytes()) + + mb, err := msg.ToStorageBlock() + if err != nil { + return nil, xerrors.Errorf("serializing message: %w", err) + } + + sig, err := ms.wallet.WalletSign(ctx, msg.From, mb.Cid().Bytes(), api.MsgMeta{ + Type: api.MTChainMsg, + Extra: mb.RawData(), + }) if err != nil { return nil, xerrors.Errorf("failed to sign message: %w", err) } diff --git a/chain/wallet/wallet.go b/chain/wallet/wallet.go index 607380547..2dbe94b50 100644 --- a/chain/wallet/wallet.go +++ b/chain/wallet/wallet.go @@ -62,7 +62,7 @@ func KeyWallet(keys ...*Key) *LocalWallet { } } -func (w *LocalWallet) WalletSign(ctx context.Context, addr address.Address, msg []byte) (*crypto.Signature, error) { +func (w *LocalWallet) WalletSign(ctx context.Context, addr address.Address, msg []byte, meta api.MsgMeta) (*crypto.Signature, error) { ki, err := w.findKey(addr) if err != nil { return nil, err diff --git a/cmd/lotus-wallet/logged.go b/cmd/lotus-wallet/logged.go index adafb7cc5..9cd729943 100644 --- a/cmd/lotus-wallet/logged.go +++ b/cmd/lotus-wallet/logged.go @@ -37,10 +37,10 @@ func (c *LoggedWallet) WalletList(ctx context.Context) ([]address.Address, error return c.under.WalletList(ctx) } -func (c *LoggedWallet) WalletSign(ctx context.Context, k address.Address, msg []byte) (*crypto.Signature, error) { +func (c *LoggedWallet) WalletSign(ctx context.Context, k address.Address, msg []byte, meta api.MsgMeta) (*crypto.Signature, error) { log.Infow("WalletSign", "address", k) - return c.under.WalletSign(ctx, k, msg) + return c.under.WalletSign(ctx, k, msg, meta) } func (c *LoggedWallet) WalletExport(ctx context.Context, a address.Address) (*types.KeyInfo, error) { diff --git a/markets/storageadapter/client.go b/markets/storageadapter/client.go index 824693dac..22ee483ce 100644 --- a/markets/storageadapter/client.go +++ b/markets/storageadapter/client.go @@ -5,6 +5,7 @@ package storageadapter import ( "bytes" "context" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/go-state-types/big" miner0 "github.com/filecoin-project/specs-actors/actors/builtin" @@ -422,7 +423,9 @@ func (c *ClientNodeAdapter) SignProposal(ctx context.Context, signer address.Add return nil, err } - sig, err := c.Wallet.WalletSign(ctx, signer, buf) + sig, err := c.Wallet.WalletSign(ctx, signer, buf, api.MsgMeta{ + Type: api.MTDealProposal, + }) if err != nil { return nil, err } @@ -434,7 +437,7 @@ func (c *ClientNodeAdapter) SignProposal(ctx context.Context, signer address.Add } func (c *ClientNodeAdapter) GetDefaultWalletAddress(ctx context.Context) (address.Address, error) { - addr, err := c.Wallet.GetDefault() + addr, err := c.DefWallet.GetDefault() return addr, err } @@ -475,7 +478,9 @@ func (c *ClientNodeAdapter) SignBytes(ctx context.Context, signer address.Addres return nil, err } - localSignature, err := c.Wallet.WalletSign(ctx, signer, b) + localSignature, err := c.Wallet.WalletSign(ctx, signer, b, api.MsgMeta{ + Type: api.MTUnknown, // TODO: pass type here + }) if err != nil { return nil, err } diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 33ee75697..49754265d 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -5,14 +5,6 @@ import ( "context" "strconv" - "github.com/filecoin-project/lotus/chain/actors/builtin" - "github.com/filecoin-project/lotus/chain/actors/policy" - - "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg" - - "github.com/filecoin-project/go-state-types/dline" - "github.com/filecoin-project/go-state-types/network" - cid "github.com/ipfs/go-cid" cbor "github.com/ipfs/go-ipld-cbor" "go.uber.org/fx" @@ -22,14 +14,19 @@ import ( "github.com/filecoin-project/go-bitfield" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/go-state-types/dline" + "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/builtin/market" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/actors/builtin/multisig" "github.com/filecoin-project/lotus/chain/actors/builtin/power" "github.com/filecoin-project/lotus/chain/actors/builtin/reward" + "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg" + "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/beacon" "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/state" @@ -47,7 +44,8 @@ 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.LocalWallet + Wallet api.WalletAPI + DefWallet wallet.Default ProofVerifier ffiwrapper.Verifier StateManager *stmgr.StateManager diff --git a/node/impl/full/wallet.go b/node/impl/full/wallet.go index 13880a03a..2e2c48c5d 100644 --- a/node/impl/full/wallet.go +++ b/node/impl/full/wallet.go @@ -49,9 +49,15 @@ func (a *WalletAPI) WalletSignMessage(ctx context.Context, k address.Address, ms return nil, xerrors.Errorf("failed to resolve ID address: %w", keyAddr) } - mcid := msg.Cid() + mb, err := msg.ToStorageBlock() + if err != nil { + return nil, xerrors.Errorf("serializing message: %w", err) + } - sig, err := a.WalletAPI.WalletSign(ctx, k, mcid.Bytes()) + sig, err := a.WalletAPI.WalletSign(ctx, k, mb.Cid().Bytes(), api.MsgMeta{ + Type: api.MTChainMsg, + Extra: mb.RawData(), + }) if err != nil { return nil, xerrors.Errorf("failed to sign message: %w", err) } From 6e8efb9d2cea1e7d828790a8e42ebd030738654e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 9 Oct 2020 01:27:49 +0200 Subject: [PATCH 06/15] gofmt --- api/api_wallet.go | 1 + api/apistruct/struct.go | 16 ++++++++-------- chain/gen/gen.go | 6 +++--- chain/gen/mining.go | 2 +- chain/wallet/remotewallet/remote.go | 2 +- cmd/lotus-wallet/logged.go | 2 +- markets/storageadapter/client.go | 4 ++-- node/impl/full/state.go | 2 +- 8 files changed, 18 insertions(+), 17 deletions(-) diff --git a/api/api_wallet.go b/api/api_wallet.go index 82ef726a0..1213ffc1d 100644 --- a/api/api_wallet.go +++ b/api/api_wallet.go @@ -10,6 +10,7 @@ import ( ) type MsgType string + const ( MTUnknown = "unknown" diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index 81fce92b5..d8c2c8094 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -363,14 +363,14 @@ type WorkerStruct struct { type WalletStruct struct { Internal struct { - WalletNew func(context.Context, crypto.SigType) (address.Address, error) `perm:"write"` - WalletHas func(context.Context, address.Address) (bool, error) `perm:"write"` - WalletList func(context.Context) ([]address.Address, error) `perm:"write"` - WalletSign func(context.Context, address.Address, []byte, api.MsgMeta) (*crypto.Signature, error) `perm:"sign"` - WalletSignMessage func(context.Context, address.Address, *types.Message) (*types.SignedMessage, error) `perm:"sign"` - WalletExport func(context.Context, address.Address) (*types.KeyInfo, error) `perm:"admin"` - WalletImport func(context.Context, *types.KeyInfo) (address.Address, error) `perm:"admin"` - WalletDelete func(context.Context, address.Address) error `perm:"write"` + WalletNew func(context.Context, crypto.SigType) (address.Address, error) `perm:"write"` + WalletHas func(context.Context, address.Address) (bool, error) `perm:"write"` + WalletList func(context.Context) ([]address.Address, error) `perm:"write"` + WalletSign func(context.Context, address.Address, []byte, api.MsgMeta) (*crypto.Signature, error) `perm:"sign"` + WalletSignMessage func(context.Context, address.Address, *types.Message) (*types.SignedMessage, error) `perm:"sign"` + WalletExport func(context.Context, address.Address) (*types.KeyInfo, error) `perm:"admin"` + WalletImport func(context.Context, *types.KeyInfo) (address.Address, error) `perm:"admin"` + WalletDelete func(context.Context, address.Address) error `perm:"write"` } } diff --git a/chain/gen/gen.go b/chain/gen/gen.go index 70c303818..d76835294 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -376,7 +376,7 @@ func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m add sf := func(ctx context.Context, a address.Address, i []byte) (*crypto.Signature, error) { return cg.w.WalletSign(ctx, a, i, api.MsgMeta{ - Type: api.MTUnknown, + Type: api.MTUnknown, }) } @@ -535,7 +535,7 @@ func getRandomMessages(cg *ChainGen) ([]*types.SignedMessage, error) { } sig, err := cg.w.WalletSign(context.TODO(), cg.banker, msg.Cid().Bytes(), api.MsgMeta{ - Type: api.MTUnknown, // testing + Type: api.MTUnknown, // testing }) if err != nil { return nil, err @@ -597,7 +597,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.WalletSign(ctx, a, v, api.MsgMeta{ - Type: api.MTUnknown, + Type: api.MTUnknown, }) } diff --git a/chain/gen/mining.go b/chain/gen/mining.go index 37e8ca2c0..45a089452 100644 --- a/chain/gen/mining.go +++ b/chain/gen/mining.go @@ -131,7 +131,7 @@ func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w api.WalletA } sig, err := w.WalletSign(ctx, waddr, nosigbytes, api.MsgMeta{ - Type: api.MTBlock, + Type: api.MTBlock, }) if err != nil { return nil, xerrors.Errorf("failed to sign new block: %w", err) diff --git a/chain/wallet/remotewallet/remote.go b/chain/wallet/remotewallet/remote.go index 712f270b4..ca4e422d5 100644 --- a/chain/wallet/remotewallet/remote.go +++ b/chain/wallet/remotewallet/remote.go @@ -48,4 +48,4 @@ func SetupRemoteWallet(url string) func(mctx helpers.MetricsCtx, lc fx.Lifecycle return &RemoteWallet{wapi}, nil } -} \ No newline at end of file +} diff --git a/cmd/lotus-wallet/logged.go b/cmd/lotus-wallet/logged.go index 9cd729943..c713c2e87 100644 --- a/cmd/lotus-wallet/logged.go +++ b/cmd/lotus-wallet/logged.go @@ -59,4 +59,4 @@ func (c *LoggedWallet) WalletDelete(ctx context.Context, addr address.Address) e log.Infow("WalletDelete", "address", addr) return c.under.WalletDelete(ctx, addr) -} \ No newline at end of file +} diff --git a/markets/storageadapter/client.go b/markets/storageadapter/client.go index 22ee483ce..080fe36eb 100644 --- a/markets/storageadapter/client.go +++ b/markets/storageadapter/client.go @@ -424,7 +424,7 @@ func (c *ClientNodeAdapter) SignProposal(ctx context.Context, signer address.Add } sig, err := c.Wallet.WalletSign(ctx, signer, buf, api.MsgMeta{ - Type: api.MTDealProposal, + Type: api.MTDealProposal, }) if err != nil { return nil, err @@ -479,7 +479,7 @@ func (c *ClientNodeAdapter) SignBytes(ctx context.Context, signer address.Addres } localSignature, err := c.Wallet.WalletSign(ctx, signer, b, api.MsgMeta{ - Type: api.MTUnknown, // TODO: pass type here + Type: api.MTUnknown, // TODO: pass type here }) if err != nil { return nil, err diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 49754265d..c67b7a887 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -44,7 +44,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 api.WalletAPI + Wallet api.WalletAPI DefWallet wallet.Default ProofVerifier ffiwrapper.Verifier From 7d2f06cfbdd008e8acc41f6a56e7c1ee43c6f12b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 9 Oct 2020 01:33:50 +0200 Subject: [PATCH 07/15] Fix WalletSign in tests --- chain/messagepool/selection_test.go | 20 +++++++++++--------- chain/messagesigner/messagesigner_test.go | 8 ++++---- chain/stmgr/forks_test.go | 19 ++++++++++--------- chain/sync_test.go | 4 ++-- chain/types/mock/chain.go | 3 ++- cmd/lotus-shed/keyinfo.go | 2 +- node/impl/full/wallet.go | 4 +++- 7 files changed, 33 insertions(+), 27 deletions(-) diff --git a/chain/messagepool/selection_test.go b/chain/messagepool/selection_test.go index 72fea4d2c..7dae583ad 100644 --- a/chain/messagepool/selection_test.go +++ b/chain/messagepool/selection_test.go @@ -13,6 +13,10 @@ import ( "sort" "testing" + "github.com/ipfs/go-cid" + "github.com/ipfs/go-datastore" + logging "github.com/ipfs/go-log" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/lotus/build" @@ -21,12 +25,10 @@ import ( "github.com/filecoin-project/lotus/chain/types/mock" "github.com/filecoin-project/lotus/chain/wallet" "github.com/filecoin-project/specs-actors/actors/builtin" - "github.com/ipfs/go-cid" - "github.com/ipfs/go-datastore" + "github.com/filecoin-project/lotus/api" _ "github.com/filecoin-project/lotus/lib/sigs/bls" _ "github.com/filecoin-project/lotus/lib/sigs/secp" - logging "github.com/ipfs/go-log" ) func init() { @@ -45,7 +47,7 @@ func makeTestMessage(w *wallet.LocalWallet, from, to address.Address, nonce uint GasFeeCap: types.NewInt(100 + gasPrice), GasPremium: types.NewInt(gasPrice), } - sig, err := w.WalletSign(context.TODO(), from, msg.Cid().Bytes()) + sig, err := w.WalletSign(context.TODO(), from, msg.Cid().Bytes(), api.MsgMeta{}) if err != nil { panic(err) } @@ -744,7 +746,7 @@ func TestPriorityMessageSelection3(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) } @@ -754,7 +756,7 @@ func TestPriorityMessageSelection3(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) } @@ -1330,7 +1332,7 @@ readLoop: } actorMap := make(map[address.Address]address.Address) - actorWallets := make(map[address.Address]*wallet.Wallet) + actorWallets := make(map[address.Address]api.WalletAPI) for _, m := range msgs { baseNonce := baseNonces[m.Message.From] @@ -1342,7 +1344,7 @@ readLoop: t.Fatal(err) } - a, err := w.GenerateKey(crypto.SigTypeSecp256k1) + a, err := w.WalletNew(context.Background(), crypto.SigTypeSecp256k1) if err != nil { t.Fatal(err) } @@ -1360,7 +1362,7 @@ readLoop: m.Message.From = localActor m.Message.Nonce -= baseNonce - sig, err := w.Sign(context.TODO(), localActor, m.Message.Cid().Bytes()) + sig, err := w.WalletSign(context.TODO(), localActor, m.Message.Cid().Bytes(), api.MsgMeta{}) if err != nil { t.Fatal(err) } diff --git a/chain/messagesigner/messagesigner_test.go b/chain/messagesigner/messagesigner_test.go index 04869ff6d..f50bb2606 100644 --- a/chain/messagesigner/messagesigner_test.go +++ b/chain/messagesigner/messagesigner_test.go @@ -47,13 +47,13 @@ func TestMessageSignerSignMessage(t *testing.T) { ctx := context.Background() w, _ := wallet.NewWallet(wallet.NewMemKeyStore()) - from1, err := w.GenerateKey(crypto.SigTypeSecp256k1) + from1, err := w.WalletNew(ctx, crypto.SigTypeSecp256k1) require.NoError(t, err) - from2, err := w.GenerateKey(crypto.SigTypeSecp256k1) + from2, err := w.WalletNew(ctx, crypto.SigTypeSecp256k1) require.NoError(t, err) - to1, err := w.GenerateKey(crypto.SigTypeSecp256k1) + to1, err := w.WalletNew(ctx, crypto.SigTypeSecp256k1) require.NoError(t, err) - to2, err := w.GenerateKey(crypto.SigTypeSecp256k1) + to2, err := w.WalletNew(ctx, crypto.SigTypeSecp256k1) require.NoError(t, err) type msgSpec struct { diff --git a/chain/stmgr/forks_test.go b/chain/stmgr/forks_test.go index 3687e6b34..0388af6ad 100644 --- a/chain/stmgr/forks_test.go +++ b/chain/stmgr/forks_test.go @@ -6,15 +6,21 @@ import ( "io" "testing" + "github.com/ipfs/go-cid" + ipldcbor "github.com/ipfs/go-ipld-cbor" + logging "github.com/ipfs/go-log" + "github.com/stretchr/testify/require" + cbg "github.com/whyrusleeping/cbor-gen" + "golang.org/x/xerrors" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/cbor" "github.com/filecoin-project/specs-actors/actors/builtin" init0 "github.com/filecoin-project/specs-actors/actors/builtin/init" "github.com/filecoin-project/specs-actors/actors/runtime" - "github.com/stretchr/testify/require" - "golang.org/x/xerrors" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/aerrors" lotusinit "github.com/filecoin-project/lotus/chain/actors/builtin/init" @@ -25,11 +31,6 @@ import ( "github.com/filecoin-project/lotus/chain/vm" _ "github.com/filecoin-project/lotus/lib/sigs/bls" _ "github.com/filecoin-project/lotus/lib/sigs/secp" - - "github.com/ipfs/go-cid" - ipldcbor "github.com/ipfs/go-ipld-cbor" - logging "github.com/ipfs/go-log" - cbg "github.com/whyrusleeping/cbor-gen" ) func init() { @@ -186,7 +187,7 @@ func TestForkHeightTriggers(t *testing.T) { Params: enc, GasLimit: types.TestGasLimit, } - sig, err := cg.Wallet().WalletSign(ctx, cg.Banker(), m.Cid().Bytes()) + sig, err := cg.Wallet().WalletSign(ctx, cg.Banker(), m.Cid().Bytes(), api.MsgMeta{}) if err != nil { t.Fatal(err) } @@ -214,7 +215,7 @@ func TestForkHeightTriggers(t *testing.T) { } nonce++ - sig, err := cg.Wallet().WalletSign(ctx, cg.Banker(), m.Cid().Bytes()) + sig, err := cg.Wallet().WalletSign(ctx, cg.Banker(), m.Cid().Bytes(), api.MsgMeta{}) if err != nil { return nil, err } diff --git a/chain/sync_test.go b/chain/sync_test.go index 2c9f2f131..82d824e62 100644 --- a/chain/sync_test.go +++ b/chain/sync_test.go @@ -593,7 +593,7 @@ func TestDuplicateNonce(t *testing.T) { GasPremium: types.NewInt(0), } - sig, err := tu.g.Wallet().WalletSign(context.TODO(), tu.g.Banker(), msg.Cid().Bytes()) + sig, err := tu.g.Wallet().WalletSign(context.TODO(), tu.g.Banker(), msg.Cid().Bytes(), api.MsgMeta{}) require.NoError(t, err) return &types.SignedMessage{ @@ -685,7 +685,7 @@ func TestBadNonce(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(), api.MsgMeta{}) require.NoError(t, err) return &types.SignedMessage{ diff --git a/chain/types/mock/chain.go b/chain/types/mock/chain.go index 7a9c82cba..2e1c0a976 100644 --- a/chain/types/mock/chain.go +++ b/chain/types/mock/chain.go @@ -9,6 +9,7 @@ import ( "github.com/filecoin-project/go-state-types/crypto" "github.com/ipfs/go-cid" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/wallet" @@ -33,7 +34,7 @@ func MkMessage(from, to address.Address, nonce uint64, w *wallet.LocalWallet) *t GasPremium: types.NewInt(1), } - sig, err := w.WalletSign(context.TODO(), from, msg.Cid().Bytes()) + sig, err := w.WalletSign(context.TODO(), from, msg.Cid().Bytes(), api.MsgMeta{}) if err != nil { panic(err) } diff --git a/cmd/lotus-shed/keyinfo.go b/cmd/lotus-shed/keyinfo.go index 09be67d1e..fdd1fcb49 100644 --- a/cmd/lotus-shed/keyinfo.go +++ b/cmd/lotus-shed/keyinfo.go @@ -105,7 +105,7 @@ var keyinfoVerifyCmd = &cli.Command{ return err } - if _, err := w.Import(&keyInfo); err != nil { + if _, err := w.WalletImport(cctx.Context, &keyInfo); err != nil { return err } diff --git a/node/impl/full/wallet.go b/node/impl/full/wallet.go index 2e2c48c5d..3bbb6556d 100644 --- a/node/impl/full/wallet.go +++ b/node/impl/full/wallet.go @@ -40,7 +40,9 @@ 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.WalletSign(ctx, keyAddr, msg) + return a.WalletAPI.WalletSign(ctx, keyAddr, msg, api.MsgMeta{ + Type: api.MTUnknown, + }) } func (a *WalletAPI) WalletSignMessage(ctx context.Context, k address.Address, msg *types.Message) (*types.SignedMessage, error) { From 791aa5c6c886fe12def84fc4c2910feb9dd434af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 9 Oct 2020 01:37:17 +0200 Subject: [PATCH 08/15] Add lotus-wallet to Makefile --- Makefile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Makefile b/Makefile index 56ab361ec..95a6af8a9 100644 --- a/Makefile +++ b/Makefile @@ -186,6 +186,12 @@ lotus-health: .PHONY: lotus-health BINS+=lotus-health +lotus-wallet: + rm -f lotus-wallet + go build -o lotus-stats ./cmd/lotus-wallet +.PHONY: lotus-wallet +BINS+=lotus-wallet + testground: go build -tags testground -o /dev/null ./cmd/lotus .PHONY: testground From 597d065e0510c240b545d30ee8ffe7fc230176ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 9 Oct 2020 01:39:06 +0200 Subject: [PATCH 09/15] Update go-jsonrpc with http(s) client support --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index e9687c7b8..e1bf6cb3b 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( github.com/filecoin-project/go-data-transfer v0.6.7 github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f github.com/filecoin-project/go-fil-markets v0.7.1 - github.com/filecoin-project/go-jsonrpc v0.1.2-0.20200822201400-474f4fdccc52 + github.com/filecoin-project/go-jsonrpc v0.1.2-0.20201008195726-68c6a2704e49 github.com/filecoin-project/go-multistore v0.0.3 github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20 github.com/filecoin-project/go-paramfetch v0.0.2-0.20200701152213-3e0f0afdc261 diff --git a/go.sum b/go.sum index bab4e929d..ef954e66d 100644 --- a/go.sum +++ b/go.sum @@ -252,8 +252,8 @@ github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CW github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CWaXZc0Hdb/JeX+EQCQzX24= github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0 h1:b3UDemBYN2HNfk3KOXNuxgTTxlWi3xVvbQP0IT38fvM= github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0/go.mod h1:7aWZdaQ1b16BVoQUYR+eEvrDCGJoPLxFpDynFjYfBjI= -github.com/filecoin-project/go-jsonrpc v0.1.2-0.20200822201400-474f4fdccc52 h1:FXtCp0ybqdQL9knb3OGDpkNTaBbPxgkqPeWKotUwkH0= -github.com/filecoin-project/go-jsonrpc v0.1.2-0.20200822201400-474f4fdccc52/go.mod h1:XBBpuKIMaXIIzeqzO1iucq4GvbF8CxmXRFoezRh+Cx4= +github.com/filecoin-project/go-jsonrpc v0.1.2-0.20201008195726-68c6a2704e49 h1:FSY245KeXFCUgyfFEu+bhrZNk8BGGJyfpSmQl2aiPU8= +github.com/filecoin-project/go-jsonrpc v0.1.2-0.20201008195726-68c6a2704e49/go.mod h1:XBBpuKIMaXIIzeqzO1iucq4GvbF8CxmXRFoezRh+Cx4= github.com/filecoin-project/go-multistore v0.0.3 h1:vaRBY4YiA2UZFPK57RNuewypB8u0DzzQwqsL0XarpnI= github.com/filecoin-project/go-multistore v0.0.3/go.mod h1:kaNqCC4IhU4B1uyr7YWFHd23TL4KM32aChS0jNkyUvQ= github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20 h1:+/4aUeUoKr6AKfPE3mBhXA5spIV6UcKdTYDPNU2Tdmg= From 6a10af626c77d083119a00c20dc482376916cccb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 9 Oct 2020 01:50:33 +0200 Subject: [PATCH 10/15] Nicer message logging in lotus-wallet --- cmd/lotus-wallet/logged.go | 33 ++++++++++++++++++++++++++++++++- node/impl/full/wallet.go | 2 +- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/cmd/lotus-wallet/logged.go b/cmd/lotus-wallet/logged.go index c713c2e87..d3630c241 100644 --- a/cmd/lotus-wallet/logged.go +++ b/cmd/lotus-wallet/logged.go @@ -1,7 +1,11 @@ package main import ( + "bytes" "context" + "encoding/hex" + "github.com/ipfs/go-cid" + "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/crypto" @@ -38,7 +42,34 @@ func (c *LoggedWallet) WalletList(ctx context.Context) ([]address.Address, error } func (c *LoggedWallet) WalletSign(ctx context.Context, k address.Address, msg []byte, meta api.MsgMeta) (*crypto.Signature, error) { - log.Infow("WalletSign", "address", k) + switch meta.Type { + case api.MTChainMsg: + var cmsg types.Message + if err := cmsg.UnmarshalCBOR(bytes.NewReader(meta.Extra)); err != nil { + return nil, xerrors.Errorf("unmarshalling message: %w", err) + } + + _, bc, err := cid.CidFromBytes(msg) + if err != nil { + return nil, xerrors.Errorf("getting cid from signing bytes: %w", err) + } + + if !cmsg.Cid().Equals(bc) { + return nil, xerrors.Errorf("cid(meta.Extra).bytes() != msg") + } + + log.Infow("WalletSign", + "address", k, + "type", meta.Type, + "from", cmsg.From, + "to", cmsg.To, + "value", types.FIL(cmsg.Value), + "feecap", types.FIL(cmsg.RequiredFunds()), + "method", cmsg.Method, + "params", hex.EncodeToString(cmsg.Params)) + default: + log.Infow("WalletSign", "address", k, "type", meta.Type) + } return c.under.WalletSign(ctx, k, msg, meta) } diff --git a/node/impl/full/wallet.go b/node/impl/full/wallet.go index 3bbb6556d..1a32cd422 100644 --- a/node/impl/full/wallet.go +++ b/node/impl/full/wallet.go @@ -41,7 +41,7 @@ func (a *WalletAPI) WalletSign(ctx context.Context, k address.Address, msg []byt return nil, xerrors.Errorf("failed to resolve ID address: %w", keyAddr) } return a.WalletAPI.WalletSign(ctx, keyAddr, msg, api.MsgMeta{ - Type: api.MTUnknown, + Type: api.MTUnknown, }) } From 6c54d2445df3a307cfb90de5ff6e1fc22a8d08c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 9 Oct 2020 01:53:12 +0200 Subject: [PATCH 11/15] Appease the linter --- chain/messagesigner/messagesigner.go | 12 +++++++----- chain/wallet/remotewallet/remote.go | 3 ++- markets/storageadapter/client.go | 13 +++++++------ 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/chain/messagesigner/messagesigner.go b/chain/messagesigner/messagesigner.go index c7948e42e..e32a78405 100644 --- a/chain/messagesigner/messagesigner.go +++ b/chain/messagesigner/messagesigner.go @@ -3,18 +3,20 @@ package messagesigner import ( "bytes" "context" - "github.com/filecoin-project/lotus/api" "sync" - "github.com/filecoin-project/go-address" - "github.com/filecoin-project/lotus/chain/messagepool" - "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" logging "github.com/ipfs/go-log/v2" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/messagepool" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/node/modules/dtypes" ) const dsKeyActorNonce = "ActorNextNonce" diff --git a/chain/wallet/remotewallet/remote.go b/chain/wallet/remotewallet/remote.go index ca4e422d5..8454ae6c9 100644 --- a/chain/wallet/remotewallet/remote.go +++ b/chain/wallet/remotewallet/remote.go @@ -2,9 +2,10 @@ package remotewallet import ( "context" + "net/http" + "go.uber.org/fx" "golang.org/x/xerrors" - "net/http" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/client" diff --git a/markets/storageadapter/client.go b/markets/storageadapter/client.go index 080fe36eb..e9a260afe 100644 --- a/markets/storageadapter/client.go +++ b/markets/storageadapter/client.go @@ -5,21 +5,23 @@ package storageadapter import ( "bytes" "context" - "github.com/filecoin-project/lotus/api" - - "github.com/filecoin-project/go-state-types/big" - miner0 "github.com/filecoin-project/specs-actors/actors/builtin" - market0 "github.com/filecoin-project/specs-actors/actors/builtin/market" "golang.org/x/xerrors" + "github.com/ipfs/go-cid" + "github.com/filecoin-project/go-address" cborutil "github.com/filecoin-project/go-cbor-util" "github.com/filecoin-project/go-fil-markets/shared" "github.com/filecoin-project/go-fil-markets/storagemarket" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/exitcode" + miner0 "github.com/filecoin-project/specs-actors/actors/builtin" + market0 "github.com/filecoin-project/specs-actors/actors/builtin/market" + + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/events" @@ -31,7 +33,6 @@ import ( "github.com/filecoin-project/lotus/lib/sigs" "github.com/filecoin-project/lotus/markets/utils" "github.com/filecoin-project/lotus/node/impl/full" - "github.com/ipfs/go-cid" ) type ClientNodeAdapter struct { From 3cd53ad9d9a17024a1a81846daf358a89313cc85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 9 Oct 2020 02:21:37 +0200 Subject: [PATCH 12/15] Use APIInfo parser for RemoteBacked wallet config --- Makefile | 2 +- chain/wallet/remotewallet/remote.go | 26 ++++++++------------------ cli/cmd.go | 29 ++++++++++++++++++++--------- 3 files changed, 29 insertions(+), 28 deletions(-) diff --git a/Makefile b/Makefile index 95a6af8a9..79f7fa81e 100644 --- a/Makefile +++ b/Makefile @@ -188,7 +188,7 @@ BINS+=lotus-health lotus-wallet: rm -f lotus-wallet - go build -o lotus-stats ./cmd/lotus-wallet + go build -o lotus-wallet ./cmd/lotus-wallet .PHONY: lotus-wallet BINS+=lotus-wallet diff --git a/chain/wallet/remotewallet/remote.go b/chain/wallet/remotewallet/remote.go index 8454ae6c9..61deec7ee 100644 --- a/chain/wallet/remotewallet/remote.go +++ b/chain/wallet/remotewallet/remote.go @@ -2,13 +2,13 @@ package remotewallet import ( "context" - "net/http" "go.uber.org/fx" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/client" + lcli "github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/node/modules/helpers" ) @@ -16,26 +16,16 @@ type RemoteWallet struct { api.WalletAPI } -func SetupRemoteWallet(url string) func(mctx helpers.MetricsCtx, lc fx.Lifecycle) (*RemoteWallet, error) { +func SetupRemoteWallet(info string) func(mctx helpers.MetricsCtx, lc fx.Lifecycle) (*RemoteWallet, error) { return func(mctx helpers.MetricsCtx, lc fx.Lifecycle) (*RemoteWallet, error) { - /*sp := strings.SplitN(env, ":", 2) - if len(sp) != 2 { - log.Warnf("invalid env(%s) value, missing token or address", envKey) - } else { - ma, err := multiaddr.NewMultiaddr(sp[1]) - if err != nil { - return APIInfo{}, xerrors.Errorf("could not parse multiaddr from env(%s): %w", envKey, err) - } - return APIInfo{ - Addr: ma, - Token: []byte(sp[0]), - }, nil - }*/ + ai := lcli.ParseApiInfo(info) - headers := http.Header{} - /*headers.Add("Authorization", "Bearer "+token)*/ + url, err := ai.DialArgs() + if err != nil { + return nil, err + } - wapi, closer, err := client.NewWalletRPC(mctx, url, headers) + wapi, closer, err := client.NewWalletRPC(mctx, url, ai.AuthHeader()) if err != nil { return nil, xerrors.Errorf("creating jsonrpc client: %w", err) } diff --git a/cli/cmd.go b/cli/cmd.go index edcb69adc..a3736f8d7 100644 --- a/cli/cmd.go +++ b/cli/cmd.go @@ -7,6 +7,7 @@ import ( "net/url" "os" "os/signal" + "regexp" "strings" "syscall" @@ -153,6 +154,24 @@ func envForRepoDeprecation(t repo.RepoType) string { } } +var ( + infoWithToken = regexp.MustCompile("^[a-zA-Z0-9\\-_]+?\\.[a-zA-Z0-9\\-_]+?\\.([a-zA-Z0-9\\-_]+)?:.+$") +) + +func ParseApiInfo(s string) APIInfo { + var tok []byte + if infoWithToken.Match([]byte(s)) { + sp := strings.SplitN(s, ":", 2) + tok = []byte(sp[0]) + s = sp[1] + } + + return APIInfo{ + Addr: s, + Token: tok, + } +} + func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { // Check if there was a flag passed with the listen address of the API // server (only used by the tests) @@ -175,15 +194,7 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { } } if ok { - sp := strings.SplitN(env, ":", 2) - if len(sp) != 2 { - log.Warnf("invalid env(%s) value, missing token or address", envKey) - } else { - return APIInfo{ - Addr: sp[1], - Token: []byte(sp[0]), - }, nil - } + return ParseApiInfo(env), nil } repoFlag := flagForRepo(t) From 6cc7559b046fc3d5410eb27e460e0aa38321751a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 9 Oct 2020 02:57:41 +0200 Subject: [PATCH 13/15] Fix APIInfo import cycle in tests --- chain/wallet/remotewallet/remote.go | 4 +- cli/cmd.go | 88 +++-------------------------- cli/util/apiinfo.go | 83 +++++++++++++++++++++++++++ cmd/lotus-shed/consensus.go | 3 +- 4 files changed, 95 insertions(+), 83 deletions(-) create mode 100644 cli/util/apiinfo.go diff --git a/chain/wallet/remotewallet/remote.go b/chain/wallet/remotewallet/remote.go index 61deec7ee..c7192f496 100644 --- a/chain/wallet/remotewallet/remote.go +++ b/chain/wallet/remotewallet/remote.go @@ -8,7 +8,7 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/client" - lcli "github.com/filecoin-project/lotus/cli" + cliutil "github.com/filecoin-project/lotus/cli/util" "github.com/filecoin-project/lotus/node/modules/helpers" ) @@ -18,7 +18,7 @@ type RemoteWallet struct { func SetupRemoteWallet(info string) func(mctx helpers.MetricsCtx, lc fx.Lifecycle) (*RemoteWallet, error) { return func(mctx helpers.MetricsCtx, lc fx.Lifecycle) (*RemoteWallet, error) { - ai := lcli.ParseApiInfo(info) + ai := cliutil.ParseApiInfo(info) url, err := ai.DialArgs() if err != nil { diff --git a/cli/cmd.go b/cli/cmd.go index a3736f8d7..fb0706997 100644 --- a/cli/cmd.go +++ b/cli/cmd.go @@ -4,17 +4,13 @@ import ( "context" "fmt" "net/http" - "net/url" "os" "os/signal" - "regexp" "strings" "syscall" logging "github.com/ipfs/go-log/v2" "github.com/mitchellh/go-homedir" - "github.com/multiformats/go-multiaddr" - manet "github.com/multiformats/go-multiaddr/net" "github.com/urfave/cli/v2" "golang.org/x/xerrors" @@ -22,6 +18,7 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/api/client" + cliutil "github.com/filecoin-project/lotus/cli/util" "github.com/filecoin-project/lotus/node/repo" ) @@ -48,57 +45,6 @@ func NewCliError(s string) error { // ApiConnector returns API instance type ApiConnector func() api.FullNode -type APIInfo struct { - Addr string - Token []byte -} - -func (a APIInfo) DialArgs() (string, error) { - ma, err := multiaddr.NewMultiaddr(a.Addr) - if err == nil { - _, addr, err := manet.DialArgs(ma) - if err != nil { - return "", err - } - - return "ws://" + addr + "/rpc/v0", nil - } - - _, err = url.Parse(a.Addr) - if err != nil { - return "", err - } - return a.Addr + "/rpc/v0", nil -} - -func (a APIInfo) Host() (string, error) { - ma, err := multiaddr.NewMultiaddr(a.Addr) - if err == nil { - _, addr, err := manet.DialArgs(ma) - if err != nil { - return "", err - } - - return addr, nil - } - - spec, err := url.Parse(a.Addr) - if err != nil { - return "", err - } - return spec.Host, nil -} - -func (a APIInfo) AuthHeader() http.Header { - if len(a.Token) != 0 { - headers := http.Header{} - headers.Add("Authorization", "Bearer "+string(a.Token)) - return headers - } - log.Warn("API Token not set and requested, capabilities might be limited.") - return nil -} - // The flag passed on the command line with the listen address of the API // server (only used by the tests) func flagForAPI(t repo.RepoType) string { @@ -154,25 +100,7 @@ func envForRepoDeprecation(t repo.RepoType) string { } } -var ( - infoWithToken = regexp.MustCompile("^[a-zA-Z0-9\\-_]+?\\.[a-zA-Z0-9\\-_]+?\\.([a-zA-Z0-9\\-_]+)?:.+$") -) - -func ParseApiInfo(s string) APIInfo { - var tok []byte - if infoWithToken.Match([]byte(s)) { - sp := strings.SplitN(s, ":", 2) - tok = []byte(sp[0]) - s = sp[1] - } - - return APIInfo{ - Addr: s, - Token: tok, - } -} - -func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { +func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (cliutil.APIInfo, error) { // Check if there was a flag passed with the listen address of the API // server (only used by the tests) apiFlag := flagForAPI(t) @@ -180,7 +108,7 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { strma := ctx.String(apiFlag) strma = strings.TrimSpace(strma) - return APIInfo{Addr: strma}, nil + return cliutil.APIInfo{Addr: strma}, nil } envKey := envForRepo(t) @@ -194,24 +122,24 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { } } if ok { - return ParseApiInfo(env), nil + return cliutil.ParseApiInfo(env), nil } repoFlag := flagForRepo(t) p, err := homedir.Expand(ctx.String(repoFlag)) if err != nil { - return APIInfo{}, xerrors.Errorf("could not expand home dir (%s): %w", repoFlag, err) + return cliutil.APIInfo{}, xerrors.Errorf("could not expand home dir (%s): %w", repoFlag, err) } r, err := repo.NewFS(p) if err != nil { - return APIInfo{}, xerrors.Errorf("could not open repo at path: %s; %w", p, err) + return cliutil.APIInfo{}, xerrors.Errorf("could not open repo at path: %s; %w", p, err) } ma, err := r.APIEndpoint() if err != nil { - return APIInfo{}, xerrors.Errorf("could not get api endpoint: %w", err) + return cliutil.APIInfo{}, xerrors.Errorf("could not get api endpoint: %w", err) } token, err := r.APIToken() @@ -219,7 +147,7 @@ func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { log.Warnf("Couldn't load CLI token, capabilities may be limited: %v", err) } - return APIInfo{ + return cliutil.APIInfo{ Addr: ma.String(), Token: token, }, nil diff --git a/cli/util/apiinfo.go b/cli/util/apiinfo.go new file mode 100644 index 000000000..1f9a83769 --- /dev/null +++ b/cli/util/apiinfo.go @@ -0,0 +1,83 @@ +package cliutil + +import ( + "net/http" + "net/url" + "regexp" + "strings" + + logging "github.com/ipfs/go-log/v2" + "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr/net" +) + +var log = logging.Logger("cliutil") + +var ( + infoWithToken = regexp.MustCompile("^[a-zA-Z0-9\\-_]+?\\.[a-zA-Z0-9\\-_]+?\\.([a-zA-Z0-9\\-_]+)?:.+$") +) + +type APIInfo struct { + Addr string + Token []byte +} + +func ParseApiInfo(s string) APIInfo { + var tok []byte + if infoWithToken.Match([]byte(s)) { + sp := strings.SplitN(s, ":", 2) + tok = []byte(sp[0]) + s = sp[1] + } + + return APIInfo{ + Addr: s, + Token: tok, + } +} + +func (a APIInfo) DialArgs() (string, error) { + ma, err := multiaddr.NewMultiaddr(a.Addr) + if err == nil { + _, addr, err := manet.DialArgs(ma) + if err != nil { + return "", err + } + + return "ws://" + addr + "/rpc/v0", nil + } + + _, err = url.Parse(a.Addr) + if err != nil { + return "", err + } + return a.Addr + "/rpc/v0", nil +} + +func (a APIInfo) Host() (string, error) { + ma, err := multiaddr.NewMultiaddr(a.Addr) + if err == nil { + _, addr, err := manet.DialArgs(ma) + if err != nil { + return "", err + } + + return addr, nil + } + + spec, err := url.Parse(a.Addr) + if err != nil { + return "", err + } + return spec.Host, nil +} + +func (a APIInfo) AuthHeader() http.Header { + if len(a.Token) != 0 { + headers := http.Header{} + headers.Add("Authorization", "Bearer "+string(a.Token)) + return headers + } + log.Warn("API Token not set and requested, capabilities might be limited.") + return nil +} diff --git a/cmd/lotus-shed/consensus.go b/cmd/lotus-shed/consensus.go index 38a8cd8ef..1fe7756c1 100644 --- a/cmd/lotus-shed/consensus.go +++ b/cmd/lotus-shed/consensus.go @@ -15,6 +15,7 @@ import ( "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" + cliutil "github.com/filecoin-project/lotus/cli/util" "github.com/libp2p/go-libp2p-core/peer" "github.com/multiformats/go-multiaddr" "github.com/urfave/cli/v2" @@ -111,7 +112,7 @@ var consensusCheckCmd = &cli.Command{ if err != nil { return err } - ainfo := lcli.APIInfo{Addr: apima.String()} + ainfo := cliutil.APIInfo{Addr: apima.String()} addr, err := ainfo.DialArgs() if err != nil { return err From 356137439f2cd0bcca2d11d8ab616d97b6eae064 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Fri, 9 Oct 2020 03:00:30 +0200 Subject: [PATCH 14/15] apistruct: Drop unused WalletSignMessage --- api/apistruct/struct.go | 19 +++++++------------ cmd/lotus-wallet/logged.go | 1 + 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index d8c2c8094..0265701d6 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -363,14 +363,13 @@ type WorkerStruct struct { type WalletStruct struct { Internal struct { - WalletNew func(context.Context, crypto.SigType) (address.Address, error) `perm:"write"` - WalletHas func(context.Context, address.Address) (bool, error) `perm:"write"` - WalletList func(context.Context) ([]address.Address, error) `perm:"write"` - WalletSign func(context.Context, address.Address, []byte, api.MsgMeta) (*crypto.Signature, error) `perm:"sign"` - WalletSignMessage func(context.Context, address.Address, *types.Message) (*types.SignedMessage, error) `perm:"sign"` - WalletExport func(context.Context, address.Address) (*types.KeyInfo, error) `perm:"admin"` - WalletImport func(context.Context, *types.KeyInfo) (address.Address, error) `perm:"admin"` - WalletDelete func(context.Context, address.Address) error `perm:"write"` + WalletNew func(context.Context, crypto.SigType) (address.Address, error) `perm:"write"` + WalletHas func(context.Context, address.Address) (bool, error) `perm:"write"` + WalletList func(context.Context) ([]address.Address, error) `perm:"write"` + WalletSign func(context.Context, address.Address, []byte, api.MsgMeta) (*crypto.Signature, error) `perm:"sign"` + WalletExport func(context.Context, address.Address) (*types.KeyInfo, error) `perm:"admin"` + WalletImport func(context.Context, *types.KeyInfo) (address.Address, error) `perm:"admin"` + WalletDelete func(context.Context, address.Address) error `perm:"write"` } } @@ -1401,10 +1400,6 @@ func (c *WalletStruct) WalletSign(ctx context.Context, k address.Address, msg [] return c.Internal.WalletSign(ctx, k, msg, meta) } -func (c *WalletStruct) WalletSignMessage(ctx context.Context, k address.Address, msg *types.Message) (*types.SignedMessage, error) { - return c.Internal.WalletSignMessage(ctx, k, msg) -} - func (c *WalletStruct) WalletExport(ctx context.Context, a address.Address) (*types.KeyInfo, error) { return c.Internal.WalletExport(ctx, a) } diff --git a/cmd/lotus-wallet/logged.go b/cmd/lotus-wallet/logged.go index d3630c241..3bcb3f867 100644 --- a/cmd/lotus-wallet/logged.go +++ b/cmd/lotus-wallet/logged.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "encoding/hex" + "github.com/ipfs/go-cid" "golang.org/x/xerrors" From f773ab4b2824b2549f7768dc83ae200aa00ddaa2 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Fri, 9 Oct 2020 17:14:21 -0400 Subject: [PATCH 15/15] Correct docs --- api/api_full.go | 3 +-- documentation/en/api-methods.md | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index 777e996cb..7ebc8791a 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -422,8 +422,7 @@ type FullNode interface { // MsigGetAvailableBalance returns the portion of a multisig's balance that can be withdrawn or spent MsigGetAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) - // MsigGetLockedBalance returns the locked balance of an msig at a vien epoch. - // The return may be greater than the multisig actor's actual balance. + // MsigGetVestingSchedule returns the vesting details of a given multisig. MsigGetVestingSchedule(context.Context, address.Address, types.TipSetKey) (MsigVesting, error) // MsigGetVested returns the amount of FIL that vested in a multisig in a certain period. // It takes the following params: , , diff --git a/documentation/en/api-methods.md b/documentation/en/api-methods.md index cc6d92e4f..b3a9627e0 100644 --- a/documentation/en/api-methods.md +++ b/documentation/en/api-methods.md @@ -2146,8 +2146,7 @@ Inputs: Response: `"0"` ### MsigGetVestingSchedule -MsigGetLockedBalance returns the locked balance of an msig at a vien epoch. -The return may be greater than the multisig actor's actual balance. +MsigGetVestingSchedule returns the vesting details of a given multisig. Perms: read