github.com/okex/exchain@v1.8.0/libs/tendermint/types/protobuf.go (about) 1 package types 2 3 import ( 4 "fmt" 5 "reflect" 6 "time" 7 8 abci "github.com/okex/exchain/libs/tendermint/abci/types" 9 "github.com/okex/exchain/libs/tendermint/crypto" 10 "github.com/okex/exchain/libs/tendermint/crypto/ed25519" 11 "github.com/okex/exchain/libs/tendermint/crypto/secp256k1" 12 "github.com/okex/exchain/libs/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 }, 143 Validator: &abci.ValidatorParams{ 144 PubKeyTypes: params.Validator.PubKeyTypes, 145 }, 146 } 147 } 148 149 // ABCI Evidence includes information from the past that's not included in the evidence itself 150 // so Evidence types stays compact. 151 // XXX: panics on nil or unknown pubkey type 152 func (tm2pb) Evidence(ev Evidence, valSet *ValidatorSet, evTime time.Time) abci.Evidence { 153 _, val := valSet.GetByAddress(ev.Address()) 154 if val == nil { 155 // should already have checked this 156 panic(val) 157 } 158 159 // set type 160 var evType string 161 switch ev.(type) { 162 case *DuplicateVoteEvidence: 163 evType = ABCIEvidenceTypeDuplicateVote 164 case MockEvidence: 165 // XXX: not great to have test types in production paths ... 166 evType = ABCIEvidenceTypeMock 167 default: 168 panic(fmt.Sprintf("Unknown evidence type: %v %v", ev, reflect.TypeOf(ev))) 169 } 170 171 return abci.Evidence{ 172 Type: evType, 173 Validator: TM2PB.Validator(val), 174 Height: ev.Height(), 175 Time: evTime, 176 TotalVotingPower: valSet.TotalVotingPower(), 177 } 178 } 179 180 // XXX: panics on nil or unknown pubkey type 181 func (tm2pb) NewValidatorUpdate(pubkey crypto.PubKey, power int64) abci.ValidatorUpdate { 182 pubkeyABCI := TM2PB.PubKey(pubkey) 183 return abci.ValidatorUpdate{ 184 PubKey: pubkeyABCI, 185 Power: power, 186 } 187 } 188 189 //---------------------------------------------------------------------------- 190 191 // PB2TM is used for converting protobuf ABCI to Tendermint ABCI. 192 // UNSTABLE 193 var PB2TM = pb2tm{} 194 195 type pb2tm struct{} 196 197 func (pb2tm) PubKey(pubKey abci.PubKey) (crypto.PubKey, error) { 198 switch pubKey.Type { 199 case ABCIPubKeyTypeEd25519: 200 if len(pubKey.Data) != ed25519.PubKeyEd25519Size { 201 return nil, fmt.Errorf("invalid size for PubKeyEd25519. Got %d, expected %d", 202 len(pubKey.Data), ed25519.PubKeyEd25519Size) 203 } 204 var pk ed25519.PubKeyEd25519 205 copy(pk[:], pubKey.Data) 206 return pk, nil 207 case ABCIPubKeyTypeSr25519: 208 if len(pubKey.Data) != sr25519.PubKeySr25519Size { 209 return nil, fmt.Errorf("invalid size for PubKeySr25519. Got %d, expected %d", 210 len(pubKey.Data), sr25519.PubKeySr25519Size) 211 } 212 var pk sr25519.PubKeySr25519 213 copy(pk[:], pubKey.Data) 214 return pk, nil 215 case ABCIPubKeyTypeSecp256k1: 216 if len(pubKey.Data) != secp256k1.PubKeySecp256k1Size { 217 return nil, fmt.Errorf("invalid size for PubKeySecp256k1. Got %d, expected %d", 218 len(pubKey.Data), secp256k1.PubKeySecp256k1Size) 219 } 220 var pk secp256k1.PubKeySecp256k1 221 copy(pk[:], pubKey.Data) 222 return pk, nil 223 default: 224 return nil, fmt.Errorf("unknown pubkey type %v", pubKey.Type) 225 } 226 } 227 228 func (pb2tm) ValidatorUpdates(vals []abci.ValidatorUpdate) ([]*Validator, error) { 229 tmVals := make([]*Validator, len(vals)) 230 for i, v := range vals { 231 pub, err := PB2TM.PubKey(v.PubKey) 232 if err != nil { 233 return nil, err 234 } 235 tmVals[i] = NewValidator(pub, v.Power) 236 } 237 return tmVals, nil 238 }