github.com/intfoundation/intchain@v0.0.0-20220727031208-4316ad31ca73/core/pending_ops.go (about)

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