github.com/adoriasoft/tendermint@v0.34.0-dev1.0.20200722151356-96d84601a75a/types/protobuf.go (about)

     1  package types
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"time"
     7  
     8  	abci "github.com/tendermint/tendermint/abci/types"
     9  	"github.com/tendermint/tendermint/crypto"
    10  	"github.com/tendermint/tendermint/crypto/ed25519"
    11  	cryptoenc "github.com/tendermint/tendermint/crypto/encoding"
    12  	tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
    13  )
    14  
    15  //-------------------------------------------------------
    16  // Use strings to distinguish types in ABCI messages
    17  
    18  const (
    19  	ABCIEvidenceTypeDuplicateVote    = "duplicate/vote"
    20  	ABCIEvidenceTypePhantom          = "phantom"
    21  	ABCIEvidenceTypeLunatic          = "lunatic"
    22  	ABCIEvidenceTypePotentialAmnesia = "potential_amnesia"
    23  	ABCIEvidenceTypeMock             = "mock/evidence"
    24  )
    25  
    26  const (
    27  	ABCIPubKeyTypeEd25519 = "ed25519"
    28  )
    29  
    30  // TODO: Make non-global by allowing for registration of more pubkey types
    31  
    32  var ABCIPubKeyTypesToNames = map[string]string{
    33  	ABCIPubKeyTypeEd25519: ed25519.PubKeyName,
    34  }
    35  
    36  //-------------------------------------------------------
    37  
    38  // TM2PB is used for converting Tendermint ABCI to protobuf ABCI.
    39  // UNSTABLE
    40  var TM2PB = tm2pb{}
    41  
    42  type tm2pb struct{}
    43  
    44  func (tm2pb) Header(header *Header) tmproto.Header {
    45  	return tmproto.Header{
    46  		Version: header.Version,
    47  		ChainID: header.ChainID,
    48  		Height:  header.Height,
    49  		Time:    header.Time,
    50  
    51  		LastBlockId: header.LastBlockID.ToProto(),
    52  
    53  		LastCommitHash: header.LastCommitHash,
    54  		DataHash:       header.DataHash,
    55  
    56  		ValidatorsHash:     header.ValidatorsHash,
    57  		NextValidatorsHash: header.NextValidatorsHash,
    58  		ConsensusHash:      header.ConsensusHash,
    59  		AppHash:            header.AppHash,
    60  		LastResultsHash:    header.LastResultsHash,
    61  
    62  		EvidenceHash:    header.EvidenceHash,
    63  		ProposerAddress: header.ProposerAddress,
    64  	}
    65  }
    66  
    67  func (tm2pb) Validator(val *Validator) abci.Validator {
    68  	return abci.Validator{
    69  		Address: val.PubKey.Address(),
    70  		Power:   val.VotingPower,
    71  	}
    72  }
    73  
    74  func (tm2pb) BlockID(blockID BlockID) tmproto.BlockID {
    75  	return tmproto.BlockID{
    76  		Hash:          blockID.Hash,
    77  		PartSetHeader: TM2PB.PartSetHeader(blockID.PartSetHeader),
    78  	}
    79  }
    80  
    81  func (tm2pb) PartSetHeader(header PartSetHeader) tmproto.PartSetHeader {
    82  	return tmproto.PartSetHeader{
    83  		Total: header.Total,
    84  		Hash:  header.Hash,
    85  	}
    86  }
    87  
    88  // XXX: panics on unknown pubkey type
    89  func (tm2pb) ValidatorUpdate(val *Validator) abci.ValidatorUpdate {
    90  	pk, err := cryptoenc.PubKeyToProto(val.PubKey)
    91  	if err != nil {
    92  		panic(err)
    93  	}
    94  	return abci.ValidatorUpdate{
    95  		PubKey: pk,
    96  		Power:  val.VotingPower,
    97  	}
    98  }
    99  
   100  // XXX: panics on nil or unknown pubkey type
   101  func (tm2pb) ValidatorUpdates(vals *ValidatorSet) []abci.ValidatorUpdate {
   102  	validators := make([]abci.ValidatorUpdate, vals.Size())
   103  	for i, val := range vals.Validators {
   104  		validators[i] = TM2PB.ValidatorUpdate(val)
   105  	}
   106  	return validators
   107  }
   108  
   109  func (tm2pb) ConsensusParams(params *tmproto.ConsensusParams) *abci.ConsensusParams {
   110  	return &abci.ConsensusParams{
   111  		Block: &abci.BlockParams{
   112  			MaxBytes: params.Block.MaxBytes,
   113  			MaxGas:   params.Block.MaxGas,
   114  		},
   115  		Evidence:  &params.Evidence,
   116  		Validator: &params.Validator,
   117  	}
   118  }
   119  
   120  // ABCI Evidence includes information from the past that's not included in the evidence itself
   121  // so Evidence types stays compact.
   122  // XXX: panics on nil or unknown pubkey type
   123  func (tm2pb) Evidence(ev Evidence, valSet *ValidatorSet, evTime time.Time) abci.Evidence {
   124  	addr := ev.Address()
   125  	_, val := valSet.GetByAddress(addr)
   126  	if val == nil {
   127  		// should already have checked this
   128  		panic(val)
   129  	}
   130  
   131  	// set type
   132  	var evType string
   133  	switch ev.(type) {
   134  	case *DuplicateVoteEvidence:
   135  		evType = ABCIEvidenceTypeDuplicateVote
   136  	case *PhantomValidatorEvidence:
   137  		evType = ABCIEvidenceTypePhantom
   138  	case *LunaticValidatorEvidence:
   139  		evType = ABCIEvidenceTypeLunatic
   140  	case *PotentialAmnesiaEvidence:
   141  		evType = ABCIEvidenceTypePotentialAmnesia
   142  	default:
   143  		panic(fmt.Sprintf("Unknown evidence type: %v %v", ev, reflect.TypeOf(ev)))
   144  	}
   145  
   146  	return abci.Evidence{
   147  		Type:             evType,
   148  		Validator:        TM2PB.Validator(val),
   149  		Height:           ev.Height(),
   150  		Time:             evTime,
   151  		TotalVotingPower: valSet.TotalVotingPower(),
   152  	}
   153  }
   154  
   155  // XXX: panics on nil or unknown pubkey type
   156  func (tm2pb) NewValidatorUpdate(pubkey crypto.PubKey, power int64) abci.ValidatorUpdate {
   157  	pubkeyABCI, err := cryptoenc.PubKeyToProto(pubkey)
   158  	if err != nil {
   159  		panic(err)
   160  	}
   161  	return abci.ValidatorUpdate{
   162  		PubKey: pubkeyABCI,
   163  		Power:  power,
   164  	}
   165  }
   166  
   167  //----------------------------------------------------------------------------
   168  
   169  // PB2TM is used for converting protobuf ABCI to Tendermint ABCI.
   170  // UNSTABLE
   171  var PB2TM = pb2tm{}
   172  
   173  type pb2tm struct{}
   174  
   175  func (pb2tm) ValidatorUpdates(vals []abci.ValidatorUpdate) ([]*Validator, error) {
   176  	tmVals := make([]*Validator, len(vals))
   177  	for i, v := range vals {
   178  		pub, err := cryptoenc.PubKeyFromProto(v.PubKey)
   179  		if err != nil {
   180  			return nil, err
   181  		}
   182  		tmVals[i] = NewValidator(pub, v.Power)
   183  	}
   184  	return tmVals, nil
   185  }