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