Merge pull request #3102 from LeoHChen/merge_to_to_master_0525

Merge t3 to master 0525
pull/3085/head
Leo Chen 5 years ago committed by GitHub
commit 607c71a5f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      internal/chain/engine.go
  2. 112
      internal/params/config.go
  3. 6
      node/node_handler.go
  4. 8
      staking/types/delegation.go
  5. 24
      staking/types/delegation_test.go

@ -335,10 +335,14 @@ func payoutUndelegations(
"[Finalize] failed to get validator from state to finalize", "[Finalize] failed to get validator from state to finalize",
) )
} }
lockPeriod := staking.LockPeriodInEpoch
if chain.Config().IsQuickUnlock(header.Epoch()) {
lockPeriod = staking.LockPeriodInEpochV2
}
for i := range wrapper.Delegations { for i := range wrapper.Delegations {
delegation := &wrapper.Delegations[i] delegation := &wrapper.Delegations[i]
totalWithdraw := delegation.RemoveUnlockedUndelegations( totalWithdraw := delegation.RemoveUnlockedUndelegations(
header.Epoch(), wrapper.LastEpochInCommittee, header.Epoch(), wrapper.LastEpochInCommittee, lockPeriod,
) )
state.AddBalance(delegation.DelegatorAddress, totalWithdraw) state.AddBalance(delegation.DelegatorAddress, totalWithdraw)
} }

@ -25,77 +25,83 @@ var EpochTBD = big.NewInt(10000000)
var ( var (
// MainnetChainConfig is the chain parameters to run a node on the main network. // MainnetChainConfig is the chain parameters to run a node on the main network.
MainnetChainConfig = &ChainConfig{ MainnetChainConfig = &ChainConfig{
ChainID: MainnetChainID, ChainID: MainnetChainID,
CrossTxEpoch: big.NewInt(28), CrossTxEpoch: big.NewInt(28),
CrossLinkEpoch: big.NewInt(186), CrossLinkEpoch: big.NewInt(186),
StakingEpoch: big.NewInt(186), StakingEpoch: big.NewInt(186),
PreStakingEpoch: big.NewInt(185), PreStakingEpoch: big.NewInt(185),
EIP155Epoch: big.NewInt(28), QuickUnlockEpoch: big.NewInt(191),
S3Epoch: big.NewInt(28), EIP155Epoch: big.NewInt(28),
ReceiptLogEpoch: big.NewInt(101), S3Epoch: big.NewInt(28),
ReceiptLogEpoch: big.NewInt(101),
} }
// TestnetChainConfig contains the chain parameters to run a node on the harmony test network. // TestnetChainConfig contains the chain parameters to run a node on the harmony test network.
TestnetChainConfig = &ChainConfig{ TestnetChainConfig = &ChainConfig{
ChainID: TestnetChainID, ChainID: TestnetChainID,
CrossTxEpoch: big.NewInt(0), CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(2), CrossLinkEpoch: big.NewInt(2),
StakingEpoch: big.NewInt(2), StakingEpoch: big.NewInt(2),
PreStakingEpoch: big.NewInt(1), PreStakingEpoch: big.NewInt(1),
EIP155Epoch: big.NewInt(0), QuickUnlockEpoch: big.NewInt(0),
S3Epoch: big.NewInt(0), EIP155Epoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0), S3Epoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0),
} }
// PangaeaChainConfig contains the chain parameters for the Pangaea network. // PangaeaChainConfig contains the chain parameters for the Pangaea network.
// All features except for CrossLink are enabled at launch. // All features except for CrossLink are enabled at launch.
PangaeaChainConfig = &ChainConfig{ PangaeaChainConfig = &ChainConfig{
ChainID: PangaeaChainID, ChainID: PangaeaChainID,
CrossTxEpoch: big.NewInt(0), CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(2), CrossLinkEpoch: big.NewInt(2),
StakingEpoch: big.NewInt(2), StakingEpoch: big.NewInt(2),
PreStakingEpoch: big.NewInt(1), PreStakingEpoch: big.NewInt(1),
EIP155Epoch: big.NewInt(0), QuickUnlockEpoch: big.NewInt(0),
S3Epoch: big.NewInt(0), EIP155Epoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0), S3Epoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0),
} }
// PartnerChainConfig contains the chain parameters for the Partner network. // PartnerChainConfig contains the chain parameters for the Partner network.
// All features except for CrossLink are enabled at launch. // All features except for CrossLink are enabled at launch.
PartnerChainConfig = &ChainConfig{ PartnerChainConfig = &ChainConfig{
ChainID: PartnerChainID, ChainID: PartnerChainID,
CrossTxEpoch: big.NewInt(0), CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(2), CrossLinkEpoch: big.NewInt(2),
StakingEpoch: big.NewInt(2), StakingEpoch: big.NewInt(2),
PreStakingEpoch: big.NewInt(1), PreStakingEpoch: big.NewInt(1),
EIP155Epoch: big.NewInt(0), QuickUnlockEpoch: big.NewInt(0),
S3Epoch: big.NewInt(0), EIP155Epoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0), S3Epoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0),
} }
// StressnetChainConfig contains the chain parameters for the Stress test network. // StressnetChainConfig contains the chain parameters for the Stress test network.
// All features except for CrossLink are enabled at launch. // All features except for CrossLink are enabled at launch.
StressnetChainConfig = &ChainConfig{ StressnetChainConfig = &ChainConfig{
ChainID: StressnetChainID, ChainID: StressnetChainID,
CrossTxEpoch: big.NewInt(0), CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(2), CrossLinkEpoch: big.NewInt(2),
StakingEpoch: big.NewInt(2), StakingEpoch: big.NewInt(2),
PreStakingEpoch: big.NewInt(1), PreStakingEpoch: big.NewInt(1),
EIP155Epoch: big.NewInt(0), QuickUnlockEpoch: big.NewInt(0),
S3Epoch: big.NewInt(0), EIP155Epoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0), S3Epoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0),
} }
// LocalnetChainConfig contains the chain parameters to run for local development. // LocalnetChainConfig contains the chain parameters to run for local development.
LocalnetChainConfig = &ChainConfig{ LocalnetChainConfig = &ChainConfig{
ChainID: TestnetChainID, ChainID: TestnetChainID,
CrossTxEpoch: big.NewInt(0), CrossTxEpoch: big.NewInt(0),
CrossLinkEpoch: big.NewInt(2), CrossLinkEpoch: big.NewInt(2),
StakingEpoch: big.NewInt(2), StakingEpoch: big.NewInt(2),
PreStakingEpoch: big.NewInt(0), PreStakingEpoch: big.NewInt(0),
EIP155Epoch: big.NewInt(0), QuickUnlockEpoch: big.NewInt(0),
S3Epoch: big.NewInt(0), EIP155Epoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0), S3Epoch: big.NewInt(0),
ReceiptLogEpoch: big.NewInt(0),
} }
// AllProtocolChanges ... // AllProtocolChanges ...
@ -107,6 +113,7 @@ var (
big.NewInt(0), // CrossLinkEpoch big.NewInt(0), // CrossLinkEpoch
big.NewInt(0), // StakingEpoch big.NewInt(0), // StakingEpoch
big.NewInt(0), // PreStakingEpoch big.NewInt(0), // PreStakingEpoch
big.NewInt(0), // QuickUnlockEpoch
big.NewInt(0), // EIP155Epoch big.NewInt(0), // EIP155Epoch
big.NewInt(0), // S3Epoch big.NewInt(0), // S3Epoch
big.NewInt(0), // ReceiptLogEpoch big.NewInt(0), // ReceiptLogEpoch
@ -121,6 +128,7 @@ var (
big.NewInt(0), // CrossLinkEpoch big.NewInt(0), // CrossLinkEpoch
big.NewInt(0), // StakingEpoch big.NewInt(0), // StakingEpoch
big.NewInt(0), // PreStakingEpoch big.NewInt(0), // PreStakingEpoch
big.NewInt(0), // QuickUnlockEpoch
big.NewInt(0), // EIP155Epoch big.NewInt(0), // EIP155Epoch
big.NewInt(0), // S3Epoch big.NewInt(0), // S3Epoch
big.NewInt(0), // ReceiptLogEpoch big.NewInt(0), // ReceiptLogEpoch
@ -165,6 +173,9 @@ type ChainConfig struct {
// PreStakingEpoch is the epoch we allow staking transactions // PreStakingEpoch is the epoch we allow staking transactions
PreStakingEpoch *big.Int `json:"prestaking-epoch,omitempty"` PreStakingEpoch *big.Int `json:"prestaking-epoch,omitempty"`
// QuickUnlockEpoch is the epoch when undelegation will be unlocked at the current epoch
QuickUnlockEpoch *big.Int `json:"quick-unlock-epoch,omitempty"`
// EIP155 hard fork epoch (include EIP158 too) // EIP155 hard fork epoch (include EIP158 too)
EIP155Epoch *big.Int `json:"eip155-epoch,omitempty"` EIP155Epoch *big.Int `json:"eip155-epoch,omitempty"`
@ -222,6 +233,11 @@ func (c *ChainConfig) IsPreStaking(epoch *big.Int) bool {
return isForked(c.PreStakingEpoch, epoch) return isForked(c.PreStakingEpoch, epoch)
} }
// IsQuickUnlock determines whether it's the epoch when the undelegation should be unlocked at end of current epoch
func (c *ChainConfig) IsQuickUnlock(epoch *big.Int) bool {
return isForked(c.QuickUnlockEpoch, epoch)
}
// IsCrossLink returns whether epoch is either equal to the CrossLink fork epoch or greater. // IsCrossLink returns whether epoch is either equal to the CrossLink fork epoch or greater.
func (c *ChainConfig) IsCrossLink(epoch *big.Int) bool { func (c *ChainConfig) IsCrossLink(epoch *big.Int) bool {
return isForked(c.CrossLinkEpoch, epoch) return isForked(c.CrossLinkEpoch, epoch)

@ -281,10 +281,8 @@ func (node *Node) BroadcastCrossLink() {
batchSize := crossLinkBatchSize batchSize := crossLinkBatchSize
diff := curBlock.Number().Uint64() - latestBlockNum diff := curBlock.Number().Uint64() - latestBlockNum
if diff > 100 { // Increase batch size by 1 for every 100 blocks beyond
// Increase batch size by 1 for every 100 blocks beyond batchSize += int(diff) / 100
batchSize += int(diff-100) / 100
}
// Cap at a sane size to avoid overload network // Cap at a sane size to avoid overload network
if batchSize > crossLinkBatchSize*2 { if batchSize > crossLinkBatchSize*2 {

@ -19,6 +19,8 @@ var (
const ( const (
// LockPeriodInEpoch is the number of epochs a undelegated token needs to be before it's released to the delegator's balance // LockPeriodInEpoch is the number of epochs a undelegated token needs to be before it's released to the delegator's balance
LockPeriodInEpoch = 7 LockPeriodInEpoch = 7
// LockPeriodInEpochV2 there is no extended locking time besides the current epoch time.
LockPeriodInEpochV2 = 0
) )
// Delegation represents the bond with tokens held by an account. It is // Delegation represents the bond with tokens held by an account. It is
@ -176,13 +178,13 @@ func (d *Delegation) DeleteEntry(epoch *big.Int) {
// RemoveUnlockedUndelegations removes all fully unlocked // RemoveUnlockedUndelegations removes all fully unlocked
// undelegations and returns the total sum // undelegations and returns the total sum
func (d *Delegation) RemoveUnlockedUndelegations( func (d *Delegation) RemoveUnlockedUndelegations(
curEpoch, lastEpochInCommittee *big.Int, curEpoch, lastEpochInCommittee *big.Int, lockPeriod int,
) *big.Int { ) *big.Int {
totalWithdraw := big.NewInt(0) totalWithdraw := big.NewInt(0)
count := 0 count := 0
for j := range d.Undelegations { for j := range d.Undelegations {
if big.NewInt(0).Sub(curEpoch, d.Undelegations[j].Epoch).Int64() >= LockPeriodInEpoch || if big.NewInt(0).Sub(curEpoch, d.Undelegations[j].Epoch).Int64() >= int64(lockPeriod) ||
big.NewInt(0).Sub(curEpoch, lastEpochInCommittee).Int64() >= LockPeriodInEpoch { big.NewInt(0).Sub(curEpoch, lastEpochInCommittee).Int64() >= int64(lockPeriod) {
// need to wait at least 7 epochs to withdraw; or the validator has been out of committee for 7 epochs // need to wait at least 7 epochs to withdraw; or the validator has been out of committee for 7 epochs
totalWithdraw.Add(totalWithdraw, d.Undelegations[j].Amount) totalWithdraw.Add(totalWithdraw, d.Undelegations[j].Amount)
count++ count++

@ -75,7 +75,7 @@ func TestUnlockedLastEpochInCommittee(t *testing.T) {
amount4 := big.NewInt(4000) amount4 := big.NewInt(4000)
delegation.Undelegate(epoch4, amount4) delegation.Undelegate(epoch4, amount4)
result := delegation.RemoveUnlockedUndelegations(curEpoch, lastEpochInCommittee) result := delegation.RemoveUnlockedUndelegations(curEpoch, lastEpochInCommittee, 7)
if result.Cmp(big.NewInt(8000)) != 0 { if result.Cmp(big.NewInt(8000)) != 0 {
t.Errorf("removing an unlocked undelegation fails") t.Errorf("removing an unlocked undelegation fails")
} }
@ -90,7 +90,7 @@ func TestUnlockedLastEpochInCommitteeFail(t *testing.T) {
amount4 := big.NewInt(4000) amount4 := big.NewInt(4000)
delegation.Undelegate(epoch4, amount4) delegation.Undelegate(epoch4, amount4)
result := delegation.RemoveUnlockedUndelegations(curEpoch, lastEpochInCommittee) result := delegation.RemoveUnlockedUndelegations(curEpoch, lastEpochInCommittee, 7)
if result.Cmp(big.NewInt(0)) != 0 { if result.Cmp(big.NewInt(0)) != 0 {
t.Errorf("premature delegation shouldn't be unlocked") t.Errorf("premature delegation shouldn't be unlocked")
} }
@ -104,7 +104,21 @@ func TestUnlockedFullPeriod(t *testing.T) {
amount5 := big.NewInt(4000) amount5 := big.NewInt(4000)
delegation.Undelegate(epoch5, amount5) delegation.Undelegate(epoch5, amount5)
result := delegation.RemoveUnlockedUndelegations(curEpoch, lastEpochInCommittee) result := delegation.RemoveUnlockedUndelegations(curEpoch, lastEpochInCommittee, 7)
if result.Cmp(big.NewInt(4000)) != 0 {
t.Errorf("removing an unlocked undelegation fails")
}
}
func TestQuickUnlock(t *testing.T) {
lastEpochInCommittee := big.NewInt(44)
curEpoch := big.NewInt(44)
epoch7 := big.NewInt(44)
amount7 := big.NewInt(4000)
delegation.Undelegate(epoch7, amount7)
result := delegation.RemoveUnlockedUndelegations(curEpoch, lastEpochInCommittee, 0)
if result.Cmp(big.NewInt(4000)) != 0 { if result.Cmp(big.NewInt(4000)) != 0 {
t.Errorf("removing an unlocked undelegation fails") t.Errorf("removing an unlocked undelegation fails")
} }
@ -119,7 +133,7 @@ func TestUnlockedFullPeriodFail(t *testing.T) {
amount5 := big.NewInt(4000) amount5 := big.NewInt(4000)
delegation.Undelegate(epoch5, amount5) delegation.Undelegate(epoch5, amount5)
result := delegation.RemoveUnlockedUndelegations(curEpoch, lastEpochInCommittee) result := delegation.RemoveUnlockedUndelegations(curEpoch, lastEpochInCommittee, 7)
if result.Cmp(big.NewInt(0)) != 0 { if result.Cmp(big.NewInt(0)) != 0 {
t.Errorf("premature delegation shouldn't be unlocked") t.Errorf("premature delegation shouldn't be unlocked")
} }
@ -133,7 +147,7 @@ func TestUnlockedPremature(t *testing.T) {
amount6 := big.NewInt(4000) amount6 := big.NewInt(4000)
delegation.Undelegate(epoch6, amount6) delegation.Undelegate(epoch6, amount6)
result := delegation.RemoveUnlockedUndelegations(curEpoch, lastEpochInCommittee) result := delegation.RemoveUnlockedUndelegations(curEpoch, lastEpochInCommittee, 7)
if result.Cmp(big.NewInt(0)) != 0 { if result.Cmp(big.NewInt(0)) != 0 {
t.Errorf("premature delegation shouldn't be unlocked") t.Errorf("premature delegation shouldn't be unlocked")
} }

Loading…
Cancel
Save