github.com/franono/tendermint@v0.32.2-0.20200527150959-749313264ce9/types/protobuf.go (about)

     1  package types
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"time"
     7  
     8  	abci "github.com/franono/tendermint/abci/types"
     9  	"github.com/franono/tendermint/crypto"
    10  	"github.com/franono/tendermint/crypto/ed25519"
    11  	"github.com/franono/tendermint/crypto/secp256k1"
    12  	"github.com/franono/tendermint/crypto/sr25519"
    13  )
    14  
    15  //-------------------------------------------------------
    16  // Use strings to distinguish types in ABCI messages
    17  
    18  const (
    19  	ABCIEvidenceTypeDuplicateVote = "duplicate/vote"
    20  	ABCIEvidenceTypeMock          = "mock/evidence"
    21  )
    22  
    23  const (
    24  	ABCIPubKeyTypeEd25519   = "ed25519"
    25  	ABCIPubKeyTypeSr25519   = "sr25519"
    26  	ABCIPubKeyTypeSecp256k1 = "secp256k1"
    27  )
    28  
    29  // TODO: Make non-global by allowing for registration of more pubkey types
    30  
    31  var ABCIPubKeyTypesToAminoNames = map[string]string{
    32  	ABCIPubKeyTypeEd25519:   ed25519.PubKeyAminoName,
    33  	ABCIPubKeyTypeSr25519:   sr25519.PubKeyAminoName,
    34  	ABCIPubKeyTypeSecp256k1: secp256k1.PubKeyAminoName,
    35  }
    36  
    37  //-------------------------------------------------------
    38  
    39  // TM2PB is used for converting Tendermint ABCI to protobuf ABCI.
    40  // UNSTABLE
    41  var TM2PB = tm2pb{}
    42  
    43  type tm2pb struct{}
    44  
    45  func (tm2pb) Header(header *Header) abci.Header {
    46  	return abci.Header{
    47  		Version: abci.Version{
    48  			Block: header.Version.Block.Uint64(),
    49  			App:   header.Version.App.Uint64(),
    50  		},
    51  		ChainID: header.ChainID,
    52  		Height:  header.Height,
    53  		Time:    header.Time,
    54  
    55  		LastBlockId: TM2PB.BlockID(header.LastBlockID),
    56  
    57  		LastCommitHash: header.LastCommitHash,
    58  		DataHash:       header.DataHash,
    59  
    60  		ValidatorsHash:     header.ValidatorsHash,
    61  		NextValidatorsHash: header.NextValidatorsHash,
    62  		ConsensusHash:      header.ConsensusHash,
    63  		AppHash:            header.AppHash,
    64  		LastResultsHash:    header.LastResultsHash,
    65  
    66  		EvidenceHash:    header.EvidenceHash,
    67  		ProposerAddress: header.ProposerAddress,
    68  	}
    69  }
    70  
    71  func (tm2pb) Validator(val *Validator) abci.Validator {
    72  	return abci.Validator{
    73  		Address: val.PubKey.Address(),
    74  		Power:   val.VotingPower,
    75  	}
    76  }
    77  
    78  func (tm2pb) BlockID(blockID BlockID) abci.BlockID {
    79  	return abci.BlockID{
    80  		Hash:        blockID.Hash,
    81  		PartsHeader: TM2PB.PartSetHeader(blockID.PartsHeader),
    82  	}
    83  }
    84  
    85  func (tm2pb) PartSetHeader(header PartSetHeader) abci.PartSetHeader {
    86  	return abci.PartSetHeader{
    87  		Total: int32(header.Total),
    88  		Hash:  header.Hash,
    89  	}
    90  }
    91  
    92  // XXX: panics on unknown pubkey type
    93  func (tm2pb) ValidatorUpdate(val *Validator) abci.ValidatorUpdate {
    94  	return abci.ValidatorUpdate{
    95  		PubKey: TM2PB.PubKey(val.PubKey),
    96  		Power:  val.VotingPower,
    97  	}
    98  }
    99  
   100  // XXX: panics on nil or unknown pubkey type
   101  // TODO: add cases when new pubkey types are added to crypto
   102  func (tm2pb) PubKey(pubKey crypto.PubKey) abci.PubKey {
   103  	switch pk := pubKey.(type) {
   104  	case ed25519.PubKeyEd25519:
   105  		return abci.PubKey{
   106  			Type: ABCIPubKeyTypeEd25519,
   107  			Data: pk[:],
   108  		}
   109  	case sr25519.PubKeySr25519:
   110  		return abci.PubKey{
   111  			Type: ABCIPubKeyTypeSr25519,
   112  			Data: pk[:],
   113  		}
   114  	case secp256k1.PubKeySecp256k1:
   115  		return abci.PubKey{
   116  			Type: ABCIPubKeyTypeSecp256k1,
   117  			Data: pk[:],
   118  		}
   119  	default:
   120  		panic(fmt.Sprintf("unknown pubkey type: %v %v", pubKey, reflect.TypeOf(pubKey)))
   121  	}
   122  }
   123  
   124  // XXX: panics on nil or unknown pubkey type
   125  func (tm2pb) ValidatorUpdates(vals *ValidatorSet) []abci.ValidatorUpdate {
   126  	validators := make([]abci.ValidatorUpdate, vals.Size())
   127  	for i, val := range vals.Validators {
   128  		validators[i] = TM2PB.ValidatorUpdate(val)
   129  	}
   130  	return validators
   131  }
   132  
   133  func (tm2pb) ConsensusParams(params *ConsensusParams) *abci.ConsensusParams {
   134  	return &abci.ConsensusParams{
   135  		Block: &abci.BlockParams{
   136  			MaxBytes: params.Block.MaxBytes,
   137  			MaxGas:   params.Block.MaxGas,
   138  		},
   139  		Evidence: &abci.EvidenceParams{
   140  			MaxAgeNumBlocks: params.Evidence.MaxAgeNumBlocks,
   141  			MaxAgeDuration:  params.Evidence.MaxAgeDuration,
   142  			MaxNum:          params.Evidence.MaxNum,
   143  		},
   144  		Validator: &abci.ValidatorParams{
   145  			PubKeyTypes: params.Validator.PubKeyTypes,
   146  		},
   147  	}
   148  }
   149  
   150  // ABCI Evidence includes information from the past that's not included in the evidence itself
   151  // so Evidence types stays compact.
   152  // XXX: panics on nil or unknown pubkey type
   153  func (tm2pb) Evidence(ev Evidence, valSet *ValidatorSet, evTime time.Time) abci.Evidence {
   154  	addr := ev.Address()
   155  	_, val := valSet.GetByAddress(addr)
   156  	if val == nil {
   157  		// should already have checked this
   158  		panic(val)
   159  	}
   160  
   161  	// set type
   162  	var evType string
   163  	switch ev.(type) {
   164  	case *DuplicateVoteEvidence:
   165  		evType = ABCIEvidenceTypeDuplicateVote
   166  	case *PhantomValidatorEvidence:
   167  		evType = "phantom"
   168  	case *LunaticValidatorEvidence:
   169  		evType = "lunatic"
   170  	case *PotentialAmnesiaEvidence:
   171  		evType = "potential_amnesia"
   172  	case MockEvidence:
   173  		// XXX: not great to have test types in production paths ...
   174  		evType = ABCIEvidenceTypeMock
   175  	default:
   176  		panic(fmt.Sprintf("Unknown evidence type: %v %v", ev, reflect.TypeOf(ev)))
   177  	}
   178  
   179  	return abci.Evidence{
   180  		Type:             evType,
   181  		Validator:        TM2PB.Validator(val),
   182  		Height:           ev.Height(),
   183  		Time:             evTime,
   184  		TotalVotingPower: valSet.TotalVotingPower(),
   185  	}
   186  }
   187  
   188  // XXX: panics on nil or unknown pubkey type
   189  func (tm2pb) NewValidatorUpdate(pubkey crypto.PubKey, power int64) abci.ValidatorUpdate {
   190  	pubkeyABCI := TM2PB.PubKey(pubkey)
   191  	return abci.ValidatorUpdate{
   192  		PubKey: pubkeyABCI,
   193  		Power:  power,
   194  	}
   195  }
   196  
   197  //----------------------------------------------------------------------------
   198  
   199  // PB2TM is used for converting protobuf ABCI to Tendermint ABCI.
   200  // UNSTABLE
   201  var PB2TM = pb2tm{}
   202  
   203  type pb2tm struct{}
   204  
   205  func (pb2tm) PubKey(pubKey abci.PubKey) (crypto.PubKey, error) {
   206  	switch pubKey.Type {
   207  	case ABCIPubKeyTypeEd25519:
   208  		if len(pubKey.Data) != ed25519.PubKeyEd25519Size {
   209  			return nil, fmt.Errorf("invalid size for PubKeyEd25519. Got %d, expected %d",
   210  				len(pubKey.Data), ed25519.PubKeyEd25519Size)
   211  		}
   212  		var pk ed25519.PubKeyEd25519
   213  		copy(pk[:], pubKey.Data)
   214  		return pk, nil
   215  	case ABCIPubKeyTypeSr25519:
   216  		if len(pubKey.Data) != sr25519.PubKeySr25519Size {
   217  			return nil, fmt.Errorf("invalid size for PubKeySr25519. Got %d, expected %d",
   218  				len(pubKey.Data), sr25519.PubKeySr25519Size)
   219  		}
   220  		var pk sr25519.PubKeySr25519
   221  		copy(pk[:], pubKey.Data)
   222  		return pk, nil
   223  	case ABCIPubKeyTypeSecp256k1:
   224  		if len(pubKey.Data) != secp256k1.PubKeySecp256k1Size {
   225  			return nil, fmt.Errorf("invalid size for PubKeySecp256k1. Got %d, expected %d",
   226  				len(pubKey.Data), secp256k1.PubKeySecp256k1Size)
   227  		}
   228  		var pk secp256k1.PubKeySecp256k1
   229  		copy(pk[:], pubKey.Data)
   230  		return pk, nil
   231  	default:
   232  		return nil, fmt.Errorf("unknown pubkey type %v", pubKey.Type)
   233  	}
   234  }
   235  
   236  func (pb2tm) ValidatorUpdates(vals []abci.ValidatorUpdate) ([]*Validator, error) {
   237  	tmVals := make([]*Validator, len(vals))
   238  	for i, v := range vals {
   239  		pub, err := PB2TM.PubKey(v.PubKey)
   240  		if err != nil {
   241  			return nil, err
   242  		}
   243  		tmVals[i] = NewValidator(pub, v.Power)
   244  	}
   245  	return tmVals, nil
   246  }