code.vegaprotocol.io/vega@v0.79.0/core/admin/nodewallets.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package admin
    17  
    18  import (
    19  	"fmt"
    20  	"net/http"
    21  
    22  	"code.vegaprotocol.io/vega/core/nodewallets"
    23  	"code.vegaprotocol.io/vega/core/nodewallets/eth/clef"
    24  	"code.vegaprotocol.io/vega/core/nodewallets/eth/keystore"
    25  	"code.vegaprotocol.io/vega/core/nodewallets/registry"
    26  	"code.vegaprotocol.io/vega/libs/crypto"
    27  	"code.vegaprotocol.io/vega/logging"
    28  	"code.vegaprotocol.io/vega/paths"
    29  )
    30  
    31  type wallet interface {
    32  	Name() string
    33  	PubKey() crypto.PublicKey
    34  }
    35  
    36  type Wallet struct {
    37  	Name      string `json:"name"`
    38  	PublicKey string `json:"publicKey"`
    39  }
    40  
    41  func newWallet(w wallet) Wallet {
    42  	return Wallet{
    43  		Name:      w.Name(),
    44  		PublicKey: w.PubKey().Hex(),
    45  	}
    46  }
    47  
    48  type NodeWalletArgs struct {
    49  	Chain string
    50  }
    51  
    52  type NodeWalletReloadReply struct {
    53  	OldWallet Wallet `json:"oldWallet"`
    54  	NewWallet Wallet `json:"newWallet"`
    55  }
    56  
    57  type NodeWallet struct {
    58  	log                  *logging.Logger
    59  	nodeWallets          *nodewallets.NodeWallets
    60  	registryLoader       *registry.Loader
    61  	nodeWalletPassphrase string
    62  	vegaPaths            paths.Paths
    63  }
    64  
    65  func NewNodeWallet(
    66  	log *logging.Logger,
    67  	vegaPaths paths.Paths,
    68  	nodeWalletPassphrase string,
    69  	nodeWallets *nodewallets.NodeWallets,
    70  ) (*NodeWallet, error) {
    71  	registryLoader, err := registry.NewLoader(vegaPaths, nodeWalletPassphrase)
    72  	if err != nil {
    73  		return nil, err
    74  	}
    75  
    76  	return &NodeWallet{
    77  		log:                  log.Named(nodeWalletNamedLogger),
    78  		nodeWallets:          nodeWallets,
    79  		registryLoader:       registryLoader,
    80  		nodeWalletPassphrase: nodeWalletPassphrase,
    81  		vegaPaths:            vegaPaths,
    82  	}, nil
    83  }
    84  
    85  func (nw *NodeWallet) Reload(_ *http.Request, args *NodeWalletArgs, reply *NodeWalletReloadReply) error {
    86  	nw.log.Info("Reloading node wallet", logging.String("chain", args.Chain))
    87  
    88  	switch args.Chain {
    89  	case "vega":
    90  		oW := newWallet(nw.nodeWallets.Vega)
    91  
    92  		reg, err := nw.registryLoader.Get(nw.nodeWalletPassphrase)
    93  		if err != nil {
    94  			return fmt.Errorf("couldn't load node wallet registry: %v", err)
    95  		}
    96  
    97  		if err := nw.nodeWallets.Vega.Reload(*reg.Vega); err != nil {
    98  			nw.log.Error("Reloading node wallet failed", logging.Error(err))
    99  			return fmt.Errorf("failed to reload Vega wallet: %w", err)
   100  		}
   101  
   102  		nW := newWallet(nw.nodeWallets.Vega)
   103  
   104  		reply.NewWallet = nW
   105  		reply.OldWallet = oW
   106  
   107  		nw.log.Info("Reloaded node wallet", logging.String("chain", args.Chain))
   108  		return nil
   109  	case "ethereum":
   110  		oW := newWallet(nw.nodeWallets.Ethereum)
   111  
   112  		reg, err := nw.registryLoader.Get(nw.nodeWalletPassphrase)
   113  		if err != nil {
   114  			return fmt.Errorf("couldn't load node wallet registry: %v", err)
   115  		}
   116  
   117  		algoType := nw.nodeWallets.Ethereum.Algo()
   118  		_, isKeyStoreWallet := reg.Ethereum.Details.(registry.EthereumKeyStoreWallet)
   119  		_, isClefWallet := reg.Ethereum.Details.(registry.EthereumClefWallet)
   120  
   121  		if isKeyStoreWallet && algoType != keystore.KeyStoreAlgoType {
   122  			w, err := nodewallets.GetEthereumWalletWithRegistry(nw.vegaPaths, reg)
   123  			if err != nil {
   124  				return fmt.Errorf("failed reload key: %w", err)
   125  			}
   126  
   127  			nw.nodeWallets.SetEthereumWallet(w)
   128  		} else if isClefWallet && algoType != clef.ClefAlgoType {
   129  			w, err := nodewallets.GetEthereumWalletWithRegistry(
   130  				nw.vegaPaths,
   131  				reg,
   132  			)
   133  			if err != nil {
   134  				return fmt.Errorf("failed reload key: %w", err)
   135  			}
   136  
   137  			nw.nodeWallets.SetEthereumWallet(w)
   138  		} else {
   139  			if err := nw.nodeWallets.Ethereum.Reload(reg.Ethereum.Details); err != nil {
   140  				nw.log.Error("Reloading node wallet failed", logging.Error(err))
   141  				return fmt.Errorf("failed to reload Ethereum wallet: %w", err)
   142  			}
   143  		}
   144  
   145  		nW := newWallet(nw.nodeWallets.Ethereum)
   146  
   147  		reply.NewWallet = nW
   148  		reply.OldWallet = oW
   149  
   150  		nw.log.Info("Reloaded node wallet", logging.String("chain", args.Chain))
   151  		return nil
   152  	}
   153  
   154  	return fmt.Errorf("failed to reload wallet for non existing chain %q", args.Chain)
   155  }
   156  
   157  func (nw *NodeWallet) Show(_ *http.Request, args *NodeWalletArgs, reply *Wallet) error {
   158  	switch args.Chain {
   159  	case "vega":
   160  		*reply = newWallet(nw.nodeWallets.Vega)
   161  		return nil
   162  	case "ethereum":
   163  		*reply = newWallet(nw.nodeWallets.Ethereum)
   164  		return nil
   165  	}
   166  
   167  	return fmt.Errorf("failed to show wallet for non existing chain %q", args.Chain)
   168  }