github.com/Gessiux/neatchain@v1.3.1/chain/core/pending_ops.go (about)

     1  package core
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/Gessiux/neatchain/chain/consensus"
     7  	tmTypes "github.com/Gessiux/neatchain/chain/consensus/neatcon/types"
     8  	"github.com/Gessiux/neatchain/chain/core/types"
     9  )
    10  
    11  // Consider moving the apply logic to each op (how to avoid import circular reference?)
    12  func ApplyOp(op types.PendingOp, bc *BlockChain, cch CrossChainHelper) error {
    13  	switch op := op.(type) {
    14  	case *types.CreateSideChainOp:
    15  		return cch.CreateSideChain(op.From, op.ChainId, op.MinValidators, op.MinDepositAmount, op.StartBlock, op.EndBlock)
    16  	case *types.JoinSideChainOp:
    17  		return cch.JoinSideChain(op.From, op.PubKey, op.ChainId, op.DepositAmount)
    18  	case *types.LaunchSideChainsOp:
    19  		if len(op.SideChainIds) > 0 {
    20  			var events []interface{}
    21  			for _, sideChainId := range op.SideChainIds {
    22  				events = append(events, CreateSideChainEvent{ChainId: sideChainId})
    23  			}
    24  			bc.PostChainEvents(events, nil)
    25  		}
    26  		if op.NewPendingIdx != nil || len(op.DeleteSideChainIds) > 0 {
    27  			cch.ProcessPostPendingData(op.NewPendingIdx, op.DeleteSideChainIds)
    28  		}
    29  		return nil
    30  	case *types.VoteNextEpochOp:
    31  		ep := bc.engine.(consensus.NeatCon).GetEpoch()
    32  		ep = ep.GetEpochByBlockNumber(bc.CurrentBlock().NumberU64())
    33  		return cch.VoteNextEpoch(ep, op.From, op.VoteHash, op.TxHash)
    34  	case *types.RevealVoteOp:
    35  		ep := bc.engine.(consensus.NeatCon).GetEpoch()
    36  		ep = ep.GetEpochByBlockNumber(bc.CurrentBlock().NumberU64())
    37  		return cch.RevealVote(ep, op.From, op.Pubkey, op.Amount, op.Salt, op.TxHash)
    38  	case *types.UpdateNextEpochOp:
    39  		ep := bc.engine.(consensus.NeatCon).GetEpoch()
    40  		ep = ep.GetEpochByBlockNumber(bc.CurrentBlock().NumberU64())
    41  		return cch.UpdateNextEpoch(ep, op.From, op.PubKey, op.Amount, op.Salt, op.TxHash)
    42  	case *types.SaveDataToMainChainOp:
    43  		return cch.SaveSideChainProofDataToMainChain(op.Data)
    44  	case *tmTypes.SwitchEpochOp:
    45  		eng := bc.engine.(consensus.NeatCon)
    46  		nextEp, err := eng.GetEpoch().EnterNewEpoch(op.NewValidators)
    47  		if err == nil {
    48  			// Stop the Engine if we are not in the new validators
    49  			if !op.NewValidators.HasAddress(eng.PrivateValidator().Bytes()) && eng.IsStarted() {
    50  				bc.PostChainEvents([]interface{}{StopMiningEvent{}}, nil)
    51  			}
    52  
    53  			//Start the Engine if we are in the new validators
    54  			if op.NewValidators.HasAddress(eng.PrivateValidator().Bytes()) && !eng.IsStarted() {
    55  				bc.PostChainEvents([]interface{}{StartMiningEvent{}}, nil)
    56  			}
    57  
    58  			eng.SetEpoch(nextEp)
    59  			cch.ChangeValidators(op.ChainId) //must after eng.SetEpoch(nextEp), it uses epoch just set
    60  		}
    61  		return err
    62  	default:
    63  		return fmt.Errorf("unknown op: %v", op)
    64  	}
    65  }