Skip to content

Commit

Permalink
Merge pull request #2211 from RainFallsSilent/feature_bpos
Browse files Browse the repository at this point in the history
Merge remote-tracking branch 'elastos/feature_dex' into feature_bpos
  • Loading branch information
RainFallsSilent authored May 23, 2023
2 parents 164655b + bfc0470 commit 29d3562
Show file tree
Hide file tree
Showing 10 changed files with 184 additions and 12 deletions.
11 changes: 8 additions & 3 deletions common/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ func GetDefaultParams() *Configuration {
DPoSV2RewardAccumulateProgramHash: StakeRewardProgramHash,
NFTStartHeight: 1405000,
NFTV2StartHeight: math.MaxUint32, // todo complete me
DexStartHeight: math.MaxUint32, // todo complete me
OriginArbiters: []string{
"0248df6705a909432be041e0baa25b8f648741018f70d1911f2ed28778db4b8fe4",
"02771faf0f4d4235744b30972d5f2c470993920846c761e4d08889ecfdc061cddf",
Expand Down Expand Up @@ -355,7 +356,7 @@ func (p *Configuration) TestNet() *Configuration {
p.DPoSConfiguration.NoCRCDPOSNodeHeight = 815060
p.DPoSConfiguration.RandomCandidatePeriod = 36 * 10
p.DPoSConfiguration.MaxInactiveRoundsOfRandomNode = 36 * 8
p.DPoSConfiguration.DPOSNodeCrossChainHeight = 2000000 // todo complete me
p.DPoSConfiguration.DPOSNodeCrossChainHeight = math.MaxUint32 // todo complete me
p.MaxReservedCustomIDLength = 255
p.DPoSConfiguration.RevertToPOWNoBlockTime = 12 * 3600
p.DPoSConfiguration.StopConfirmBlockTime = 11 * 3600
Expand Down Expand Up @@ -385,6 +386,7 @@ func (p *Configuration) TestNet() *Configuration {
p.CRConfiguration.CRClaimPeriod = 10080
p.DPoSConfiguration.NFTStartHeight = 1098000
p.DPoSConfiguration.NFTV2StartHeight = math.MaxUint32 // todo complete me
p.DPoSConfiguration.DexStartHeight = math.MaxUint32 // todo complete me

p.HttpInfoPort = 21333
p.HttpRestPort = 21334
Expand Down Expand Up @@ -478,7 +480,7 @@ func (p *Configuration) RegNet() *Configuration {
p.DPoSConfiguration.NoCRCDPOSNodeHeight = 706240
p.DPoSConfiguration.RandomCandidatePeriod = 36 * 10
p.DPoSConfiguration.MaxInactiveRoundsOfRandomNode = 36 * 8
p.DPoSConfiguration.DPOSNodeCrossChainHeight = 2000000 // todo complete me
p.DPoSConfiguration.DPOSNodeCrossChainHeight = math.MaxUint32 // todo complete me
p.MaxReservedCustomIDLength = 255
p.DPoSConfiguration.RevertToPOWNoBlockTime = 12 * 3600
p.DPoSConfiguration.StopConfirmBlockTime = 11 * 3600
Expand Down Expand Up @@ -515,7 +517,8 @@ func (p *Configuration) RegNet() *Configuration {
p.ProducerSchnorrStartHeight = math.MaxUint32
p.CRSchnorrStartHeight = math.MaxUint32
p.VotesSchnorrStartHeight = math.MaxUint32
p.MultiExchangeVotesStartHeight = math.MaxUint32 // todo complete me
p.MultiExchangeVotesStartHeight = math.MaxUint32 // todo complete me
p.DPoSConfiguration.DexStartHeight = math.MaxUint32 // todo complete me

p.MemoryPoolTxMaximumStayHeight = 10

Expand Down Expand Up @@ -735,6 +738,8 @@ type DPoSConfiguration struct {
NFTStartHeight uint32 `screw:"--nftstartheight" usage:"the start height of NFT transaction"`
// NFTV2StartHeight defines the height of NFT 2.0 started, NFT transaction will record the detailed votes information.
NFTV2StartHeight uint32 `screw:"--NFTV2StartHeight" usage:"the start height of NFT 2.0 transaction"`
// DexStartHeight defines the height of DEX started.
DexStartHeight uint32 `screw:"--dexstartheight" usage:"the starting height of Dex support"`
}

type CRConfiguration struct {
Expand Down
2 changes: 1 addition & 1 deletion core/transaction/dposv2claimrewardtransaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func (t *DPoSV2ClaimRewardTransaction) SpecialContextCheck() (elaerr.ELAError, b
}

if claimAmount < claimReward.Value {
return elaerr.Simple(elaerr.ErrTxPayload, errors.New("claim reward exceeded , max claim reward "+claimAmount.String())), true
return elaerr.Simple(elaerr.ErrTxPayload, errors.New("claim reward exceeded , max claim reward "+claimAmount.String()+"current:"+ claimAmount.String())), true
}

if claimReward.Value <= t.parameters.Config.CRConfiguration.RealWithdrawSingleFee {
Expand Down
2 changes: 1 addition & 1 deletion core/transaction/dposv2claimrewardtransaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func (s *txValidatorTestSuite) TestCreateClaimDposV2Transaction() {
})

err, _ = tx.SpecialContextCheck()
s.EqualError(err.(errors.ELAError).InnerError(), "claim reward exceeded , max claim reward 0.00000100")
s.EqualError(err.(errors.ELAError).InnerError(), "claim reward exceeded , max claim reward 0.00000100current:0.00000100")

bc = s.Chain
bc.GetState().DPoSV2RewardInfo[stakeAddr] = 10000000000
Expand Down
53 changes: 53 additions & 0 deletions core/transaction/nexttrundposinfotransaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package transaction
import (
"bytes"
"errors"
"fmt"
"math"

"github.com/elastos/Elastos.ELA/blockchain"
Expand All @@ -28,6 +29,16 @@ func (t *NextTurnDPOSInfoTransaction) CheckTransactionInput() error {
return nil
}

func (t *NextTurnDPOSInfoTransaction) HeightVersionCheck() error {
blockHeight := t.parameters.BlockHeight
chainParams := t.parameters.Config
if t.PayloadVersion() >= payload.NextTurnDPOSInfoVersion2 && blockHeight < chainParams.DPoSConfiguration.DexStartHeight {
return errors.New(fmt.Sprintf("not support %s transaction "+
"before DexStartHeight", t.TxType().Name()))
}
return nil
}

func (t *NextTurnDPOSInfoTransaction) CheckTransactionOutput() error {

if len(t.Outputs()) > math.MaxUint16 {
Expand Down Expand Up @@ -87,6 +98,14 @@ func (t *NextTurnDPOSInfoTransaction) SpecialContextCheck() (elaerr.ELAError, bo
return elaerr.Simple(elaerr.ErrTxPayload, errors.New("checkNextTurnDPOSInfoTransaction nextTurnDPOSInfo was wrong")), true
}
}

if t.PayloadVersion() >= payload.NextTurnDPOSInfoVersion2 {
if !isCompleteArbitratorsSame(nextTurnDPOSInfo, nextCRCArbitrators) {
log.Warnf("[checkNextTurnDPOSInfoTransaction] CRPublicKeys %v, nextCRCArbitrators%v\n",
convertToArbitersStr(nextTurnDPOSInfo.CompleteCRPublicKeys), convertToArbitersStr(nextCRCArbitrators))
return elaerr.Simple(elaerr.ErrTxPayload, errors.New("checkNextTurnDPOSInfoTransaction nextTurnDPOSInfo was wrong")), true
}
}
return nil, true
}

Expand Down Expand Up @@ -154,3 +173,37 @@ func isNextArbitratorsSameV1(nextTurnDPOSInfo *payload.NextTurnDPOSInfo,
}
return true
}

func isCompleteArbitratorsSame(nextTurnDPOSInfo *payload.NextTurnDPOSInfo, CRCArbitrators [][]byte) bool {
if len(nextTurnDPOSInfo.CompleteCRPublicKeys) != len(CRCArbitrators) {
log.Warn("[isCompleteArbitratorsSame] CompleteCRPublicKeys len ", len(CRCArbitrators))
return false
}

crcArbitersMap := make(map[string]struct{})
for _, v := range CRCArbitrators {
crcArbitersMap[common.BytesToHexString(v)] = struct{}{}
}
if len(crcArbitersMap) != len(CRCArbitrators) {
log.Warn("[isCompleteArbitratorsSame] duplicated crc arbiters")
return false
}

currentCRCArbtiersMap := make(map[string]struct{})
for _, v := range nextTurnDPOSInfo.CompleteCRPublicKeys {
currentCRCArbtiersMap[common.BytesToHexString(v)] = struct{}{}
}
if len(currentCRCArbtiersMap) != len(nextTurnDPOSInfo.CompleteCRPublicKeys) {
log.Warn("[isCompleteArbitratorsSame] duplicated crc arbiters in payload")
return false
}

for k, _ := range crcArbitersMap {
if _, ok := currentCRCArbtiersMap[k]; !ok {
log.Warn("[isCompleteArbitratorsSame] invalid crc arbiter in payload")
return false
}
}

return true
}
34 changes: 31 additions & 3 deletions core/types/payload/nextturndposinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ import (
)

const NextTurnDPOSInfoVersion byte = 0x00
const NextTurnDPOSInfoVersion2 byte = 0x01

type NextTurnDPOSInfo struct {
WorkingHeight uint32
CRPublicKeys [][]byte
DPOSPublicKeys [][]byte
WorkingHeight uint32
CRPublicKeys [][]byte
DPOSPublicKeys [][]byte
CompleteCRPublicKeys [][]byte

hash *common.Uint256
}
Expand Down Expand Up @@ -59,6 +61,19 @@ func (n *NextTurnDPOSInfo) SerializeUnsigned(w io.Writer, version byte) error {
return err
}
}

if version >= NextTurnDPOSInfoVersion2 {
if err := common.WriteVarUint(w, uint64(len(n.CompleteCRPublicKeys))); err != nil {
return err
}

for _, v := range n.CompleteCRPublicKeys {
if err := common.WriteVarBytes(w, v); err != nil {
return err
}
}
}

return nil
}

Expand Down Expand Up @@ -107,6 +122,19 @@ func (n *NextTurnDPOSInfo) DeserializeUnsigned(r io.Reader, version byte) error
}
n.DPOSPublicKeys = append(n.DPOSPublicKeys, DPOSPublicKey)
}

if version >= NextTurnDPOSInfoVersion2 {
n.CompleteCRPublicKeys = make([][]byte, 0, len)
for i := uint64(0); i < len; i++ {
var publicKey []byte
if publicKey, err = common.ReadVarBytes(r, crypto.COMPRESSEDLEN,
"complete crcs"); err != nil {
return err
}
n.CompleteCRPublicKeys = append(n.CompleteCRPublicKeys, publicKey)
}
}

return nil
}

Expand Down
58 changes: 58 additions & 0 deletions dpos/state/arbitrators.go
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,13 @@ func (a *Arbiters) normalChange(height uint32) error {
}

func (a *Arbiters) notifyNextTurnDPOSInfoTx(blockHeight, versionHeight uint32, forceChange bool) {
if blockHeight+uint32(a.ChainParams.DPoSConfiguration.NormalArbitratorsCount+len(a.ChainParams.DPoSConfiguration.CRCArbiters)) >= a.ChainParams.DPoSConfiguration.DexStartHeight {
nextTurnDPOSInfoTx := a.createNextTurnDPOSInfoTransactionV2(blockHeight, forceChange)
go events.Notify(events.ETAppendTxToTxPool, nextTurnDPOSInfoTx)

return
}

if blockHeight+uint32(a.ChainParams.DPoSConfiguration.NormalArbitratorsCount+len(a.ChainParams.DPoSConfiguration.CRCArbiters)) >= a.DPoSV2ActiveHeight {
nextTurnDPOSInfoTx := a.createNextTurnDPOSInfoTransactionV1(blockHeight, forceChange)
go events.Notify(events.ETAppendTxToTxPool, nextTurnDPOSInfoTx)
Expand All @@ -519,6 +526,7 @@ func (a *Arbiters) notifyNextTurnDPOSInfoTx(blockHeight, versionHeight uint32, f

nextTurnDPOSInfoTx := a.createNextTurnDPOSInfoTransactionV0(blockHeight, forceChange)
go events.Notify(events.ETAppendTxToTxPool, nextTurnDPOSInfoTx)

return
}

Expand Down Expand Up @@ -1862,6 +1870,56 @@ func (a *Arbiters) createNextTurnDPOSInfoTransactionV0(blockHeight uint32, force
)
}

func (a *Arbiters) createNextTurnDPOSInfoTransactionV2(blockHeight uint32, forceChange bool) interfaces.Transaction {

var nextTurnDPOSInfo payload.NextTurnDPOSInfo
nextTurnDPOSInfo.CRPublicKeys = make([][]byte, 0)
nextTurnDPOSInfo.DPOSPublicKeys = make([][]byte, 0)
var workingHeight uint32
if forceChange {
workingHeight = blockHeight
} else {
workingHeight = blockHeight + uint32(a.ChainParams.DPoSConfiguration.NormalArbitratorsCount+len(a.ChainParams.DPoSConfiguration.CRCArbiters))
}
nextTurnDPOSInfo.WorkingHeight = workingHeight
for _, v := range a.nextCRCArbiters {
nodePK := v.GetNodePublicKey()
if v.IsNormal() {
nextTurnDPOSInfo.CRPublicKeys = append(nextTurnDPOSInfo.CRPublicKeys, nodePK)
} else {
nextTurnDPOSInfo.CRPublicKeys = append(nextTurnDPOSInfo.CRPublicKeys, []byte{})
}

nextTurnDPOSInfo.CompleteCRPublicKeys = append(nextTurnDPOSInfo.CompleteCRPublicKeys, nodePK)
}
for _, v := range a.nextArbitrators {
if a.isNextCRCArbitrator(v.GetNodePublicKey()) {
if abt, ok := v.(*crcArbiter); ok && abt.crMember.MemberState != state.MemberElected {
nextTurnDPOSInfo.DPOSPublicKeys = append(nextTurnDPOSInfo.DPOSPublicKeys, []byte{})
} else {
nextTurnDPOSInfo.DPOSPublicKeys = append(nextTurnDPOSInfo.DPOSPublicKeys, v.GetNodePublicKey())
}
} else {
nextTurnDPOSInfo.DPOSPublicKeys = append(nextTurnDPOSInfo.DPOSPublicKeys, v.GetNodePublicKey())
}
}

log.Debugf("[createNextTurnDPOSInfoTransaction] CRPublicKeys %v, DPOSPublicKeys%v\n",
a.ConvertToArbitersStr(nextTurnDPOSInfo.CRPublicKeys), a.ConvertToArbitersStr(nextTurnDPOSInfo.DPOSPublicKeys))

return functions.CreateTransaction(
common2.TxVersion09,
common2.NextTurnDPOSInfo,
payload.NextTurnDPOSInfoVersion2,
&nextTurnDPOSInfo,
[]*common2.Attribute{},
[]*common2.Input{},
[]*common2.Output{},
0,
[]*program.Program{},
)
}

func (a *Arbiters) createNextTurnDPOSInfoTransactionV1(blockHeight uint32, forceChange bool) interfaces.Transaction {

var nextTurnDPOSInfo payload.NextTurnDPOSInfo
Expand Down
2 changes: 1 addition & 1 deletion pow/revertlistener.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (pow *Service) ListenForRevert() {
}
lastBlockTimestamp := int64(pow.arbiters.GetLastBlockTimestamp())
localTimestamp := pow.chain.TimeSource.AdjustedTime().Unix()
log.Info("ListenForRevert lastBlockTimestamp:", lastBlockTimestamp,
log.Debug("ListenForRevert lastBlockTimestamp:", lastBlockTimestamp,
"localTimestamp:", localTimestamp, "RevertToPOWNoBlockTime:", pow.chainParams.DPoSConfiguration.RevertToPOWNoBlockTime)
if localTimestamp-lastBlockTimestamp < pow.chainParams.DPoSConfiguration.RevertToPOWNoBlockTime {
continue
Expand Down
7 changes: 7 additions & 0 deletions servers/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,13 @@ type NextTurnDPOSPayloadInfo struct {
DPOSPublicKeys []string `json:"dpospublickeys"`
}

type NextTurnDPOSPayloadInfoV2 struct {
WorkingHeight uint32 `json:"workingheight"`
CRPublicKeys []string `json:"crpublickeys"`
DPOSPublicKeys []string `json:"dpospublickeys"`
CompleteCRPublicKeys []string `json:"CompleteCRPublicKeys"`
}

type CRCProposalRealWithdrawInfo struct {
WithdrawTransactionHashes []string `json:"withdrawtransactionhashes"`
}
Expand Down
25 changes: 23 additions & 2 deletions servers/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -3554,18 +3554,39 @@ func getPayloadInfo(p interfaces.Payload, payloadVersion byte) PayloadInfo {
return obj

case *payload.NextTurnDPOSInfo:
obj := new(NextTurnDPOSPayloadInfo)
if payloadVersion == payload.NextTurnDPOSInfoVersion {
obj := new(NextTurnDPOSPayloadInfo)
crPublicKeysString := make([]string, 0)
dposPublicKeysString := make([]string, 0)
for _, v := range object.CRPublicKeys {
crPublicKeysString = append(crPublicKeysString, common.BytesToHexString(v))
}
for _, v := range object.DPOSPublicKeys {
dposPublicKeysString = append(dposPublicKeysString, common.BytesToHexString(v))
}
obj.WorkingHeight = object.WorkingHeight
obj.CRPublickeys = crPublicKeysString
obj.DPOSPublicKeys = dposPublicKeysString
return obj
}

obj := new(NextTurnDPOSPayloadInfoV2)
crPublicKeysString := make([]string, 0)
dposPublicKeysString := make([]string, 0)
completeCRPublicKeysString := make([]string, 0)
for _, v := range object.CRPublicKeys {
crPublicKeysString = append(crPublicKeysString, common.BytesToHexString(v))
}
for _, v := range object.DPOSPublicKeys {
dposPublicKeysString = append(dposPublicKeysString, common.BytesToHexString(v))
}
for _, v := range object.CompleteCRPublicKeys {
completeCRPublicKeysString = append(completeCRPublicKeysString, common.BytesToHexString(v))
}
obj.WorkingHeight = object.WorkingHeight
obj.CRPublickeys = crPublicKeysString
obj.CRPublicKeys = crPublicKeysString
obj.DPOSPublicKeys = dposPublicKeysString
obj.CompleteCRPublicKeys = completeCRPublicKeysString
return obj

case *payload.CRCProposalRealWithdraw:
Expand Down
2 changes: 1 addition & 1 deletion test/unit/txvalidator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7526,7 +7526,7 @@ func (s *txValidatorTestSuite) TestCreateCRClaimDposV2Transaction() {
})

err, _ = tx.SpecialContextCheck()
s.EqualError(err.(errors.ELAError).InnerError(), "claim reward exceeded , max claim reward 0.00000100")
s.EqualError(err.(errors.ELAError).InnerError(), "claim reward exceeded , max claim reward 0.00000100current:0.00000100")

bc = s.Chain
bc.GetState().DPoSV2RewardInfo[stakeAddr] = 10000000000
Expand Down

0 comments on commit 29d3562

Please sign in to comment.