Skip to content

Commit

Permalink
feat(bpos): use State mtx protect member variables
Browse files Browse the repository at this point in the history
  • Loading branch information
Houshoupei84 committed Sep 6, 2023
1 parent edea772 commit eddb7e7
Show file tree
Hide file tree
Showing 22 changed files with 282 additions and 99 deletions.
3 changes: 0 additions & 3 deletions blockchain/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,6 @@ func (b *BlockChain) GetHeight() uint32 {

return b.getHeight()
}

func (b *BlockChain) getHeight() uint32 {
if len(b.Nodes) == 0 {
return 0
Expand Down Expand Up @@ -1645,9 +1644,7 @@ func (b *BlockChain) maybeAcceptBlock(block *Block, confirm *payload.Confirm) (b
b.state.RevertToPOWBlockHeight, false)
DefaultLedger.Arbitrators.DumpInfo(block.Height)
}

events.Notify(events.ETBlockProcessed, block)

// Notify the caller that the new block was accepted into the block
// chain. The caller would typically want to react by relaying the
// inventory to other peers.
Expand Down
1 change: 0 additions & 1 deletion core/checkpoint/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,6 @@ func (m *Manager) onBlockSaved(block *types.DposBlock,
<-reply
}
}

if block.Height >=
originalHeight+v.SavePeriod() {
v.SetHeight(block.Height)
Expand Down
2 changes: 1 addition & 1 deletion core/transaction/activateproducertransaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ func (t *ActivateProducerTransaction) SpecialContextCheck() (elaerr.ELAError, bo
}

var minActivateAmount common.Fixed64
if t.parameters.BlockHeight >= t.parameters.BlockChain.GetState().DPoSV2ActiveHeight {
if t.parameters.BlockHeight >= t.parameters.BlockChain.GetState().GetDPoSV2ActiveHeight() {
switch producer.Identity() {
case state.DPoSV1:
return elaerr.Simple(elaerr.ErrTxPayload, errors.New("not allow to activate producer 1.0")), true
Expand Down
2 changes: 1 addition & 1 deletion core/transaction/crcappropriationtransaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ func (t *CRCAppropriationTransaction) SpecialContextCheck() (result elaerr.ELAEr
//
// Outputs has check in CheckTransactionOutput function:
// first one to CRCommitteeAddress, second one to CRAssetsAddress
appropriationAmount := t.parameters.BlockChain.GetCRCommittee().AppropriationAmount
appropriationAmount := t.parameters.BlockChain.GetCRCommittee().GetAppropriationAmount()
if appropriationAmount != t.Outputs()[0].Value {
return elaerr.Simple(elaerr.ErrTxPayload,
fmt.Errorf("invalid appropriation amount %s, need to be %s",
Expand Down
5 changes: 2 additions & 3 deletions core/transaction/crcouncilmemberclaimnodetransaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ package transaction

import (
"bytes"
"encoding/hex"
"errors"
"fmt"

Expand Down Expand Up @@ -64,7 +63,7 @@ func (t *CRCouncilMemberClaimNodeTransaction) SpecialContextCheck() (result elae
switch t.payloadVersion {
case payload.CurrentCRClaimDPoSNodeVersion:
crMember = t.parameters.BlockChain.GetCRCommittee().GetMember(did)
if _, ok := comm.ClaimedDPoSKeys[hex.EncodeToString(manager.NodePublicKey)]; ok {
if ok := comm.ClaimedDPoSKey(manager.NodePublicKey); ok {
return elaerr.Simple(elaerr.ErrTxPayload, fmt.Errorf("producer already registered")), true
}
// check duplication of node.
Expand All @@ -73,7 +72,7 @@ func (t *CRCouncilMemberClaimNodeTransaction) SpecialContextCheck() (result elae
}
case payload.NextCRClaimDPoSNodeVersion:
crMember = t.parameters.BlockChain.GetCRCommittee().GetNextMember(did)
if _, ok := comm.NextClaimedDPoSKeys[hex.EncodeToString(manager.NodePublicKey)]; ok {
if ok := comm.NextClaimedDPoSKey(manager.NodePublicKey); ok {
return elaerr.Simple(elaerr.ErrTxPayload, fmt.Errorf("producer already registered")), true
}
// check duplication of node.
Expand Down
12 changes: 6 additions & 6 deletions core/transaction/crcproposaltransaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -643,15 +643,15 @@ func (t *CRCProposalTransaction) checkNormalOrELIPProposal(params *TransactionPa
if finalPaymentCount != 1 {
return errors.New("final payment count invalid")
}
if amount > (t.parameters.BlockChain.GetCRCommittee().CRCCurrentStageAmount-
t.parameters.BlockChain.GetCRCommittee().CommitteeUsedAmount)*blockchain.CRCProposalBudgetsPercentage/100 {
if amount > (t.parameters.BlockChain.GetCRCommittee().GetCRCCurrentStageAmount()-
t.parameters.BlockChain.GetCRCommittee().GetCommitteeUsedAmount())*blockchain.CRCProposalBudgetsPercentage/100 {
return errors.New("budgets exceeds 10% of CRC committee balance")
} else if amount > t.parameters.BlockChain.GetCRCommittee().CRCCurrentStageAmount-
t.parameters.BlockChain.GetCRCommittee().CRCCommitteeUsedAmount-proposalsUsedAmount {
} else if amount > t.parameters.BlockChain.GetCRCommittee().GetCRCCurrentStageAmount()-
t.parameters.BlockChain.GetCRCommittee().GetCRCCommitteeUsedAmount()-proposalsUsedAmount {
return errors.New(fmt.Sprintf("budgets exceeds the balance of CRC"+
" committee, proposal hash:%s, budgets:%s, need <= %s",
common.ToReversedString(proposal.Hash(PayloadVersion)), amount, t.parameters.BlockChain.GetCRCommittee().CRCCurrentStageAmount-
t.parameters.BlockChain.GetCRCommittee().CRCCommitteeUsedAmount-proposalsUsedAmount))
common.ToReversedString(proposal.Hash(PayloadVersion)), amount, t.parameters.BlockChain.GetCRCommittee().GetCRCCurrentStageAmount()-
t.parameters.BlockChain.GetCRCommittee().GetCRCCommitteeUsedAmount()-proposalsUsedAmount))
} else if amount < 0 {
return errors.New("budgets is invalid")
}
Expand Down
19 changes: 10 additions & 9 deletions core/transaction/createnfttransaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ func (t *CreateNFTTransaction) SpecialContextCheck() (elaerr.ELAError, bool) {
}

state := t.parameters.BlockChain.GetState()
crState := t.parameters.BlockChain.GetCRCommittee().GetState()
crCommittee := t.parameters.BlockChain.GetCRCommittee()

producers := state.GetDposV2Producers()
nftID := common.GetNFTID(pld.ReferKey, t.hash())
var existVote bool
Expand Down Expand Up @@ -143,37 +144,37 @@ func (t *CreateNFTTransaction) SpecialContextCheck() (elaerr.ELAError, bool) {
}

// nft has not been created before
if g, ok := state.NFTIDInfoHashMap[nftID]; ok {
if nftInfo := state.GetNFTInfo(nftID); nftInfo != nil {
log.Warnf("NFT has been create before, side chain genesis block "+
"hash: %s", g)
"hash: %s", nftInfo.GenesisBlockHash.String())
return elaerr.Simple(elaerr.ErrTxPayload,
errors.New("NFT has been created before")), true
}

// check the vote rights is enough or not
totalVoteRights := state.DposV2VoteRights[*stakeProgramHash]
totalVoteRights := state.GetDposV2VoteRights(*stakeProgramHash)
var usedCRVotes common.Fixed64
if ucv := crState.UsedCRVotes[*stakeProgramHash]; ucv != nil {
if ucv := crCommittee.GetUsedCRVotes(*stakeProgramHash); ucv != nil {
for _, v := range ucv {
usedCRVotes += v.Votes
}
}
var usedCRImpeachmentVotes common.Fixed64
if ucv := crState.UsedCRImpeachmentVotes[*stakeProgramHash]; ucv != nil {
if ucv := crCommittee.GetUsedCRImpeachmentVotes(*stakeProgramHash); ucv != nil {
for _, v := range ucv {
usedCRImpeachmentVotes += v.Votes
}
}
var usedCRProposalVotes common.Fixed64
if ucv := crState.UsedCRCProposalVotes[*stakeProgramHash]; ucv != nil {
if ucv := crCommittee.GetUsedCRCProposalVotes(*stakeProgramHash); ucv != nil {
for _, v := range ucv {
if usedCRProposalVotes < v.Votes {
usedCRProposalVotes = v.Votes
}
}
}
var usedDPoSVotes common.Fixed64
if udv := state.UsedDposVotes[*stakeProgramHash]; udv != nil {
if udv, ok := state.GetUsedDposVotes(*stakeProgramHash); ok {
for _, v := range udv {
if usedDPoSVotes < v.Votes {
usedDPoSVotes = v.Votes
Expand All @@ -182,7 +183,7 @@ func (t *CreateNFTTransaction) SpecialContextCheck() (elaerr.ELAError, bool) {
}

blockHeight := t.parameters.BlockHeight
if blockHeight < state.DPoSV2ActiveHeight {
if blockHeight < state.GetDPoSV2ActiveHeight() {
if nftAmount > totalVoteRights-usedDPoSVotes {
log.Errorf("vote rights is not enough, nft amount:%s, "+
"total vote rights:%s, used DPoS 1.0 votes:%s",
Expand Down
6 changes: 3 additions & 3 deletions core/transaction/dposv2claimrewardtransaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,13 @@ func (t *DPoSV2ClaimRewardTransaction) SpecialContextCheck() (elaerr.ELAError, b
if err != nil {
return elaerr.Simple(elaerr.ErrTxPayload, errors.New("Programs code to address error")), true
}
claimAmount, ok := t.parameters.BlockChain.GetState().DPoSV2RewardInfo[addr]
if !ok {
claimAmount := t.parameters.BlockChain.GetState().GetDPoSV2RewardInfo(addr)
if claimAmount == 0 {
return elaerr.Simple(elaerr.ErrTxPayload, errors.New("no reward to claim for such address")), true
}

if claimAmount < claimReward.Value {
return elaerr.Simple(elaerr.ErrTxPayload, errors.New("claim reward exceeded , max claim reward "+claimAmount.String()+"current:"+ 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
6 changes: 2 additions & 4 deletions core/transaction/registerproducertransaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@ import (
"bytes"
"errors"
"fmt"
state2 "github.com/elastos/Elastos.ELA/dpos/state"

"github.com/elastos/Elastos.ELA/blockchain"
"github.com/elastos/Elastos.ELA/common"
"github.com/elastos/Elastos.ELA/core/contract"
"github.com/elastos/Elastos.ELA/core/types/payload"
crstate "github.com/elastos/Elastos.ELA/cr/state"
"github.com/elastos/Elastos.ELA/crypto"
state2 "github.com/elastos/Elastos.ELA/dpos/state"
elaerr "github.com/elastos/Elastos.ELA/errors"
"github.com/elastos/Elastos.ELA/vm"
)
Expand Down Expand Up @@ -201,12 +200,11 @@ func (t *RegisterProducerTransaction) SpecialContextCheck() (elaerr.ELAError, bo
state := t.parameters.BlockChain.GetState()
if height < t.parameters.Config.DPoSV2StartHeight && t.payloadVersion == payload.ProducerInfoDposV2Version {
return elaerr.Simple(elaerr.ErrTxPayload, fmt.Errorf("can not register dposv2 before dposv2 start height")), true
} else if height > state.DPoSV2ActiveHeight && t.payloadVersion == payload.ProducerInfoVersion {
} else if height > state.GetDPoSV2ActiveHeight() && t.payloadVersion == payload.ProducerInfoVersion {
return elaerr.Simple(elaerr.ErrTxPayload, fmt.Errorf("can not register dposv1 after dposv2 active height")), true
} else if height < t.parameters.Config.SupportMultiCodeHeight && t.payloadVersion == payload.ProducerInfoMultiVersion {
return elaerr.Simple(elaerr.ErrTxPayload, fmt.Errorf("not support ProducerInfoMultiVersion when height is not reach SupportMultiCodeHeight")), true
}

var ownKeyProgramHash *common.Uint168

ownKeyProgramHash, err := state2.GetOwnerKeyDepositProgramHash(info.OwnerKey)
Expand Down
6 changes: 3 additions & 3 deletions core/transaction/returnvotes.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,15 @@ func (t *ReturnVotesTransaction) SpecialContextCheck() (result elaerr.ELAError,
stakeProgramHash := ct.ToProgramHash()
state := t.parameters.BlockChain.GetState()
commitee := t.parameters.BlockChain.GetCRCommittee()
voteRights := state.DposV2VoteRights[*stakeProgramHash]
voteRights := state.GetDposV2VoteRights(*stakeProgramHash)
usedDposVoteRights := state.GetUsedDPoSVoteRights(stakeProgramHash)
usedDposV2VoteRights := state.UsedDposV2Votes[*stakeProgramHash]
usedDposV2VoteRights := state.GetUsedDposV2Votes(*stakeProgramHash)
cs := commitee.GetState()
usedCRVoteRights := cs.GetUsedCRVoteRights(stakeProgramHash)
usedCRImpeachmentVoteRights := cs.GetUsedCRImpeachmentVoteRights(stakeProgramHash)
usedCRCProposalVoteRights := cs.GetUsedCRCProposalVoteRights(stakeProgramHash)

if t.parameters.BlockHeight > state.DPoSV2ActiveHeight {
if t.parameters.BlockHeight > state.GetDPoSV2ActiveHeight() {
if pl.Value > voteRights-usedDposV2VoteRights ||
pl.Value > voteRights-usedCRVoteRights ||
pl.Value > voteRights-usedCRImpeachmentVoteRights ||
Expand Down
2 changes: 1 addition & 1 deletion core/transaction/reverttodpostransaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func (t *RevertToDPOSTransaction) SpecialContextCheck() (elaerr.ELAError, bool)
}

// to avoid init DPOSWorkHeight repeatedly
if t.parameters.BlockChain.GetState().DPOSWorkHeight > t.parameters.BlockHeight {
if t.parameters.BlockChain.GetState().GetDPOSWorkHeight() > t.parameters.BlockHeight {
return elaerr.Simple(elaerr.ErrTxPayload, errors.New("already receieved revertodpos")), true
}

Expand Down
4 changes: 2 additions & 2 deletions core/transaction/reverttopowtransaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,11 @@ func (t *RevertToPOWTransaction) SpecialContextCheck() (result elaerr.ELAError,
}
}
case payload.NoProducers:
if !t.parameters.BlockChain.GetState().NoProducers {
if !t.parameters.BlockChain.GetState().GetNoProducers() {
return elaerr.Simple(elaerr.ErrTxPayload, errors.New("current producers is enough")), true
}
case payload.NoClaimDPOSNode:
if !t.parameters.BlockChain.GetState().NoClaimDPOSNode {
if !t.parameters.BlockChain.GetState().GetNoClaimDPOSNode() {
return elaerr.Simple(elaerr.ErrTxPayload, errors.New("current CR member claimed DPoS node")), true
}
}
Expand Down
2 changes: 1 addition & 1 deletion core/transaction/transactionchecker.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ func (t *DefaultChecker) tryCheckVoteOutputs() error {
candidates = []*crstate.Candidate{}
}
dposv2Run := false
if blockHeight >= dposState.DPoSV2ActiveHeight {
if blockHeight >= dposState.GetDPoSV2ActiveHeight() {
dposv2Run = true
}
err := t.checkVoteOutputs(blockHeight, txn.Outputs(), t.references,
Expand Down
8 changes: 4 additions & 4 deletions core/transaction/updateproducertransaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ func (t *UpdateProducerTransaction) SpecialContextCheck() (elaerr.ELAError, bool
if producer == nil {
return elaerr.Simple(elaerr.ErrTxPayload, errors.New("updating unknown producer")), true
}
stake := t.parameters.BlockChain.GetState()
dposState := t.parameters.BlockChain.GetState()
//if producer is already dposv2
switch producer.Identity() {
case state.DPoSV1:
Expand All @@ -173,7 +173,7 @@ func (t *UpdateProducerTransaction) SpecialContextCheck() (elaerr.ELAError, bool
}

case state.DPoSV1V2:
if t.parameters.BlockHeight >= stake.DPoSV2ActiveHeight {
if t.parameters.BlockHeight >= dposState.GetDPoSV2ActiveHeight() {
if t.parameters.BlockHeight > producer.Info().StakeUntil {
return elaerr.Simple(elaerr.ErrTxPayload, errors.New("producer already expired and dposv2 already started, can not update anything ")), true
}
Expand Down Expand Up @@ -246,7 +246,7 @@ func (t *UpdateProducerTransaction) additionalProducerInfoCheck(info *payload.Pr
return errors.New("invalid node public key in payload")
}

for _, m := range t.parameters.BlockChain.GetCRCommittee().Members {
for _, m := range t.parameters.BlockChain.GetCRCommittee().GetMembers() {
if bytes.Equal(m.DPOSPublicKey, info.NodePublicKey) {
return errors.New("node public key can't equal with current CR Node PK")
}
Expand All @@ -255,7 +255,7 @@ func (t *UpdateProducerTransaction) additionalProducerInfoCheck(info *payload.Pr
}
}

for _, m := range t.parameters.BlockChain.GetCRCommittee().NextMembers {
for _, m := range t.parameters.BlockChain.GetCRCommittee().GetNextMembers() {
if bytes.Equal(m.DPOSPublicKey, info.NodePublicKey) {
return errors.New("node public key can't equal with next CR Node PK")
}
Expand Down
11 changes: 3 additions & 8 deletions core/transaction/voting.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,8 @@ func (t *VotingTransaction) SpecialContextCheck() (result elaerr.ELAError, end b
}
stakeProgramHash := ct.ToProgramHash()
state := t.parameters.BlockChain.GetState()
//commitee := t.parameters.BlockChain.GetCRCommittee()
voteRights := state.DposV2VoteRights
totalVotes, exist := voteRights[*stakeProgramHash]
if !exist {
return elaerr.Simple(elaerr.ErrTxInvalidOutput, errors.New("has no vote rights")), true
}
usedDPoSV2VoteRights, _ := state.UsedDposV2Votes[*stakeProgramHash]
totalVotes := state.GetDposV2VoteRights(*stakeProgramHash)
usedDPoSV2VoteRights := state.GetUsedDposV2Votes(*stakeProgramHash)

var candidates []*crstate.Candidate
if crCommittee.IsInVotingPeriod(blockHeight) {
Expand Down Expand Up @@ -161,7 +156,7 @@ func (t *VotingTransaction) SpecialContextCheck() (result elaerr.ELAError, end b

switch content.VoteType {
case outputpayload.Delegate:
if blockHeight > state.DPoSV2ActiveHeight {
if blockHeight > state.GetDPoSV2ActiveHeight() {
return elaerr.Simple(elaerr.ErrTxPayload,
errors.New("delegate votes is not allowed in DPoS V2")), true
}
Expand Down
Loading

0 comments on commit eddb7e7

Please sign in to comment.