|
|
@ -15,6 +15,7 @@ import ( |
|
|
|
"github.com/harmony-one/harmony/drand" |
|
|
|
"github.com/harmony-one/harmony/drand" |
|
|
|
|
|
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/common" |
|
|
|
"github.com/ethereum/go-ethereum/common" |
|
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/common/hexutil" |
|
|
|
"github.com/ethereum/go-ethereum/crypto" |
|
|
|
"github.com/ethereum/go-ethereum/crypto" |
|
|
|
"github.com/ethereum/go-ethereum/ethdb" |
|
|
|
"github.com/ethereum/go-ethereum/ethdb" |
|
|
|
"github.com/ethereum/go-ethereum/params" |
|
|
|
"github.com/ethereum/go-ethereum/params" |
|
|
@ -31,6 +32,7 @@ import ( |
|
|
|
"github.com/harmony-one/harmony/api/service/explorer" |
|
|
|
"github.com/harmony-one/harmony/api/service/explorer" |
|
|
|
"github.com/harmony-one/harmony/api/service/networkinfo" |
|
|
|
"github.com/harmony-one/harmony/api/service/networkinfo" |
|
|
|
randomness_service "github.com/harmony-one/harmony/api/service/randomness" |
|
|
|
randomness_service "github.com/harmony-one/harmony/api/service/randomness" |
|
|
|
|
|
|
|
|
|
|
|
"github.com/harmony-one/harmony/api/service/staking" |
|
|
|
"github.com/harmony-one/harmony/api/service/staking" |
|
|
|
"github.com/harmony-one/harmony/api/service/syncing" |
|
|
|
"github.com/harmony-one/harmony/api/service/syncing" |
|
|
|
"github.com/harmony-one/harmony/api/service/syncing/downloader" |
|
|
|
"github.com/harmony-one/harmony/api/service/syncing/downloader" |
|
|
@ -116,6 +118,17 @@ type syncConfig struct { |
|
|
|
client *downloader.Client |
|
|
|
client *downloader.Client |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//constants related to staking
|
|
|
|
|
|
|
|
//The first four bytes of the call data for a function call specifies the function to be called.
|
|
|
|
|
|
|
|
//It is the first (left, high-order in big-endian) four bytes of the Keccak-256 (SHA-3)
|
|
|
|
|
|
|
|
//Refer: https://solidity.readthedocs.io/en/develop/abi-spec.html
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const ( |
|
|
|
|
|
|
|
depositFuncSignature = "0xd0e30db0" |
|
|
|
|
|
|
|
withdrawFuncSignature = "0x2e1a7d4d" |
|
|
|
|
|
|
|
funcSingatureBytes = 4 |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
// Node represents a protocol-participating node in the network
|
|
|
|
// Node represents a protocol-participating node in the network
|
|
|
|
type Node struct { |
|
|
|
type Node struct { |
|
|
|
Consensus *bft.Consensus // Consensus object containing all Consensus related data (e.g. committee members, signatures, commits)
|
|
|
|
Consensus *bft.Consensus // Consensus object containing all Consensus related data (e.g. committee members, signatures, commits)
|
|
|
@ -272,6 +285,7 @@ func New(host p2p.Host, consensus *bft.Consensus, db ethdb.Database) *Node { |
|
|
|
node.blockchain = chain |
|
|
|
node.blockchain = chain |
|
|
|
node.BlockChannel = make(chan *types.Block) |
|
|
|
node.BlockChannel = make(chan *types.Block) |
|
|
|
node.ConfirmedBlockChannel = make(chan *types.Block) |
|
|
|
node.ConfirmedBlockChannel = make(chan *types.Block) |
|
|
|
|
|
|
|
|
|
|
|
node.TxPool = core.NewTxPool(core.DefaultTxPoolConfig, params.TestChainConfig, chain) |
|
|
|
node.TxPool = core.NewTxPool(core.DefaultTxPoolConfig, params.TestChainConfig, chain) |
|
|
|
node.Worker = worker.New(params.TestChainConfig, chain, node.Consensus, pki.GetAddressFromPublicKey(node.SelfPeer.PubKey), node.Consensus.ShardID) |
|
|
|
node.Worker = worker.New(params.TestChainConfig, chain, node.Consensus, pki.GetAddressFromPublicKey(node.SelfPeer.PubKey), node.Consensus.ShardID) |
|
|
|
node.AddFaucetContractToPendingTransactions() |
|
|
|
node.AddFaucetContractToPendingTransactions() |
|
|
@ -632,27 +646,27 @@ func (node *Node) UpdateStakingList(block *types.Block) error { |
|
|
|
txns := block.Transactions() |
|
|
|
txns := block.Transactions() |
|
|
|
for i := range txns { |
|
|
|
for i := range txns { |
|
|
|
txn := txns[i] |
|
|
|
txn := txns[i] |
|
|
|
value := txn.Value().Int64() |
|
|
|
|
|
|
|
currentSender, _ := types.Sender(signerType, txn) |
|
|
|
|
|
|
|
_, isPresent := node.CurrentStakes[currentSender] |
|
|
|
|
|
|
|
toAddress := txn.To() |
|
|
|
toAddress := txn.To() |
|
|
|
if *toAddress != node.StakingContractAddress { //Not a address aimed at the staking contract.
|
|
|
|
if *toAddress != node.StakingContractAddress { //Not a address aimed at the staking contract.
|
|
|
|
continue |
|
|
|
continue |
|
|
|
} |
|
|
|
} |
|
|
|
//This should be based on a switch case on function signature.
|
|
|
|
currentSender, _ := types.Sender(signerType, txn) |
|
|
|
//TODO (ak) https://github.com/harmony-one/harmony/issues/430
|
|
|
|
_, isPresent := node.CurrentStakes[currentSender] |
|
|
|
if value > int64(0) { //If value >0 means its a staking deposit transaction
|
|
|
|
data := txn.Data() |
|
|
|
|
|
|
|
switch funcSignature := decodeFuncSign(data); funcSignature { |
|
|
|
|
|
|
|
case depositFuncSignature: //deposit, currently: 0xd0e30db0
|
|
|
|
|
|
|
|
amount := txn.Value() |
|
|
|
|
|
|
|
value := amount.Int64() |
|
|
|
if isPresent { |
|
|
|
if isPresent { |
|
|
|
//This means this node has increaserd its stake
|
|
|
|
//This means the node has increased its stake.
|
|
|
|
node.CurrentStakes[currentSender] += value |
|
|
|
node.CurrentStakes[currentSender] += value |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
|
|
|
|
//This means its a new node that is staking the first time.
|
|
|
|
node.CurrentStakes[currentSender] = value |
|
|
|
node.CurrentStakes[currentSender] = value |
|
|
|
} |
|
|
|
} |
|
|
|
} else { //This means node has withdrawn stake.
|
|
|
|
case withdrawFuncSignature: //withdaw, currently: 0x2e1a7d4d
|
|
|
|
getData := txn.Data() |
|
|
|
value := decodeStakeCall(data) |
|
|
|
value := decodeStakeCall(getData) //Value being withdrawn
|
|
|
|
|
|
|
|
if isPresent { |
|
|
|
if isPresent { |
|
|
|
//This means this node has increaserd its stake
|
|
|
|
|
|
|
|
if node.CurrentStakes[currentSender] > value { |
|
|
|
if node.CurrentStakes[currentSender] > value { |
|
|
|
node.CurrentStakes[currentSender] -= value |
|
|
|
node.CurrentStakes[currentSender] -= value |
|
|
|
} else if node.CurrentStakes[currentSender] == value { |
|
|
|
} else if node.CurrentStakes[currentSender] == value { |
|
|
@ -661,18 +675,33 @@ func (node *Node) UpdateStakingList(block *types.Block) error { |
|
|
|
continue //Overdraft protection.
|
|
|
|
continue //Overdraft protection.
|
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
node.CurrentStakes[currentSender] = value |
|
|
|
continue //no-op: a node that is not staked cannot withdraw stake.
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
continue //no-op if its not deposit or withdaw
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return nil |
|
|
|
return nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//The first four bytes of the call data for a function call specifies the function to be called.
|
|
|
|
|
|
|
|
//It is the first (left, high-order in big-endian) four bytes of the Keccak-256 (SHA-3)
|
|
|
|
|
|
|
|
//Refer: https://solidity.readthedocs.io/en/develop/abi-spec.html
|
|
|
|
func decodeStakeCall(getData []byte) int64 { |
|
|
|
func decodeStakeCall(getData []byte) int64 { |
|
|
|
value := new(big.Int) |
|
|
|
value := new(big.Int) |
|
|
|
value.SetBytes(getData[4:]) //Escape the method call.
|
|
|
|
value.SetBytes(getData[funcSingatureBytes:]) //Escape the method call.
|
|
|
|
return value.Int64() |
|
|
|
return value.Int64() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//The first four bytes of the call data for a function call specifies the function to be called.
|
|
|
|
|
|
|
|
//It is the first (left, high-order in big-endian) four bytes of the Keccak-256 (SHA-3)
|
|
|
|
|
|
|
|
//Refer: https://solidity.readthedocs.io/en/develop/abi-spec.html
|
|
|
|
|
|
|
|
//gets the function signature from data.
|
|
|
|
|
|
|
|
func decodeFuncSign(data []byte) string { |
|
|
|
|
|
|
|
funcSign := hexutil.Encode(data[:funcSingatureBytes]) //The function signature is first 4 bytes of data in ethereum
|
|
|
|
|
|
|
|
return funcSign |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (node *Node) setupForShardLeader() { |
|
|
|
func (node *Node) setupForShardLeader() { |
|
|
|
// Register explorer service.
|
|
|
|
// Register explorer service.
|
|
|
|
node.serviceManager.RegisterService(service_manager.SupportExplorer, explorer.New(&node.SelfPeer)) |
|
|
|
node.serviceManager.RegisterService(service_manager.SupportExplorer, explorer.New(&node.SelfPeer)) |
|
|
|