pull/1836/head
Rongjian Lan 5 years ago
parent 3b7b70cb1c
commit 77ff9d422d
  1. 2
      block/factory/factory.go
  2. 15
      cmd/staking/root.go
  3. 2
      consensus/consensus_v2.go
  4. 4
      core/blockchain.go
  5. 2
      core/state_processor.go
  6. 29
      core/types/block.go
  7. 11
      core/types/bodyfieldsetter.go
  8. 14
      core/types/bodyv0.go
  9. 14
      core/types/bodyv1.go
  10. 9
      core/types/bodyv2.go
  11. 4
      hmy/api_backend.go
  12. 2
      internal/hmyapi/backend.go
  13. 10
      internal/hmyapi/transactionpool.go
  14. 30
      node/node_handler.go
  15. 1
      node/node_newblock.go
  16. 16
      staking/types/transaction.go
  17. 22
      staking/types/validator.go

@ -30,7 +30,7 @@ func NewFactory(chainConfig *params.ChainConfig) Factory {
func (f *factory) NewHeader(epoch *big.Int) *block.Header {
var impl blockif.Header
switch {
case epoch.Cmp(f.chainConfig.StakingEpoch) >= 0:
case epoch.Cmp(f.chainConfig.StakingEpoch) < 0: // REVERT BEFORE COMMIT
impl = v3.NewHeader()
case epoch.Cmp(f.chainConfig.CrossLinkEpoch) >= 0:
impl = v2.NewHeader()

@ -11,6 +11,8 @@ import (
"path"
"strconv"
"github.com/harmony-one/harmony/common/denominations"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/rlp"
@ -75,9 +77,9 @@ func (s *staker) run(cmd *cobra.Command, args []string) error {
pub := shard.BlsPublicKey{}
pub.FromLibBLSPublicKey(p)
ra, _ := numeric.NewDecFromStr("27.27")
maxRate, _ := numeric.NewDecFromStr("150.99")
maxChangeRate, _ := numeric.NewDecFromStr("0.5")
ra, _ := numeric.NewDecFromStr("0.2")
maxRate, _ := numeric.NewDecFromStr("1")
maxChangeRate, _ := numeric.NewDecFromStr("0.05")
if cmdType == "create" {
return staking.DirectiveCreateValidator, staking.CreateValidator{
Description: &staking.Description{
@ -92,11 +94,11 @@ func (s *staker) run(cmd *cobra.Command, args []string) error {
MaxRate: maxRate,
MaxChangeRate: maxChangeRate,
},
MinSelfDelegation: big.NewInt(10),
MaxTotalDelegation: big.NewInt(3000),
MinSelfDelegation: big.NewInt(denominations.One),
MaxTotalDelegation: big.NewInt(0).Mul(big.NewInt(denominations.One), big.NewInt(1000)),
ValidatorAddress: common.Address(dAddr),
SlotPubKeys: []shard.BlsPublicKey{pub},
Amount: big.NewInt(100),
Amount: big.NewInt(denominations.One),
}
}
/*
@ -133,6 +135,7 @@ func (s *staker) run(cmd *cobra.Command, args []string) error {
if oops1 != nil {
return oops1
}
tx := new(staking.StakingTransaction)
if err := rlp.DecodeBytes(enc, tx); err != nil {
return err

@ -833,6 +833,8 @@ func (consensus *Consensus) finalizeCommits() {
Uint64("ViewId", block.Header().ViewID().Uint64()).
Str("blockHash", block.Hash().String()).
Int("index", consensus.Decider.IndexOf(consensus.PubKey)).
Int("numTxns", len(block.Transactions())).
Int("numStakingTxns", len(block.StakingTransactions())).
Msg("HOORAY!!!!!!! CONSENSUS REACHED!!!!!!!")
// Send signal to Node so the new block can be added and new round of consensus can be triggered
consensus.ReadySignal <- struct{}{}

@ -1171,7 +1171,7 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.
}
// Do bookkeeping for new staking txns
if bc.chainConfig.IsStaking(block.Epoch()) {
//if bc.chainConfig.IsStaking(block.Epoch()) {
for _, tx := range block.StakingTransactions() {
err = bc.UpdateStakingMetaData(tx)
// keep offchain database consistency with onchain we need revert
@ -1181,7 +1181,7 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.
return NonStatTy, err
}
}
}
//}
//// Cross-links
if len(header.CrossLinks()) > 0 {

@ -266,7 +266,9 @@ func ApplyIncomingReceipt(config *params.ChainConfig, db *state.DB, header *bloc
// requires a signer to derive the sender.
// put it here to avoid cyclic import
func StakingToMessage(tx *staking.StakingTransaction, blockNum *big.Int) (types.Message, error) {
utils.Logger().Info().Msgf("ApplyStakingMessage: aaaaaa:")
payload, err := tx.RLPEncodeStakeMsg()
utils.Logger().Info().Msgf("ApplyStakingMessage: aaaaaa:", err)
if err != nil {
return types.Message{}, err
}

@ -90,6 +90,10 @@ type BodyInterface interface {
// It returns nil if index is out of bounds.
TransactionAt(index int) *Transaction
// StakingTransactionAt returns the staking transaction at the given index in this block.
// It returns nil if index is out of bounds.
StakingTransactionAt(index int) *staking.StakingTransaction
// CXReceiptAt returns the CXReceipt given index (calculated from IncomingReceipts)
// It returns nil if index is out of bounds
CXReceiptAt(index int) *CXReceipt
@ -98,6 +102,10 @@ type BodyInterface interface {
// given list.
SetTransactions(newTransactions []*Transaction)
// SetStakingTransactions sets the list of staking transactions with a deep copy of the
// given list.
SetStakingTransactions(newStakingTransactions []*staking.StakingTransaction)
// Uncles returns a deep copy of the list of uncle headers of this block.
Uncles() []*block.Header
@ -190,11 +198,11 @@ func init() {
// Block represents an entire block in the Harmony blockchain.
type Block struct {
header *block.Header
uncles []*block.Header
transactions Transactions
stks staking.StakingTransactions
incomingReceipts CXReceiptsProofs
header *block.Header
uncles []*block.Header
transactions Transactions
stakingTransactions staking.StakingTransactions
incomingReceipts CXReceiptsProofs
// caches
hash atomic.Value
@ -301,8 +309,8 @@ func NewBlock(header *block.Header, txs []*Transaction, receipts []*Receipt, out
}
if len(stks) > 0 {
b.stks = make(staking.StakingTransactions, len(stks))
copy(b.stks, stks)
b.stakingTransactions = make(staking.StakingTransactions, len(stks))
copy(b.stakingTransactions, stks)
}
return b
@ -332,7 +340,7 @@ func (b *Block) DecodeRLP(s *rlp.Stream) error {
}
switch eb := eb.(type) {
case *extblockV2:
b.header, b.uncles, b.transactions, b.incomingReceipts, b.stks = eb.Header, eb.Uncles, eb.Txs, eb.IncomingReceipts, eb.Stks
b.header, b.uncles, b.transactions, b.incomingReceipts, b.stakingTransactions = eb.Header, eb.Uncles, eb.Txs, eb.IncomingReceipts, eb.Stks
case *extblockV1:
b.header, b.uncles, b.transactions, b.incomingReceipts = eb.Header, eb.Uncles, eb.Txs, eb.IncomingReceipts
case *extblock:
@ -349,7 +357,7 @@ func (b *Block) EncodeRLP(w io.Writer) error {
var eb interface{}
switch h := b.header.Header.(type) {
case *v3.Header:
eb = extblockV2{b.header, b.transactions, b.stks, b.uncles, b.incomingReceipts}
eb = extblockV2{b.header, b.transactions, b.stakingTransactions, b.uncles, b.incomingReceipts}
case *v2.Header, *v1.Header:
eb = extblockV1{b.header, b.transactions, b.uncles, b.incomingReceipts}
case *v0.Header:
@ -376,7 +384,7 @@ func (b *Block) Transactions() Transactions {
// StakingTransactions returns stakingTransactions.
func (b *Block) StakingTransactions() staking.StakingTransactions {
return b.stks
return b.stakingTransactions
}
// IncomingReceipts returns verified outgoing receipts
@ -454,6 +462,7 @@ func (b *Block) Body() *Body {
}
return body.With().
Transactions(b.transactions).
StakingTransactions(b.stakingTransactions).
Uncles(b.uncles).
IncomingReceipts(b.incomingReceipts).
Body()

@ -1,6 +1,9 @@
package types
import "github.com/harmony-one/harmony/block"
import (
"github.com/harmony-one/harmony/block"
"github.com/harmony-one/harmony/staking/types"
)
// BodyFieldSetter is a body field setter.
type BodyFieldSetter struct {
@ -13,6 +16,12 @@ func (bfs BodyFieldSetter) Transactions(newTransactions []*Transaction) BodyFiel
return bfs
}
// StakingTransactions sets the StakingTransactions field of the body.
func (bfs BodyFieldSetter) StakingTransactions(newStakingTransactions []*types.StakingTransaction) BodyFieldSetter {
bfs.b.SetStakingTransactions(newStakingTransactions)
return bfs
}
// Uncles sets the Uncles field of the body.
func (bfs BodyFieldSetter) Uncles(newUncles []*block.Header) BodyFieldSetter {
bfs.b.SetUncles(newUncles)

@ -40,6 +40,13 @@ func (b *BodyV0) TransactionAt(index int) *Transaction {
return b.f.Transactions[index].Copy()
}
// StakingTransactionAt returns the staking transaction at the given index in this block.
// It returns nil if index is out of bounds. (not supported by Body V0)
func (b *BodyV0) StakingTransactionAt(index int) *staking.StakingTransaction {
// not supported
return nil
}
// CXReceiptAt returns the CXReceipt at given index in this block
// It returns nil if index is out of bounds
// V0 will just return nil because we don't support CXReceipt
@ -57,6 +64,13 @@ func (b *BodyV0) SetTransactions(newTransactions []*Transaction) {
b.f.Transactions = txs
}
// SetStakingTransactions sets the list of staking transactions with a deep copy of the given
// list. (not supported by Body V0)
func (b *BodyV0) SetStakingTransactions(newTransactions []*staking.StakingTransaction) {
// not supported
return
}
// Uncles returns a deep copy of the list of uncle headers of this block.
func (b *BodyV0) Uncles() (uncles []*block.Header) {
for _, uncle := range b.f.Uncles {

@ -73,6 +73,20 @@ func (b *BodyV1) SetTransactions(newTransactions []*Transaction) {
b.f.Transactions = txs
}
// SetStakingTransactions sets the list of staking transactions with a deep copy of the given
// list. (not supported by Body V1)
func (b *BodyV1) SetStakingTransactions(newTransactions []*staking.StakingTransaction) {
// not supported
return
}
// StakingTransactionAt returns the staking transaction at the given index in this block.
// It returns nil if index is out of bounds. (not supported by Body V1)
func (b *BodyV1) StakingTransactionAt(index int) *staking.StakingTransaction {
// not supported
return nil
}
// Uncles returns a deep copy of the list of uncle headers of this block.
func (b *BodyV1) Uncles() (uncles []*block.Header) {
for _, uncle := range b.f.Uncles {

@ -51,6 +51,15 @@ func (b *BodyV2) TransactionAt(index int) *Transaction {
return b.f.Transactions[index].Copy()
}
// StakingTransactionAt returns the staking transaction at the given index in this block.
// It returns nil if index is out of bounds.
func (b *BodyV2) StakingTransactionAt(index int) *staking.StakingTransaction {
if index < 0 || index >= len(b.f.StakingTransactions) {
return nil
}
return b.f.StakingTransactions[index].Copy()
}
// CXReceiptAt returns the CXReceipt at given index in this block
// It returns nil if index is out of bounds
func (b *BodyV2) CXReceiptAt(index int) *CXReceipt {

@ -296,8 +296,8 @@ func (b *APIBackend) GetActiveValidatorAddresses() []common.Address {
return list
}
// GetValidatorCandidates returns the up to date validator candidates for next epoch
func (b *APIBackend) GetValidatorCandidates() []common.Address {
// GetAllValidatorAddresses returns the up to date validator candidates for next epoch
func (b *APIBackend) GetAllValidatorAddresses() []common.Address {
return b.hmy.BlockChain().ValidatorCandidates()
}

@ -74,7 +74,7 @@ type Backend interface {
IsLeader() bool
SendStakingTx(ctx context.Context, newStakingTx *staking.StakingTransaction) error
GetActiveValidatorAddresses() []common.Address
GetValidatorCandidates() []common.Address
GetAllValidatorAddresses() []common.Address
GetValidatorInformation(addr common.Address) *staking.Validator
GetDelegatorsInformation(addr common.Address) []*staking.Delegation
GetValidatorStakingWithDelegation(addr common.Address) *big.Int

@ -298,3 +298,13 @@ func (s *PublicTransactionPoolAPI) GetCXReceiptByHash(ctx context.Context, hash
}
return nil
}
// GetAllValidatorAddresses returns ...
func (s *PublicTransactionPoolAPI) GetAllValidatorAddresses() ([]common.Address, error) {
return s.b.GetAllValidatorAddresses(), nil
}
// GetActiveValidatorAddresses returns ...
func (s *PublicTransactionPoolAPI) GetActiveValidatorAddresses() ([]common.Address, error) {
return s.b.GetActiveValidatorAddresses(), nil
}

@ -400,23 +400,21 @@ func (node *Node) PostConsensusProcessing(newBlock *types.Block, commitSigAndBit
func (node *Node) AddNewBlock(newBlock *types.Block) error {
_, err := node.Blockchain().InsertChain([]*types.Block{newBlock}, true /* verifyHeaders */)
/*
// Debug only
addrs, err := node.Blockchain().ReadValidatorList()
utils.Logger().Debug().Msgf("validator list updated, err=%v, len(addrs)=%v", err, len(addrs))
for i, addr := range addrs {
val, err := node.Blockchain().ValidatorInformation(addr)
if err != nil {
utils.Logger().Debug().Msgf("ValidatorInformation Error %v: err %v", i, err)
}
utils.Logger().Debug().Msgf("ValidatorInformation %v: %v", i, val)
// Debug only
addrs, err := node.Blockchain().ReadValidatorList()
utils.Logger().Debug().Msgf("validator list updated, err=%v, len(addrs)=%v", err, len(addrs))
for i, addr := range addrs {
val, err := node.Blockchain().ValidatorInformation(addr)
if err != nil {
utils.Logger().Debug().Msgf("ValidatorInformation Error %v: err %v", i, err)
}
currAddrs := node.Blockchain().ActiveValidatorAddresses()
utils.Logger().Debug().Msgf("CurrentValidators : %v", currAddrs)
candidates := node.Blockchain().ValidatorCandidates()
utils.Logger().Debug().Msgf("CandidateValidators : %v", candidates)
// Finish debug
*/
utils.Logger().Debug().Msgf("ValidatorInformation %v: %v", i, val)
}
currAddrs, err := node.Blockchain().ReadActiveValidatorList()
utils.Logger().Debug().Msgf("CurrentValidators : %v", currAddrs)
candidates := node.Blockchain().ValidatorCandidates()
utils.Logger().Debug().Msgf("CandidateValidators : %v", candidates)
// Finish debug
if err != nil {
utils.Logger().Error().

@ -91,6 +91,7 @@ func (node *Node) proposeNewBlock() (*types.Block, error) {
for _, tx := range node.pendingStakingTransactions {
pendingStakingTransactions = append(pendingStakingTransactions, tx)
}
node.pendingStakingTransactions = make(map[common.Hash]*types2.StakingTransaction)
node.Worker.UpdateCurrent(coinbase)
if err := node.Worker.CommitTransactions(pending, pendingStakingTransactions, coinbase); err != nil {

@ -4,7 +4,6 @@ import (
"errors"
"io"
"math/big"
"reflect"
"sync/atomic"
"github.com/ethereum/go-ethereum/common"
@ -35,7 +34,20 @@ func (d *txdata) CopyFrom(d2 *txdata) {
d.AccountNonce = d2.AccountNonce
d.Price = new(big.Int).Set(d2.Price)
d.GasLimit = d2.GasLimit
d.StakeMsg = reflect.New(reflect.ValueOf(d2.StakeMsg).Elem().Type()).Interface()
//switch d.Directive { // TODO: make these deep copies.
//case DirectiveCreateValidator:
// d.StakeMsg = d2.StakeMsg.(CreateValidator)
//case DirectiveEditValidator:
// d.StakeMsg = d2.StakeMsg.(EditValidator)
//case DirectiveDelegate:
// d.StakeMsg = d2.StakeMsg.(Delegate)
//case DirectiveUndelegate:
// d.StakeMsg = d2.StakeMsg.(Undelegate)
//case DirectiveCollectRewards:
// d.StakeMsg = d2.StakeMsg.(CollectRewards)
//default:
// return
//}
d.V = new(big.Int).Set(d2.V)
d.R = new(big.Int).Set(d2.R)
d.S = new(big.Int).Set(d2.S)

@ -30,6 +30,8 @@ var (
errInvalidTotalDelegation = errors.New("total delegation can not be bigger than max_total_delegation")
errMinSelfDelegationTooSmall = errors.New("min_self_delegation has to be greater than 1 ONE")
errInvalidMaxTotalDelegation = errors.New("max_total_delegation can not be less than min_self_delegation")
errCommissionRateTooLarge = errors.New("commission rate and change rate can not be larger than max commission rate")
errInvalidComissionRate = errors.New("commission rate, change rate and max rate should be within 0-100%")
)
// ValidatorWrapper contains validator and its delegation information
@ -103,6 +105,26 @@ func (w *ValidatorWrapper) SanityCheck() error {
if totalDelegation.Cmp(w.Validator.MaxTotalDelegation) > 0 {
return errInvalidTotalDelegation
}
hundredPercent := numeric.NewDec(1)
zeroPercent := numeric.NewDec(0)
if w.Validator.Rate.LT(zeroPercent) || w.Validator.Rate.GT(hundredPercent) {
return errInvalidComissionRate
}
if w.Validator.MaxRate.LT(zeroPercent) || w.Validator.MaxRate.GT(hundredPercent) {
return errInvalidComissionRate
}
if w.Validator.MaxChangeRate.LT(zeroPercent) || w.Validator.MaxChangeRate.GT(hundredPercent) {
return errInvalidComissionRate
}
if w.Validator.Rate.GT(w.Validator.MaxRate) {
return errCommissionRateTooLarge
}
if w.Validator.MaxChangeRate.GT(w.Validator.MaxRate) {
return errCommissionRateTooLarge
}
return nil
}

Loading…
Cancel
Save