Skip to content

Commit

Permalink
Merge pull request #6396 from filecoin-project/feat/use-gateway-for-f…
Browse files Browse the repository at this point in the history
…3-sign

feat: Use sophon gateway to sign f3 message
  • Loading branch information
simlecode authored Oct 9, 2024
2 parents 8b23108 + 61db1e9 commit 102a6b1
Show file tree
Hide file tree
Showing 15 changed files with 236 additions and 26 deletions.
2 changes: 1 addition & 1 deletion app/node/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func (b *Builder) build(ctx context.Context) (*Node, error) {
return nil, errors.Wrap(err, "failed to build node.wallet")
}

nd.f3, err = f3.NewF3Submodule(ctx, nd.repo, nd.chain, nd.network, nd.wallet.API())
nd.f3, err = f3.NewF3Submodule(ctx, nd.repo, nd.chain, nd.network, nd.wallet.GetWalletSign())
if err != nil {
return nil, errors.Wrap(err, "failed to build node.f3")
}
Expand Down
2 changes: 2 additions & 0 deletions app/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,8 @@ func (node *Node) Stop(ctx context.Context) {
log.Warnf("error shutdown jaeger-tracing: %w", err)
}
}

node.Wallet().WalletGateway.Close()
}

// RunRPCAndWait start rpc server and listen to signal to exit
Expand Down
5 changes: 3 additions & 2 deletions app/submodule/f3/f3_submodule.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/filecoin-project/venus/app/submodule/network"
"github.com/filecoin-project/venus/pkg/repo"
"github.com/filecoin-project/venus/pkg/vf3"
"github.com/filecoin-project/venus/pkg/wallet"
v1api "github.com/filecoin-project/venus/venus-shared/api/chain/v1"
logging "github.com/ipfs/go-log"
)
Expand All @@ -21,7 +22,7 @@ func NewF3Submodule(ctx context.Context,
repo repo.Repo,
chain *chain.ChainSubmodule,
network *network.NetworkSubmodule,
walletAPI v1api.IWallet,
walletSign wallet.WalletSignFunc,
) (*F3Submodule, error) {
netConf := repo.Config().NetworkParams
if !netConf.F3Enabled {
Expand All @@ -36,7 +37,7 @@ func NewF3Submodule(ctx context.Context,
ChainStore: chain.ChainReader,
StateManager: chain.Stmgr,
Datastore: repo.MetaDatastore(),
Wallet: walletAPI,
WalletSign: walletSign,
ManifestProvider: vf3.NewManifestProvider(network.NetworkName, repo.MetaDatastore(), network.Pubsub, netConf),
})
if err != nil {
Expand Down
44 changes: 34 additions & 10 deletions app/submodule/wallet/wallet_submodule.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package wallet

import (
"context"
"fmt"
"strings"

v0api "github.com/filecoin-project/venus/venus-shared/api/chain/v0"
v1api "github.com/filecoin-project/venus/venus-shared/api/chain/v1"
Expand All @@ -16,18 +18,20 @@ import (
"github.com/filecoin-project/venus/pkg/repo"
"github.com/filecoin-project/venus/pkg/state"
"github.com/filecoin-project/venus/pkg/wallet"
"github.com/filecoin-project/venus/pkg/wallet/gateway"
"github.com/filecoin-project/venus/venus-shared/types"
)

var log = logging.Logger("wallet")

// WalletSubmodule enhances the `Node` with a "wallet" and FIL transfer capabilities.
type WalletSubmodule struct { // nolint
Chain *chain.ChainSubmodule
Wallet *wallet.Wallet
adapter wallet.WalletIntersection
Signer types.Signer
Config *config.ConfigModule
Chain *chain.ChainSubmodule
Wallet *wallet.Wallet
adapter wallet.WalletIntersection
Signer types.Signer
Config *config.ConfigModule
WalletGateway *gateway.WalletGateway
}

type walletRepo interface {
Expand Down Expand Up @@ -66,12 +70,25 @@ func NewWalletSubmodule(ctx context.Context,
} else {
adapter = fcWallet
}

var wg *gateway.WalletGateway
if len(repo.Config().Wallet.GatewayBacked) != 0 {
// GatewayBacked token:url
tokenURL := strings.SplitN(repo.Config().Wallet.GatewayBacked, ":", 2)
fmt.Println(tokenURL)
wg, err = gateway.NewWalletGateway(ctx, tokenURL[1], tokenURL[0])
if err != nil {
return nil, err
}
log.Info("wallet gateway set up")
}
return &WalletSubmodule{
Config: cfgModule,
Chain: chain,
Wallet: fcWallet,
adapter: adapter,
Signer: state.NewSigner(headSigner, fcWallet),
Config: cfgModule,
Chain: chain,
Wallet: fcWallet,
adapter: adapter,
Signer: state.NewSigner(headSigner, fcWallet),
WalletGateway: wg,
}, nil
}

Expand All @@ -94,6 +111,13 @@ func (wallet *WalletSubmodule) WalletIntersection() wallet.WalletIntersection {
return wallet.adapter
}

func (wallet *WalletSubmodule) GetWalletSign() wallet.WalletSignFunc {
if wallet.WalletGateway == nil {
return wallet.adapter.WalletSign
}
return wallet.WalletGateway.WalletSign
}

func getPassphraseConfig(cfg *pconfig.Config) (pconfig.PassphraseConfig, error) {
return pconfig.PassphraseConfig{
ScryptN: cfg.Wallet.PassphraseConfig.ScryptN,
Expand Down
7 changes: 7 additions & 0 deletions cmd/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ var daemonCmd = &cmds.Command{
cmds.StringOption(Network, "when set, populates config with network specific parameters, eg. mainnet,2k,calibrationnet,interopnet,butterflynet").WithDefault("mainnet"),
cmds.StringOption(Password, "set wallet password"),
cmds.StringOption(Profile, "specify type of node, eg. bootstrapper"),
cmds.StringOption(WalletGateway, "set sophon gateway url and token, eg. token:url"),
},
Run: func(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment) error {
if limit, _ := req.Options[ULimit].(bool); limit {
Expand Down Expand Up @@ -168,6 +169,9 @@ func initRun(req *cmds.Request, repoDir string) error {
return fmt.Errorf("must also pass token with venus auth service to `--%s`", AuthServiceToken)
}
}
if walletGateway, ok := req.Options[WalletGateway].(string); ok && len(walletGateway) > 0 {
cfg.Wallet.GatewayBacked = walletGateway
}

if err := rep.ReplaceConfig(cfg); err != nil {
log.Errorf("Error replacing config %s", err)
Expand Down Expand Up @@ -240,6 +244,9 @@ func daemonRun(req *cmds.Request, re cmds.ResponseEmitter) error {
if len(config.API.VenusAuthURL)+len(config.API.VenusAuthToken) > 0 && len(config.API.VenusAuthToken)*len(config.API.VenusAuthURL) == 0 {
return fmt.Errorf("must set both venus auth service url and token at the same time")
}
if walletGateway, ok := req.Options[WalletGateway].(string); ok && len(walletGateway) > 0 {
config.Wallet.GatewayBacked = walletGateway
}

if bootPeers, ok := req.Options[BootstrapPeers].([]string); ok && len(bootPeers) > 0 {
config.Bootstrap.AddPeers(bootPeers...)
Expand Down
2 changes: 2 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ const (
AuthServiceURL = "auth-url"
AuthServiceToken = "auth-token"

WalletGateway = "wallet-gateway"

BootstrapPeers = "bootstrap-peers"

Profile = "profile"
Expand Down
1 change: 1 addition & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ type WalletConfig struct {
PassphraseConfig PassphraseConfig `json:"passphraseConfig,omitempty"`
RemoteEnable bool `json:"remoteEnable"`
RemoteBackend string `json:"remoteBackend"`
GatewayBacked string `json:"gatewayBacked"`
}

type PassphraseConfig struct {
Expand Down
12 changes: 6 additions & 6 deletions pkg/vf3/ec.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,12 @@ func (ec *ecWrapper) GetTipsetByEpoch(ctx context.Context, epoch int64) (ec.TipS
}

func (ec *ecWrapper) GetTipset(ctx context.Context, tsk gpbft.TipSetKey) (ec.TipSet, error) {
tskLotus, err := types.TipSetKeyFromBytes(tsk)
key, err := types.TipSetKeyFromBytes(tsk)
if err != nil {
return nil, fmt.Errorf("decoding tsk: %w", err)
}

ts, err := ec.ChainStore.GetTipSet(ctx, tskLotus)
ts, err := ec.ChainStore.GetTipSet(ctx, key)
if err != nil {
return nil, fmt.Errorf("getting tipset by key: %w", err)
}
Expand All @@ -104,11 +104,11 @@ func (ec *ecWrapper) GetParent(ctx context.Context, tsF3 ec.TipSet) (ec.TipSet,
//
// TODO: Revisit the type check here and remove as needed once testing
// is over and fake EC backend goes away.
tskLotus, err := types.TipSetKeyFromBytes(tsF3.Key())
tsk, err := types.TipSetKeyFromBytes(tsF3.Key())
if err != nil {
return nil, fmt.Errorf("decoding tsk: %w", err)
}
ts, err = ec.ChainStore.GetTipSet(ctx, tskLotus)
ts, err = ec.ChainStore.GetTipSet(ctx, tsk)
if err != nil {
return nil, fmt.Errorf("getting tipset by key for get parent: %w", err)
}
Expand All @@ -125,10 +125,10 @@ func (ec *ecWrapper) GetPowerTable(ctx context.Context, tskF3 gpbft.TipSetKey) (
if err != nil {
return nil, fmt.Errorf("decoding tsk: %w", err)
}
return ec.getPowerTableLotusTSK(ctx, tsk)
return ec.getPowerTableTSK(ctx, tsk)
}

func (ec *ecWrapper) getPowerTableLotusTSK(ctx context.Context, tsk types.TipSetKey) (gpbft.PowerEntries, error) {
func (ec *ecWrapper) getPowerTableTSK(ctx context.Context, tsk types.TipSetKey) (gpbft.PowerEntries, error) {
ts, err := ec.ChainStore.GetTipSet(ctx, tsk)
if err != nil {
return nil, fmt.Errorf("getting tipset by key for get parent: %w", err)
Expand Down
8 changes: 4 additions & 4 deletions pkg/vf3/f3.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
"github.com/filecoin-project/go-f3/manifest"
"github.com/filecoin-project/venus/pkg/chain"
"github.com/filecoin-project/venus/pkg/statemanger"
v1api "github.com/filecoin-project/venus/venus-shared/api/chain/v1"
"github.com/filecoin-project/venus/pkg/wallet"
"github.com/filecoin-project/venus/venus-shared/types"
logging "github.com/ipfs/go-log"
)
Expand Down Expand Up @@ -56,7 +56,7 @@ type F3Params struct {
ChainStore *chain.Store
StateManager *statemanger.Stmgr
Datastore datastore.Batching
Wallet v1api.IWallet
WalletSign wallet.WalletSignFunc
}

var log = logging.Logger("f3")
Expand All @@ -79,7 +79,7 @@ func New(mctx context.Context, params F3Params) (*F3, error) {
fff := &F3{
inner: module,
ec: ec,
signer: &signer{params.Wallet},
signer: &signer{sign: params.WalletSign},
newLeases: make(chan leaseRequest, 4), // some buffer to avoid
}

Expand Down Expand Up @@ -174,7 +174,7 @@ func (fff *F3) GetLatestCert(ctx context.Context) (*certs.FinalityCertificate, e
}

func (fff *F3) GetPowerTable(ctx context.Context, tsk types.TipSetKey) (gpbft.PowerEntries, error) {
return fff.ec.getPowerTableLotusTSK(ctx, tsk)
return fff.ec.getPowerTableTSK(ctx, tsk)
}

func (fff *F3) GetF3PowerTable(ctx context.Context, tsk types.TipSetKey) (gpbft.PowerEntries, error) {
Expand Down
6 changes: 3 additions & 3 deletions pkg/vf3/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import (

"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-f3/gpbft"
v1api "github.com/filecoin-project/venus/venus-shared/api/chain/v1"
"github.com/filecoin-project/venus/pkg/wallet"
"github.com/filecoin-project/venus/venus-shared/types"
)

type signer struct {
wallet v1api.IWallet
sign wallet.WalletSignFunc
}

// Sign signs a message with the private key corresponding to a public key.
Expand All @@ -21,7 +21,7 @@ func (s *signer) Sign(ctx context.Context, sender gpbft.PubKey, msg []byte) ([]b
if err != nil {
return nil, fmt.Errorf("converting pubkey to address: %w", err)
}
sig, err := s.wallet.WalletSign(ctx, addr, msg, types.MsgMeta{Type: types.MTUnknown})
sig, err := s.sign(ctx, addr, msg, types.MsgMeta{Type: types.MTF3})
if err != nil {
return nil, fmt.Errorf("error while signing: %w", err)
}
Expand Down
117 changes: 117 additions & 0 deletions pkg/wallet/gateway/wallet_gateway.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package gateway

import (
"context"
"fmt"
"sync"
"time"

"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-jsonrpc"
"github.com/filecoin-project/venus/pkg/crypto"
gatewayAPI "github.com/filecoin-project/venus/venus-shared/api/gateway/v2"
"github.com/filecoin-project/venus/venus-shared/types"
logging "github.com/ipfs/go-log/v2"
)

var log = logging.Logger("wallet-gateway")

type WalletGateway struct {
cli gatewayAPI.IWalletClient
closer jsonrpc.ClientCloser

addressAccount map[address.Address][]string

lk sync.RWMutex
}

func NewWalletGateway(ctx context.Context, url, token string) (*WalletGateway, error) {
cli, close, err := gatewayAPI.DialIGatewayRPC(ctx, url, token, nil)
if err != nil {
return nil, err
}

wg := &WalletGateway{cli: cli, closer: close, addressAccount: map[address.Address][]string{}}
err = wg.updateAddressAccount(ctx)
if err != nil {
return nil, err
}
go wg.loopUpdateAddressAccount(ctx)

return wg, nil
}

func (w *WalletGateway) updateAddressAccount(ctx context.Context) error {
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()

w.lk.Lock()
defer w.lk.Unlock()

wds, err := w.cli.ListWalletInfo(ctx)
if err != nil {
return err
}

for _, wd := range wds {
accountMap := map[string]struct{}{
wd.Account: {},
}
accounts := []string{wd.Account}
for _, account := range wd.SupportAccounts {
if _, ok := accountMap[account]; ok {
continue
}
accounts = append(accounts, account)
accountMap[account] = struct{}{}
}

addrs := make(map[address.Address]struct{}, 0)
for _, cs := range wd.ConnectStates {
for _, addr := range cs.Addrs {
addrs[addr] = struct{}{}
}
}

for addr := range addrs {
w.addressAccount[addr] = accounts
}
}

return err
}

func (w *WalletGateway) loopUpdateAddressAccount(ctx context.Context) {
ticker := time.NewTicker(10 * time.Minute)
defer ticker.Stop()

for {
select {
case <-ticker.C:
err := w.updateAddressAccount(ctx)
if err != nil {
log.Errorf("update address account failed: %s", err)
}
case <-ctx.Done():
return
}
}
}

func (w *WalletGateway) Close() {
if w == nil {
return
}
w.closer()
}

func (w *WalletGateway) WalletSign(ctx context.Context, k address.Address, msg []byte, meta types.MsgMeta) (*crypto.Signature, error) {
w.lk.RLock()
accounts, ok := w.addressAccount[k]
w.lk.RUnlock()
if !ok {
return nil, fmt.Errorf("address %s not found", k)
}

return w.cli.WalletSign(ctx, k, accounts, msg, meta)
}
Loading

0 comments on commit 102a6b1

Please sign in to comment.