diff --git a/consensus/consensus.go b/consensus/consensus.go index 513ea64..29f9068 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -22,6 +22,7 @@ type PBFTConsensusManager struct { psb *pb.PubSubRouter Consensuses map[string]*ConsensusData maxFaultNodes int + miner *Miner } type ConsensusData struct { diff --git a/consensus/leader.go b/consensus/leader.go index 7d06d30..6f53b7d 100644 --- a/consensus/leader.go +++ b/consensus/leader.go @@ -41,7 +41,7 @@ func VerifyVRF(ctx context.Context, worker peer.ID, vrfBase, vrfproof []byte) er } func IsRoundWinner(ctx context.Context, round types.DrandRound, - worker peer.ID, brand types.BeaconEntry, minerStake, networkStake types.BigInt, a MinerAPI) (*types.ElectionProof, error) { + worker peer.ID, brand types.BeaconEntry, minerStake, networkStake types.BigInt, a WalletAPI) (*types.ElectionProof, error) { buf, err := worker.MarshalBinary() if err != nil { diff --git a/consensus/miner.go b/consensus/miner.go index d9e3267..612d1bc 100644 --- a/consensus/miner.go +++ b/consensus/miner.go @@ -19,7 +19,7 @@ import ( type Miner struct { address peer.ID ethAddress common.Address - api MinerAPI + api WalletAPI mutex sync.Mutex beacon beacon.BeaconNetworks ethClient *ethclient.EthereumClient @@ -27,9 +27,24 @@ type Miner struct { networkStake types.BigInt } -type MinerAPI interface { +func NewMiner( + address peer.ID, + ethAddress common.Address, + api WalletAPI, + beacon beacon.BeaconNetworks, + ethClient *ethclient.EthereumClient, +) *Miner { + return &Miner{ + address: address, + ethAddress: ethAddress, + api: api, + beacon: beacon, + ethClient: ethClient, + } +} + +type WalletAPI interface { WalletSign(context.Context, peer.ID, []byte) (*types.Signature, error) - // TODO: get miner base based on epoch; } func (m *Miner) UpdateCurrentStakeInfo() error { @@ -53,7 +68,7 @@ func (m *Miner) UpdateCurrentStakeInfo() error { return nil } -func (m *Miner) MineTask(ctx context.Context) (*types.DioneTask, error) { +func (m *Miner) MineTask(ctx context.Context, payload []byte) (*types.DioneTask, error) { bvals, err := beacon.BeaconEntriesForTask(ctx, m.beacon) if err != nil { return nil, xerrors.Errorf("failed to get beacon entries: %w", err) @@ -84,6 +99,7 @@ func (m *Miner) MineTask(ctx context.Context) (*types.DioneTask, error) { Ticket: ticket, ElectionProof: winner, BeaconEntries: bvals, + Payload: payload, // TODO: signature DrandRound: types.DrandRound(rbase.Round), }, nil diff --git a/ethclient/ethereum.go b/ethclient/ethereum.go index 531f1ef..39e6f2a 100644 --- a/ethclient/ethereum.go +++ b/ethclient/ethereum.go @@ -54,9 +54,9 @@ func (c *EthereumClient) Initialize(ctx context.Context, url, privateKey, oracle if err != nil { return err } - c.ethAddress = &c.authTransactor.From authTransactor := bind.NewKeyedTransactor(ecdsaKey) c.authTransactor = authTransactor + c.ethAddress = &c.authTransactor.From oracleEmitter, err := oracleemitter.NewOracleEmitter(common.HexToAddress(oracleEmitterContractAddress), client) if err != nil { @@ -99,6 +99,10 @@ func (c *EthereumClient) Initialize(ctx context.Context, url, privateKey, oracle return nil } +func (c *EthereumClient) GetEthAddress() *common.Address { + return c.ethAddress +} + // // Balance returns the balance of the given ethereum address. // func (c *EthereumClient) Balance(ctx context.Context, address string) (*big.Int, error) { // ethereumAddress := common.HexToAddress(address) diff --git a/ethclient/wallet.go b/ethclient/wallet.go deleted file mode 100644 index ecbcfdd..0000000 --- a/ethclient/wallet.go +++ /dev/null @@ -1,35 +0,0 @@ -package ethclient - -import ( - "crypto/ecdsa" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/crypto" - "github.com/sirupsen/logrus" -) - -func GenerateEthWalletAddressFromPrivateKey(private_key string) common.Address { - privateKey, err := crypto.HexToECDSA(private_key) - if err != nil { - logrus.Fatal("Failed to generate private key", err) - } - - publicKey := privateKey.Public() - publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey) - if !ok { - logrus.Fatal("cannot assert type: publicKey is not of type *ecdsa.PublicKey") - } - - publicKeyBytes := crypto.FromECDSAPub(publicKeyECDSA) - logrus.Info(hexutil.Encode(publicKeyBytes)[4:]) - - address := crypto.PubkeyToAddress(*publicKeyECDSA) - - return address -} - -// Convert common.Address type into string for ethereum wallet -func EthWalletToString(ethWallet common.Address) string { - return ethWallet.Hex() -} diff --git a/node/node.go b/node/node.go index bddcb13..6e67952 100644 --- a/node/node.go +++ b/node/node.go @@ -7,6 +7,14 @@ import ( "fmt" "time" + "github.com/Secured-Finance/dione/types" + + "github.com/Secured-Finance/dione/wallet" + + "golang.org/x/xerrors" + + "github.com/Secured-Finance/dione/beacon" + pex "github.com/Secured-Finance/go-libp2p-pex" "github.com/Secured-Finance/dione/config" @@ -35,7 +43,9 @@ type Node struct { Lotus *rpc.LotusClient Ethereum *ethclient.EthereumClient ConsensusManager *consensus.PBFTConsensusManager - MinerBase *consensus.MinerBase + Miner *consensus.Miner + Beacon beacon.BeaconNetworks + Wallet *wallet.LocalWallet } func NewNode(configPath string) (*Node, error) { @@ -53,16 +63,59 @@ func NewNode(configPath string) (*Node, error) { func (n *Node) setupNode(ctx context.Context, prvKey crypto.PrivKey, pexDiscoveryUpdateTime time.Duration) { n.setupLibp2pHost(context.TODO(), prvKey, pexDiscoveryUpdateTime) - if err := n.setupEthereumClient(); err != nil { - logrus.Fatal("Can't set up an ethereum client, exiting... ", err) - } //n.setupFilecoinClient() + err := n.setupEthereumClient() + if err != nil { + logrus.Fatal(err) + } n.setupPubsub() n.setupConsensusManager(n.Config.ConsensusMaxFaultNodes) + err = n.setupBeacon() + if err != nil { + logrus.Fatal(err) + } + err = n.setupWallet(prvKey) + if err != nil { + logrus.Fatal(err) + } + err = n.setupMiner() + if err != nil { + logrus.Fatal(err) + } } func (n *Node) setupMiner() error { - // here we do miner base setup + n.Miner = consensus.NewMiner(n.Host.ID(), *n.Ethereum.GetEthAddress(), n.Wallet, n.Beacon, n.Ethereum) + return nil +} + +func (n *Node) setupBeacon() error { + beacon, err := n.NewBeaconClient() + if err != nil { + return xerrors.Errorf("failed to setup beacon: %w", err) + } + n.Beacon = beacon + return nil +} + +func (n *Node) setupWallet(privKey crypto.PrivKey) error { + // TODO make persistent keystore + kstore := wallet.NewMemKeyStore() + pKeyBytes, err := privKey.Raw() + if err != nil { + return xerrors.Errorf("failed to get raw private key: %w", err) + } + keyInfo := types.KeyInfo{ + Type: types.KTEd25519, + PrivateKey: pKeyBytes, + } + + kstore.Put(wallet.KNamePrefix+n.Host.ID().String(), keyInfo) + w, err := wallet.NewWallet(kstore) + if err != nil { + return xerrors.Errorf("failed to setup wallet: %w", err) + } + n.Wallet = w return nil } @@ -202,11 +255,11 @@ func Start() error { func generatePrivateKey() (crypto.PrivKey, error) { r := rand.Reader // Creates a new RSA key pair for this host. - prvKey, _, err := crypto.GenerateKeyPairWithReader(crypto.RSA, 2048, r) + prvKey, _, err := crypto.GenerateKeyPairWithReader(crypto.Ed25519, 2048, r) if err != nil { return nil, err } return prvKey, nil } -// TODO generate MinerBase for the node +// TODO generate Miner for the node diff --git a/wallet/wallet.go b/wallet/wallet.go index d0e3bbb..7e0d78c 100644 --- a/wallet/wallet.go +++ b/wallet/wallet.go @@ -55,7 +55,7 @@ func (w *LocalWallet) WalletSign(ctx context.Context, addr peer.ID, msg []byte) return nil, err } if ki == nil { - return nil, xerrors.Errorf("signing using key '%s': %w", addr.String(), types.ErrKeyInfoNotFound) + return nil, xerrors.Errorf("failed to find private key of %w: %w", addr.String(), types.ErrKeyInfoNotFound) } return sigs.Sign(ActSigType(ki.Type), ki.PrivateKey, msg)