Use hard coded account for staking

pull/512/head
Rongjian Lan 6 years ago
parent b9fac736f0
commit eb0af9c05d
  1. 2
      cmd/harmony.go
  2. 10
      internal/utils/contract/constants.go
  3. 22
      internal/utils/utils.go
  4. 27
      node/contract.go
  5. 8
      node/node.go
  6. 12
      node/node_genesis.go
  7. 14
      node/node_handler.go
  8. 38
      node/staking.go
  9. 2
      test/deploy_newnode.sh

@ -143,7 +143,7 @@ func main() {
var clientPeer *p2p.Peer
var role string
stakingPriKey := utils.LoadStakingKeyFromFile(*stakingKeyFile)
stakingPriKey := node.LoadStakingKeyFromFile(*stakingKeyFile)
nodePriKey, _, err := utils.LoadKeyFromFile(*keyFile)
if err != nil {

@ -38,6 +38,16 @@ var GenesisBeaconAccountPublicKey = GenesisBeaconAccountPriKey.PublicKey
// DeployedContractAddress is the deployed contract address of the staking smart contract in beacon chain.
var DeployedContractAddress = crypto.CreateAddress(crypto.PubkeyToAddress(GenesisBeaconAccountPublicKey), uint64(0))
// StakingAccounts is the accounts only used for staking.
var StakingAccounts = [...]DeployAccount{
{Address: "0xE2bD4413172C98d5094B94de1A8AC6a383d68b84", Private: "e401343197a852f361e38ce6b46c99f1d6d1f80499864c6ae7effee42b46ab6b", Public: "0xE2bD4413172C98d5094B94de1A8AC6a383d68b84"},
{Address: "0x183418934Fd8A97c98E086151317B2df6259b8A8", Private: "a7d764439a7619f703c97ee2a2cf0be2cd62ad4c9deebd5423d6f28de417b907", Public: "0x183418934Fd8A97c98E086151317B2df6259b8A8"},
{Address: "0x9df0e70D4cb3E9beC0548D8Ac56F46596D1BcdB6", Private: "4e3f7c819a15249d2824834cd7ce20fe24d6eab8eb39ac63b78cb3713362cf78", Public: "0x9df0e70D4cb3E9beC0548D8Ac56F46596D1BcdB6"},
{Address: "0x64570B8D2f9028b850340b6710bB0027baC5EFa2", Private: "8565eded3f70b2f8608495fa7e301fefc36cbc03286c0f4e75ffde7e02b49791", Public: "0x64570B8D2f9028b850340b6710bB0027baC5EFa2"},
{Address: "0x7E653426a7E0c1D210A652bf0E74B15838059b80", Private: "23176da901759e231d7b2d8761f3448220fcfd0232ed0b9644689a6ad7d50990", Public: "0x7E653426a7E0c1D210A652bf0E74B15838059b80"},
{Address: "0xAe44500A96756112C69F88008388037F6C6dd723", Private: "a9b4c273ffa398a1b1c8eeab63c40cef2c2fb2fc1fc4de9ab73a61f12e4d990a", Public: "0xAe44500A96756112C69F88008388037F6C6dd723"},
}
// FakeAccounts is the accounts only used for development purpose.
var FakeAccounts = [...]DeployAccount{
{Address: "0xE2bD4413172C98d5094B94de1A8AC6a383d68b84", Private: "e401343197a852f361e38ce6b46c99f1d6d1f80499864c6ae7effee42b46ab6b", Public: "0xE2bD4413172C98d5094B94de1A8AC6a383d68b84"},

@ -2,7 +2,6 @@ package utils
import (
"bytes"
"crypto/ecdsa"
"encoding/binary"
"encoding/json"
"fmt"
@ -14,7 +13,6 @@ import (
"strconv"
"sync"
crypto "github.com/ethereum/go-ethereum/crypto"
"github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/p2p"
p2p_crypto "github.com/libp2p/go-libp2p-crypto"
@ -216,23 +214,3 @@ func LoadKeyFromFile(keyfile string) (key p2p_crypto.PrivKey, pk p2p_crypto.PubK
key, pk, err = LoadPrivateKey(keyStruct.Key)
return key, pk, err
}
// LoadStakingKeyFromFile load staking private key from keyfile
// If the private key is not loadable or no file, it will generate
// a new random private key
func LoadStakingKeyFromFile(keyfile string) *ecdsa.PrivateKey {
key, err := crypto.LoadECDSA(keyfile)
if err != nil {
GetLogInstance().Error("no key file. Let's create a staking private key")
key, err = crypto.GenerateKey()
if err != nil {
GetLogInstance().Error("Unable to generate the private key")
os.Exit(1)
}
if err = crypto.SaveECDSA(keyfile, key); err != nil {
GetLogInstance().Error("Unable to save the private key", "error", err)
os.Exit(1)
}
}
return key
}

@ -96,7 +96,7 @@ func (node *Node) getDeployedStakingContract() common.Address {
// AddFaucetContractToPendingTransactions adds the faucet contract the genesis block.
func (node *Node) AddFaucetContractToPendingTransactions() {
// Add a contract deployment transactionv
priKey := node.ContractKeys[0]
priKey := node.ContractDeployerKey
dataEnc := common.FromHex(FaucetContractBinary)
// Unsigned transaction to avoid the case of transaction address.
@ -112,28 +112,37 @@ func (node *Node) AddFaucetContractToPendingTransactions() {
// CallFaucetContract invokes the faucet contract to give the walletAddress initial money
func (node *Node) CallFaucetContract(address common.Address) common.Hash {
return node.callGetFreeTokenWithTransaction(address)
return node.callGetFreeToken(address)
}
func (node *Node) callGetFreeTokenWithTransaction(address common.Address) common.Hash {
func (node *Node) callGetFreeToken(address common.Address) common.Hash {
state, err := node.blockchain.State()
if err != nil {
log.Error("Failed to get chain state", "Error", err)
}
nonce := state.GetNonce(crypto.PubkeyToAddress(node.ContractKeys[0].PublicKey))
nonce := state.GetNonce(crypto.PubkeyToAddress(node.ContractDeployerKey.PublicKey))
return node.callGetFreeTokenWithNonce(address, nonce)
}
func (node *Node) callGetFreeTokenWithNonce(address common.Address, nonce uint64) common.Hash {
contractData := FaucetFreeMoneyMethodCall + hex.EncodeToString(address.Bytes())
dataEnc := common.FromHex(contractData)
utils.GetLogInstance().Info("Sending Free Token to ", "Address", address.Hex())
tx, _ := types.SignTx(types.NewTransaction(nonce, node.ContractAddresses[0], node.Consensus.ShardID, big.NewInt(0), params.TxGasContractCreation*10, nil, dataEnc), types.HomesteadSigner{}, node.ContractKeys[0])
tx, _ := types.SignTx(types.NewTransaction(nonce, node.ContractAddresses[0], node.Consensus.ShardID, big.NewInt(0), params.TxGasContractCreation*10, nil, dataEnc), types.HomesteadSigner{}, node.ContractDeployerKey)
node.addPendingTransactions(types.Transactions{tx})
return tx.Hash()
}
// DepositToFakeAccounts invokes the faucet contract to give the fake accounts initial money
func (node *Node) DepositToFakeAccounts() {
for _, deployAccount := range contract.FakeAccounts {
// DepositToStakingAccounts invokes the faucet contract to give the staking accounts initial money
func (node *Node) DepositToStakingAccounts() {
state, err := node.blockchain.State()
if err != nil {
log.Error("Failed to get chain state", "Error", err)
}
nonce := state.GetNonce(crypto.PubkeyToAddress(node.ContractDeployerKey.PublicKey)) + 1 // + 1 because deployer key is already used for faucet contract deployment
for i, deployAccount := range contract.StakingAccounts {
address := common.HexToAddress(deployAccount.Address)
node.callGetFreeTokenWithTransaction(address)
node.callGetFreeTokenWithNonce(address, nonce+uint64(i))
}
}

@ -177,9 +177,9 @@ type Node struct {
Address common.Address
// For test only
TestBankKeys []*ecdsa.PrivateKey
ContractKeys []*ecdsa.PrivateKey
ContractAddresses []common.Address
TestBankKeys []*ecdsa.PrivateKey
ContractDeployerKey *ecdsa.PrivateKey
ContractAddresses []common.Address
// Group Message Receiver
groupReceiver p2p.GroupReceiver
@ -284,7 +284,7 @@ func New(host p2p.Host, consensusObj *consensus.Consensus, db ethdb.Database) *N
node.AddFaucetContractToPendingTransactions()
node.CurrentStakes = make(map[common.Address]int64)
node.AddStakingContractToPendingTransactions() //This will save the latest information about staked nodes in current staked
// node.DepositToFakeAccounts()
node.DepositToStakingAccounts()
}
if consensusObj != nil && consensusObj.IsLeader {

@ -24,12 +24,12 @@ const (
func (node *Node) GenesisBlockSetup(db ethdb.Database) (*core.BlockChain, error) {
// Initialize genesis block and blockchain
genesisAlloc := node.CreateGenesisAllocWithTestingAddresses(FakeAddressNumber)
contractKey, _ := ecdsa.GenerateKey(crypto.S256(), strings.NewReader("Test contract key string stream that is fixed so that generated test key are deterministic every time"))
contractAddress := crypto.PubkeyToAddress(contractKey.PublicKey)
contractFunds := big.NewInt(TotalInitFund)
contractFunds = contractFunds.Mul(contractFunds, big.NewInt(params.Ether))
genesisAlloc[contractAddress] = core.GenesisAccount{Balance: contractFunds}
node.ContractKeys = append(node.ContractKeys, contractKey)
contractDeployerKey, _ := ecdsa.GenerateKey(crypto.S256(), strings.NewReader("Test contract key string stream that is fixed so that generated test key are deterministic every time"))
contractDeployerAddress := crypto.PubkeyToAddress(contractDeployerKey.PublicKey)
contractDeployerFunds := big.NewInt(TotalInitFund)
contractDeployerFunds = contractDeployerFunds.Mul(contractDeployerFunds, big.NewInt(params.Ether))
genesisAlloc[contractDeployerAddress] = core.GenesisAccount{Balance: contractDeployerFunds}
node.ContractDeployerKey = contractDeployerKey
chainConfig := params.TestChainConfig
chainConfig.ChainID = big.NewInt(int64(node.Consensus.ShardID)) // Use ChainID as piggybacked ShardID

@ -208,20 +208,8 @@ func (node *Node) processStakingMessage(msgPayload []byte) {
stakingRequest := msg.GetStaking()
txs := types.Transactions{}
if err = rlp.DecodeBytes(stakingRequest.Transaction, &txs); err == nil {
for _, tx := range txs {
signerType := types.HomesteadSigner{}
sender, err := types.Sender(signerType, tx)
if err != nil {
utils.GetLogInstance().Error("Failed to get the staker address", "error", err)
} else {
node.CallFaucetContract(sender)
}
}
utils.GetLogInstance().Info("Successfully added staking transaction to pending list.")
go func() {
time.Sleep(5 * time.Second)
node.addPendingTransactions(txs)
}()
node.addPendingTransactions(txs)
} else {
utils.GetLogInstance().Error("Failed to unmarshal staking transaction list", "error", err)
}

@ -1,7 +1,12 @@
package node
import (
"crypto/ecdsa"
"math/big"
"os"
"github.com/ethereum/go-ethereum/crypto"
"github.com/harmony-one/harmony/internal/utils/contract"
"github.com/harmony-one/harmony/internal/utils"
@ -94,3 +99,36 @@ func decodeFuncSign(data []byte) string {
funcSign := hexutil.Encode(data[:funcSingatureBytes]) //The function signature is first 4 bytes of data in ethereum
return funcSign
}
// LoadStakingKeyFromFile load staking private key from keyfile
// If the private key is not loadable or no file, it will generate
// a new random private key
// Currently for deploy_newnode.sh, we hard-coded the first fake account as staking account and
// it is minted in genesis block. See genesis_node.go
func LoadStakingKeyFromFile(keyfile string) *ecdsa.PrivateKey {
// contract.FakeAccounts[0] gets minted tokens in genesis block of beacon chain.
key, err := crypto.HexToECDSA(contract.FakeAccounts[0].Private)
if err != nil {
utils.GetLogInstance().Error("Unable to get staking key")
os.Exit(1)
}
if err := crypto.SaveECDSA(keyfile, key); err != nil {
utils.GetLogInstance().Error("Unable to save the private key", "error", err)
os.Exit(1)
}
// TODO(minhdoan): Enable this back.
// key, err := crypto.LoadECDSA(keyfile)
// if err != nil {
// GetLogInstance().Error("no key file. Let's create a staking private key")
// key, err = crypto.GenerateKey()
// if err != nil {
// GetLogInstance().Error("Unable to generate the private key")
// os.Exit(1)
// }
// if err = crypto.SaveECDSA(keyfile, key); err != nil {
// GetLogInstance().Error("Unable to save the private key", "error", err)
// os.Exit(1)
// }
// }
return key
}

@ -116,7 +116,7 @@ LOG_FILE=$log_folder/r.log
HMY_OPT=
# Change to the beacon chain output from deploy.sh
HMY_OPT2=
HMY_OPT2="-bootnodes /ip4/127.0.0.1/tcp/19876/p2p/QmWGSpah5QiBB1aKHKoJpM4VqJxcefc8kVxEbzXD59M8kP"
HMY_OPT3=
($DRYRUN $ROOT/bin/harmony -ip 127.0.0.1 -port 9100 -log_folder $log_folder -is_newnode $DB -min_peers $MIN $HMY_OPT $HMY_OPT2 $HMY_OPT3 -key /tmp/127.0.0.1-9100.key 2>&1 | tee -a $LOG_FILE ) &

Loading…
Cancel
Save