github.com/Gessiux/neatchain@v1.3.1/chain/consensus/neatcon/api.go (about)

     1  package neatcon
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"math/big"
     7  
     8  	"github.com/Gessiux/go-crypto"
     9  	"github.com/Gessiux/neatchain/chain/consensus"
    10  	"github.com/Gessiux/neatchain/chain/consensus/neatcon/epoch"
    11  	ntcTypes "github.com/Gessiux/neatchain/chain/consensus/neatcon/types"
    12  	"github.com/Gessiux/neatchain/utilities/common"
    13  	"github.com/Gessiux/neatchain/utilities/common/hexutil"
    14  	neatCrypto "github.com/Gessiux/neatchain/utilities/crypto"
    15  )
    16  
    17  // API is a user facing RPC API of NeatCon
    18  type API struct {
    19  	chain   consensus.ChainReader
    20  	neatcon *backend
    21  }
    22  
    23  // GetCurrentEpochNumber retrieves the current epoch number.
    24  func (api *API) GetCurrentEpochNumber() (hexutil.Uint64, error) {
    25  	return hexutil.Uint64(api.neatcon.core.consensusState.Epoch.Number), nil
    26  }
    27  
    28  // GetEpoch retrieves the Epoch Detail by Number
    29  func (api *API) GetEpoch(num hexutil.Uint64) (*ntcTypes.EpochApiForConsole, error) {
    30  
    31  	number := uint64(num)
    32  	var resultEpoch *epoch.Epoch
    33  	curEpoch := api.neatcon.core.consensusState.Epoch
    34  	if number < 0 || number > curEpoch.Number {
    35  		return nil, errors.New("epoch number out of range")
    36  	}
    37  
    38  	if number == curEpoch.Number {
    39  		resultEpoch = curEpoch
    40  	} else {
    41  		resultEpoch = epoch.LoadOneEpoch(curEpoch.GetDB(), number, nil)
    42  	}
    43  
    44  	validators := make([]*ntcTypes.EpochValidatorForConsole, len(resultEpoch.Validators.Validators))
    45  	for i, val := range resultEpoch.Validators.Validators {
    46  		validators[i] = &ntcTypes.EpochValidatorForConsole{
    47  			Address:        common.BytesToAddress(val.Address).String(),
    48  			PubKey:         val.PubKey.KeyString(),
    49  			Amount:         (*hexutil.Big)(val.VotingPower),
    50  			RemainingEpoch: hexutil.Uint64(val.RemainingEpoch),
    51  		}
    52  	}
    53  
    54  	return &ntcTypes.EpochApiForConsole{
    55  		Number:         hexutil.Uint64(resultEpoch.Number),
    56  		RewardPerBlock: (*hexutil.Big)(resultEpoch.RewardPerBlock),
    57  		StartBlock:     hexutil.Uint64(resultEpoch.StartBlock),
    58  		EndBlock:       hexutil.Uint64(resultEpoch.EndBlock),
    59  		StartTime:      resultEpoch.StartTime,
    60  		EndTime:        resultEpoch.EndTime,
    61  		Validators:     validators,
    62  	}, nil
    63  }
    64  
    65  // GetEpochVote
    66  func (api *API) GetNextEpochVote() (*ntcTypes.EpochVotesApiForConsole, error) {
    67  
    68  	ep := api.neatcon.core.consensusState.Epoch
    69  	if ep.GetNextEpoch() != nil {
    70  
    71  		var votes []*epoch.EpochValidatorVote
    72  		if ep.GetNextEpoch().GetEpochValidatorVoteSet() != nil {
    73  			votes = ep.GetNextEpoch().GetEpochValidatorVoteSet().Votes
    74  		}
    75  		votesApi := make([]*ntcTypes.EpochValidatorVoteApiForConsole, 0, len(votes))
    76  		for _, v := range votes {
    77  			var pkstring string
    78  			if v.PubKey != nil {
    79  				pkstring = v.PubKey.KeyString()
    80  			}
    81  
    82  			votesApi = append(votesApi, &ntcTypes.EpochValidatorVoteApiForConsole{
    83  				EpochValidatorForConsole: ntcTypes.EpochValidatorForConsole{
    84  					Address: v.Address.String(),
    85  					PubKey:  pkstring,
    86  					Amount:  (*hexutil.Big)(v.Amount),
    87  				},
    88  				Salt:     v.Salt,
    89  				VoteHash: v.VoteHash,
    90  				TxHash:   v.TxHash,
    91  			})
    92  		}
    93  
    94  		return &ntcTypes.EpochVotesApiForConsole{
    95  			EpochNumber: hexutil.Uint64(ep.GetNextEpoch().Number),
    96  			StartBlock:  hexutil.Uint64(ep.GetNextEpoch().StartBlock),
    97  			EndBlock:    hexutil.Uint64(ep.GetNextEpoch().EndBlock),
    98  			Votes:       votesApi,
    99  		}, nil
   100  	}
   101  	return nil, errors.New("next epoch has not been proposed")
   102  }
   103  
   104  func (api *API) GetNextEpochValidators() ([]*ntcTypes.EpochValidatorForConsole, error) {
   105  
   106  	//height := api.chain.CurrentBlock().NumberU64()
   107  
   108  	ep := api.neatcon.core.consensusState.Epoch
   109  	nextEp := ep.GetNextEpoch()
   110  	if nextEp == nil {
   111  		return nil, errors.New("voting for next epoch has not started yet")
   112  	} else {
   113  		state, err := api.chain.State()
   114  		if err != nil {
   115  			return nil, err
   116  		}
   117  
   118  		nextValidators := ep.Validators.Copy()
   119  		err = epoch.DryRunUpdateEpochValidatorSet(state, nextValidators, nextEp.GetEpochValidatorVoteSet())
   120  		if err != nil {
   121  			return nil, err
   122  		}
   123  
   124  		validators := make([]*ntcTypes.EpochValidatorForConsole, 0, len(nextValidators.Validators))
   125  		for _, val := range nextValidators.Validators {
   126  			var pkstring string
   127  			if val.PubKey != nil {
   128  				pkstring = val.PubKey.KeyString()
   129  			}
   130  			validators = append(validators, &ntcTypes.EpochValidatorForConsole{
   131  				Address:        common.BytesToAddress(val.Address).String(),
   132  				PubKey:         pkstring,
   133  				Amount:         (*hexutil.Big)(val.VotingPower),
   134  				RemainingEpoch: hexutil.Uint64(val.RemainingEpoch),
   135  			})
   136  		}
   137  
   138  		return validators, nil
   139  	}
   140  }
   141  
   142  // CreateValidator
   143  func (api *API) CreateValidator(from common.Address) (*ntcTypes.PrivV, error) {
   144  	validator := ntcTypes.GenPrivValidatorKey(from)
   145  	privV := &ntcTypes.PrivV{
   146  		Address: validator.Address.String(),
   147  		PubKey:  validator.PubKey,
   148  		PrivKey: validator.PrivKey,
   149  	}
   150  	return privV, nil
   151  }
   152  
   153  // decode extra data
   154  func (api *API) DecodeExtraData(extra string) (extraApi *ntcTypes.NeatConExtraApi, err error) {
   155  	ncExtra, err := ntcTypes.DecodeExtraData(extra)
   156  	if err != nil {
   157  		return nil, err
   158  	}
   159  	extraApi = &ntcTypes.NeatConExtraApi{
   160  		ChainID:         ncExtra.ChainID,
   161  		Height:          hexutil.Uint64(ncExtra.Height),
   162  		Time:            ncExtra.Time,
   163  		NeedToSave:      ncExtra.NeedToSave,
   164  		NeedToBroadcast: ncExtra.NeedToBroadcast,
   165  		EpochNumber:     hexutil.Uint64(ncExtra.EpochNumber),
   166  		SeenCommitHash:  hexutil.Encode(ncExtra.SeenCommitHash),
   167  		ValidatorsHash:  hexutil.Encode(ncExtra.ValidatorsHash),
   168  		SeenCommit: &ntcTypes.CommitApi{
   169  			BlockID: ntcTypes.BlockIDApi{
   170  				Hash: hexutil.Encode(ncExtra.SeenCommit.BlockID.Hash),
   171  				PartsHeader: ntcTypes.PartSetHeaderApi{
   172  					Total: hexutil.Uint64(ncExtra.SeenCommit.BlockID.PartsHeader.Total),
   173  					Hash:  hexutil.Encode(ncExtra.SeenCommit.BlockID.PartsHeader.Hash),
   174  				},
   175  			},
   176  			Height:   hexutil.Uint64(ncExtra.SeenCommit.Height),
   177  			Round:    ncExtra.SeenCommit.Round,
   178  			SignAggr: ncExtra.SeenCommit.SignAggr,
   179  			BitArray: ncExtra.SeenCommit.BitArray,
   180  		},
   181  		EpochBytes: ncExtra.EpochBytes,
   182  	}
   183  	return extraApi, nil
   184  }
   185  
   186  // get consensus publickey of the block
   187  func (api *API) GetConsensusPublicKey(extra string) ([]string, error) {
   188  	ncExtra, err := ntcTypes.DecodeExtraData(extra)
   189  	if err != nil {
   190  		return nil, err
   191  	}
   192  
   193  	//fmt.Printf("GetConsensusPublicKey ncExtra %v\n", ncExtra)
   194  	number := uint64(ncExtra.EpochNumber)
   195  	var resultEpoch *epoch.Epoch
   196  	curEpoch := api.neatcon.core.consensusState.Epoch
   197  	if number < 0 || number > curEpoch.Number {
   198  		return nil, errors.New("epoch number out of range")
   199  	}
   200  
   201  	if number == curEpoch.Number {
   202  		resultEpoch = curEpoch
   203  	} else {
   204  		resultEpoch = epoch.LoadOneEpoch(curEpoch.GetDB(), number, nil)
   205  	}
   206  
   207  	//fmt.Printf("GetConsensusPublicKey result epoch %v\n", resultEpoch)
   208  	validatorSet := resultEpoch.Validators
   209  	//fmt.Printf("GetConsensusPublicKey validatorset %v\n", validatorSet)
   210  
   211  	aggr, err := validatorSet.GetAggrPubKeyAndAddress(ncExtra.SeenCommit.BitArray)
   212  	if err != nil {
   213  		return nil, err
   214  	}
   215  
   216  	var pubkeys []string
   217  	if len(aggr.PublicKeys) > 0 {
   218  		for _, v := range aggr.PublicKeys {
   219  			if v != "" {
   220  				pubkeys = append(pubkeys, v)
   221  			}
   222  		}
   223  	}
   224  
   225  	return pubkeys, nil
   226  }
   227  
   228  func (api *API) GetVoteHash(from common.Address, pubkey crypto.BLSPubKey, amount *hexutil.Big, salt string) common.Hash {
   229  	byteData := [][]byte{
   230  		from.Bytes(),
   231  		pubkey.Bytes(),
   232  		(*big.Int)(amount).Bytes(),
   233  		[]byte(salt),
   234  	}
   235  	return neatCrypto.Keccak256Hash(ConcatCopyPreAllocate(byteData))
   236  }
   237  
   238  func (api *API) GetValidatorStatus(from common.Address) (*ntcTypes.ValidatorStatus, error) {
   239  	state, err := api.chain.State()
   240  	if state == nil || err != nil {
   241  		return nil, err
   242  	}
   243  	status := &ntcTypes.ValidatorStatus{
   244  		IsForbidden: state.GetOrNewStateObject(from).IsForbidden(),
   245  	}
   246  
   247  	return status, nil
   248  }
   249  
   250  func (api *API) GetCandidateList() (*ntcTypes.CandidateApi, error) {
   251  	state, err := api.chain.State()
   252  
   253  	if state == nil || err != nil {
   254  		return nil, err
   255  	}
   256  
   257  	candidateList := make([]string, 0)
   258  	candidateSet := state.GetCandidateSet()
   259  	fmt.Printf("candidate set %v", candidateSet)
   260  	for addr := range candidateSet {
   261  		candidateList = append(candidateList, addr.String())
   262  	}
   263  
   264  	candidates := &ntcTypes.CandidateApi{
   265  		CandidateList: candidateList,
   266  	}
   267  
   268  	return candidates, nil
   269  }
   270  
   271  func (api *API) GetForbiddenList() (*ntcTypes.ForbiddenApi, error) {
   272  	state, err := api.chain.State()
   273  
   274  	if state == nil || err != nil {
   275  		return nil, err
   276  	}
   277  
   278  	forbiddenList := make([]string, 0)
   279  	forbiddenSet := state.GetForbiddenSet()
   280  	fmt.Printf("forbidden set %v", forbiddenSet)
   281  	for addr := range forbiddenSet {
   282  		forbiddenList = append(forbiddenList, addr.String())
   283  	}
   284  
   285  	forbiddenAddresses := &ntcTypes.ForbiddenApi{
   286  		ForbiddenList: forbiddenList,
   287  	}
   288  
   289  	return forbiddenAddresses, nil
   290  }