Merge pull request #437 from harmony-one/fixNewbinary

Update Binary and Staking Calls based on new staking contract
pull/450/head
alajko 6 years ago committed by GitHub
commit 292fc38d49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 15
      node/contract.go
  2. 55
      node/node.go
  3. 19
      node/node_test.go

File diff suppressed because one or more lines are too long

@ -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))

@ -243,17 +243,20 @@ func TestUpdateStakingWithdrawal(t *testing.T) {
node.StakingContractAddress = DepositContractAddress node.StakingContractAddress = DepositContractAddress
node.AccountKey, _ = crypto.GenerateKey() node.AccountKey, _ = crypto.GenerateKey()
Address := crypto.PubkeyToAddress(node.AccountKey.PublicKey) Address := crypto.PubkeyToAddress(node.AccountKey.PublicKey)
node.CurrentStakes[Address] = int64(1010) initialStake := int64(1010)
node.CurrentStakes[Address] = initialStake //initial stake
withdrawFnSignature := []byte("withdraw(uint)") withdrawFnSignature := []byte("withdraw(uint256)")
hash := sha3.NewLegacyKeccak256() hash := sha3.NewLegacyKeccak256()
hash.Write(withdrawFnSignature) hash.Write(withdrawFnSignature)
methodID := hash.Sum(nil)[:4] methodID := hash.Sum(nil)[:4]
stake := "1000" amount := "10"
amount := new(big.Int) stakeToWithdraw := new(big.Int)
amount.SetString(stake, 10) stakeToWithdraw.SetString(amount, 10)
paddedAmount := common.LeftPadBytes(amount.Bytes(), 32) paddedAmount := common.LeftPadBytes(stakeToWithdraw.Bytes(), 32)
remainingStakeShouldBe := initialStake - stakeToWithdraw.Int64()
var dataEnc []byte var dataEnc []byte
dataEnc = append(dataEnc, methodID...) dataEnc = append(dataEnc, methodID...)
@ -265,11 +268,11 @@ func TestUpdateStakingWithdrawal(t *testing.T) {
header := &types.Header{Extra: []byte("hello")} header := &types.Header{Extra: []byte("hello")}
block := types.NewBlock(header, txs, nil) block := types.NewBlock(header, txs, nil)
node.UpdateStakingList(block) node.UpdateStakingList(block)
value, ok := node.CurrentStakes[Address] currentStake, ok := node.CurrentStakes[Address]
if !ok { if !ok {
t.Error("The correct address was not present") t.Error("The correct address was not present")
} }
if value != 10 { if currentStake != remainingStakeShouldBe {
t.Error("The correct stake value was not subtracted") t.Error("The correct stake value was not subtracted")
} }

Loading…
Cancel
Save