github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/consense/dpoa/paxos.go (about) 1 package dpoa 2 3 import ( 4 "encoding/json" 5 "math/big" 6 "time" 7 8 //"github.com/sixexorg/magnetic-ring/core/types" 9 "github.com/sixexorg/magnetic-ring/account" 10 "github.com/sixexorg/magnetic-ring/consense/dpoa/comm" 11 12 //"github.com/sixexorg/magnetic-ring/core/signature" 13 //"github.com/sixexorg/magnetic-ring/consensus/vbft/config" 14 "github.com/sixexorg/magnetic-ring/log" 15 16 comm2 "github.com/sixexorg/magnetic-ring/common" 17 "github.com/sixexorg/magnetic-ring/crypto" 18 ) 19 20 // Paxos instance 21 type Paxos struct { 22 index int 23 totalGas int 24 publicKey string 25 active bool // active leader 26 ballot comm.Ballot // highest ballot number 27 ab comm.Ballot // highest ballot number 28 av []byte 29 quorumPhase1 *comm.Quorum // phase 1 quorum 30 quorumPhase2 *comm.Quorum // phase 2 quorum 31 candidateBlock *comm.Block 32 dataPhase1 *comm.P1a // 33 dataPhase2 *comm.P2a 34 done bool 35 account account.Account 36 sendCh chan interface{} 37 partiCfg *comm.ParticiConfig 38 sigsMap map[uint16][]byte 39 } 40 41 func NewPaxos(publicKey string, acc account.Account, sendCh chan interface{}) *Paxos { 42 return &Paxos{ 43 sendCh: sendCh, 44 publicKey: publicKey, 45 account: acc, 46 } 47 } 48 49 func (p *Paxos) ConsensProcess(block *comm.Block, totalGas int, partiCfg *comm.ParticiConfig, stopCh chan struct{}) { 50 51 log.Info("func dpoa paxos ConsensProcess", "blockHeight", block.Block.Header.Height, "txlen", block.Block.Transactions.Len()) 52 53 //fmt.Println("============>>>>>>>>>ConsensProcess", block.GetProposer(), block.GetBlockNum(), block.GetViews(), block.Block.Sigs == nil) 54 p.partiCfg = partiCfg 55 p.candidateBlock = block 56 p.totalGas = totalGas 57 58 { 59 mm, _ := p.candidateBlock.Serialize() 60 bk := &comm.Block{} 61 bk.Deserialize(mm) 62 63 //log.Info("ConsensProcess print info bk", "block.txs.len", bk.Block.Transactions.Len()) 64 65 //fmt.Println("11111111111============>>>>>>>>>ConsensProcess", bk.GetProposer(), bk.GetBlockNum(), bk.GetViews(), bk.Block.Sigs == nil) 66 } 67 68 p.ballot = comm.Ballot(0) 69 p.quorumPhase1 = comm.NewQuorum(len(p.partiCfg.ProcNodes)) 70 p.quorumPhase2 = comm.NewQuorum(len(p.partiCfg.ProcNodes)) 71 p.index, _ = GetIndex(p.partiCfg.PartiRaw, p.publicKey) 72 p.sigsMap = make(map[uint16][]byte) 73 p.P1a() 74 75 for { 76 select { 77 case <-time.After(time.Second * 2): 78 if p.done { 79 return 80 } 81 82 p.P1a() 83 log.Info("func dpoa paxos ConsensProcess") 84 case <-stopCh: 85 p.clean() 86 return 87 } 88 } 89 } 90 91 // P1a starts phase 1 prepare 92 func (p *Paxos) P1a() { 93 p.active = false 94 p.ballot.Next(comm.NewID(p.totalGas, p.index)) 95 p.quorumPhase1.Reset() 96 p.quorumPhase2.Reset() 97 p.quorumPhase1.ACK(comm.NewID(0, p.index)) // 98 //fmt.Println("=======================>>>>>>>>>>>>>>>>>>>>>>>>>>P1a", p.index, p.ballot.String(), p.candidateBlock.Block.Hash()) 99 p1a := comm.P1a{Ballot: p.ballot, ID: uint32(p.index), BlockNumber: p.partiCfg.BlkNum, View: p.partiCfg.View, TotalGas: big.NewInt(int64(p.totalGas))} 100 bp1a, _ := json.Marshal(p1a) 101 sig, err := p.account.Sign(bp1a) 102 103 if err != nil { 104 log.Error("sign paxos 105 occured error", "error", err) 105 return 106 } 107 log.Info("func dpoa paxos P1a sendCh msg") 108 p.sendCh <- &SendMsgEvent{ToPeer: comm.BroadCast, Msg: &comm.PrepareMsg{Msg: p1a, Sig: sig}} 109 } 110 111 func (p *Paxos) p1aCheck(m comm.P1a) error { 112 113 114 return nil 115 } 116 117 // HandleP1a handles P1a message 118 func (p *Paxos) HandleP1a(m comm.P1a) { 119 //fmt.Printf("success--------------->>>>>>>>>>>>>>>>>>>>>>>>>>HandleP1a\n", m) 120 /* 121 Serial number check 122 Verification signature 123 Height check 124 View check 125 Round check 126 Txhash check 127 */ 128 if p.done { 129 if m.Ballot > p.ballot { // accept 130 if p.p1aCheck(m) != nil { 131 return 132 } 133 134 m := comm.P1b{ 135 Ballot: m.Ballot, 136 ID: uint32(p.index), 137 Ab: p.ab, 138 Av: p.av, 139 BlockNumber: p.partiCfg.BlkNum, 140 View: p.partiCfg.View, 141 } 142 b, _ := json.Marshal(&m) 143 sig, err := p.account.Sign(b) 144 145 if err != nil { 146 log.Error("sign paxos 160 occured error", "error", err) 147 return 148 } 149 150 p.sendCh <- &SendMsgEvent{ToPeer: comm.BroadCast, Msg: &comm.PromiseMsg{Msg: m, Sig: sig}} 151 } 152 return 153 } 154 155 if p.p1aCheck(m) != nil { 156 return 157 } 158 159 if m.Ballot > p.ballot { // accept 160 p.ballot = m.Ballot 161 p.active = false 162 if len(p.av) == 0 { 163 p.dataPhase1 = &m 164 } 165 m := comm.P1b{ 166 Ballot: p.ballot, 167 ID: uint32(p.index), 168 Ab: p.ab, 169 Av: p.av, 170 BlockNumber: p.partiCfg.BlkNum, 171 View: p.partiCfg.View, 172 } 173 b, _ := json.Marshal(&m) 174 sig, err := p.account.Sign(b) 175 if err != nil { 176 log.Error("sign pasos190 occured error", "error", err) 177 return 178 } 179 p.sendCh <- &SendMsgEvent{ToPeer: comm.BroadCast, Msg: &comm.PromiseMsg{Msg: m, Sig: sig}} 180 } 181 return 182 } 183 184 // HandleP1b handles P1b message 185 func (p *Paxos) HandleP1b(m comm.P1b) { 186 //fmt.Println("==================>>>>>>>>>>>>>>>>>>>>>>>>>>HandleP1b", m.ID, m.Ballot.String(), p.ballot.String(), p.index, p.ab, p.done) 187 //fmt.Println("==================>>>>>>>>>>>>>>>>>>>>>>>>>>HandleP1bm", m) 188 if p.done || m.Ballot < p.ballot { 189 return 190 } 191 192 if m.Ab > p.ab && len(m.Av) > 0 { 193 p.ab = m.Ab 194 p.av = m.Av 195 } 196 197 if m.Ballot > p.ballot { 198 p.ballot = m.Ballot 199 p.active = false // not necessary 200 } 201 202 if m.Ballot.ID().Node() == p.index && m.Ballot == p.ballot { 203 p.quorumPhase1.ACK(comm.NewID(0, int(m.ID))) 204 if p.quorumPhase1.Q1() { 205 p.active = true 206 //p.quorump2.Reset() 207 p.quorumPhase2.ACK(comm.NewID(0, p.index)) 208 //fmt.Printf("success---------------===>>>>>>>>>>>>>>>>>>>>>>>>>>HandleP1b lenth %v\n", len(p.av)) 209 if len(p.av) == 0 { 210 p.ab = p.ballot 211 p.av, _ = p.candidateBlock.Serialize() 212 213 tmpblock := new(comm.Block) 214 215 err := tmpblock.Deserialize(p.av) 216 if err != nil { 217 log.Error("tmpblock Deserialize occured err", "error", err) 218 } else { 219 log.Debug("block", "height", tmpblock.Block.Header.Height, "block", tmpblock, "block.txlen", tmpblock.Block.Transactions.Len()) 220 } 221 222 log.Info("func dpoa HandleP1b", "txlen", p.candidateBlock.Block.Transactions.Len()) 223 } 224 m := comm.P2a{ 225 Ballot: p.ballot, 226 Av: p.av, 227 BlockNumber: p.partiCfg.BlkNum, 228 View: p.partiCfg.View, 229 ID: uint32(p.index), 230 } 231 232 b, _ := json.Marshal(&m) 233 { //test by rennbon 234 m2 := &comm.P2a{} 235 err := json.Unmarshal(b, m2) 236 if err != nil { 237 bl := &comm.Block{} 238 err = bl.Deserialize(m2.Av) 239 if err != nil { 240 log.Info("func dpoa paxos HandleP1b", "blockHeight", bl.Block.Header.Height, "txlen", bl.Block.Transactions.Len()) 241 } else { 242 log.Info("func dpoa paxos HandleP1b", "error", err) 243 } 244 245 } 246 } 247 sig, err := p.account.Sign(b) 248 if err != nil { 249 log.Error("sign paxos 264 occured error", "error", err) 250 return 251 } 252 p.sendCh <- &SendMsgEvent{ToPeer: comm.BroadCast, Msg: &comm.ProposerMsg{Msg: m, Sig: sig}} 253 } 254 } 255 } 256 257 func (p *Paxos) p2aCheck(m comm.P2a) error { 258 259 return nil 260 } 261 262 func (p *Paxos) HandleP2a(m comm.P2a) { 263 //fmt.Printf("===================->>>>>>>>>>>>>>>>>HandleP2a\n", p.index, p.done, m.Ballot == p.ballot, m.Ballot.ID().Node() == p.index) 264 if p.done { 265 if m.Ballot > p.ballot { // accept 266 if p.p2aCheck(m) != nil { 267 return 268 } 269 270 m1 := comm.P2b{ 271 Ballot: m.Ballot, 272 ID: uint32(p.index), 273 BlockNumber: p.partiCfg.BlkNum, 274 View: p.partiCfg.View, 275 } 276 b, _ := json.Marshal(&m1) 277 sig, err := p.account.Sign(b) 278 if err != nil { 279 log.Error("sign paxos 304 occured error", "error", err) 280 return 281 } 282 p.sendCh <- &SendMsgEvent{ToPeer: comm.BroadCast, Msg: &comm.AcceptMsg{Msg: m1, Sig: sig}} 283 } 284 return 285 } 286 287 if p.p2aCheck(m) != nil { 288 return 289 } 290 291 if m.Ballot == p.ballot { 292 //p.dataPhase1.TxHashs 293 blk := &comm.Block{} 294 err := blk.Deserialize(m.Av) 295 //blk.Block.Transactions, p.dataPhase1.TxHashs 296 297 if err != nil { 298 log.Error("handle p2a tmpblock Deserialize occured err", "error", err) 299 } else { 300 log.Debug("handle p2a block", "", blk.Block.Header.Height, "block", blk, "block.txlen", blk.Block.Transactions.Len()) 301 } 302 303 p.dataPhase2 = &m 304 p.ab = m.Ballot 305 p.av = m.Av 306 h := blk.Block.Hash() 307 bsig, err := p.account.Sign(h[:]) 308 if err != nil { 309 log.Error("sign paxos 335 occured error", "error", err) 310 return 311 } 312 m1 := comm.P2b{ 313 Ballot: p.ballot, 314 ID: uint32(p.index), 315 BlockNumber: p.partiCfg.BlkNum, 316 View: p.partiCfg.View, 317 Signature: bsig, 318 } 319 b, _ := json.Marshal(&m1) 320 sig, err := p.account.Sign(b) 321 if err != nil { 322 log.Error("sign paxos348 occured error", "error", err) 323 return 324 } 325 //fmt.Printf("===>>>>>>>>>>>>>>>>>HandleP2a\n", m.Ballot, p.ballot, bsig) 326 p.sendCh <- &SendMsgEvent{ToPeer: comm.BroadCast, Msg: &comm.AcceptMsg{Msg: m1, Sig: sig}} 327 } 328 } 329 330 // HandleP2b handles P2b message 331 func (p *Paxos) HandleP2b(m comm.P2b) { 332 //fmt.Printf("success--------------->>>>>>>>>>>>>>>>>>>>>>>>>>HandleP2b\n", p.index, p.done, m.Ballot == p.ballot, m.Ballot.ID().Node() == p.index, p.av == nil) 333 if p.done { 334 return 335 } 336 log.Info("func dpoa HandleP2b 01") 337 if m.Ballot > p.ballot { 338 p.ballot = m.Ballot 339 p.active = false 340 } 341 log.Info("func dpoa HandleP2b 02") 342 if m.Ballot.ID().Node() == p.index && m.Ballot == p.ballot { // id 和序号校验 343 p.quorumPhase2.ACK(comm.NewID(0, int(m.ID))) 344 p.sigsMap[uint16(m.ID)] = m.Signature 345 if p.quorumPhase2.Q2() { 346 p.done = true 347 blk := &comm.Block{} 348 blk.Deserialize(p.av) 349 log.Info("func dpoa HandleP2b 03", "blockHeight", blk.Block.Header.Height, "txlen", blk.Block.Transactions.Len()) 350 if len(blk.Block.Sigs.ProcSigs) == 0 { 351 for idx, sig := range p.sigsMap { 352 //fmt.Println(">>$$$$$$$$$$$$$$$$$idx", idx) 353 var d []byte 354 //dd := int2Byte(uint16(idx)) 355 d = append(d, int2Byte(uint16(idx))...) 356 //fmt.Println("1>>$$$$$$$$$$$$$$$$$idx", len(d), byte2Int(d[0:2]), byte2Int(dd)) 357 d = append(d, sig...) 358 blk.Block.Sigs.ProcSigs = append(blk.Block.Sigs.ProcSigs, d) 359 /////////// 360 //fmt.Println("2>>$$$$$$$$$$$$$$$$$idx", byte2Int(d[0:2])) 361 pubStr, _ := GetNode(p.partiCfg.PartiRaw, int(byte2Int(d[0:2]))) 362 363 buf, err := comm2.Hex2Bytes(pubStr) 364 if err != nil { 365 return 366 } 367 368 publicKey, _ := crypto.UnmarshalPubkey(buf) 369 //pubKey, _ := vconfig.Pubkey(pubStr) 370 h := blk.Block.Hash() 371 if fg, err := publicKey.Verify(h[:], d[2:]); !fg && err != nil { 372 //fmt.Errorf("1111111111111111$$$$$$$$$$$$$$$$$idx:%v err:%v", pubStr, err) 373 } else { 374 //fmt.Println(">>$$$$$$$$$$$$$$$$$idx------->done", d) 375 } 376 //if err := signature.Verify(pubKey, h[:], d[2:]); err != nil{ 377 // fmt.Errorf("1111111111111111$$$$$$$$$$$$$$$$$idx:%v err:%v", pubStr, err) 378 // //return err 379 //}else { 380 // fmt.Println(">>$$$$$$$$$$$$$$$$$idx------->done", d) 381 //} 382 } 383 var d []byte 384 h := blk.Block.Hash() 385 bsig, err := p.account.Sign(h[:]) 386 if err != nil { 387 log.Error("sign paxos408 block.hash() occured error", "error", err) 388 return 389 } 390 d = append(d, int2Byte(uint16(p.index))...) 391 d = append(d, bsig...) 392 blk.Block.Sigs.ProcSigs = append(blk.Block.Sigs.ProcSigs, d) 393 } 394 //fmt.Println("success---------------!!!!HandleP2b", blk.GetBlockNum(), len(blk.Block.Sigs.TimeoutSigs), len(blk.Block.Sigs.ProcSigs), len(blk.Block.Sigs.FailerSigs), len(blk.Block.Transactions)) 395 log.Info("func dpoa HandleP2b 04", "blockHeight", blk.GetBlockNum(), "timeout", len(blk.Block.Sigs.TimeoutSigs), "proc", len(blk.Block.Sigs.ProcSigs), "failer", len(blk.Block.Sigs.FailerSigs), "txlen", len(blk.Block.Transactions)) 396 p.sendCh <- blk 397 blockData, _ := blk.Serialize() 398 399 sig, err := p.account.Sign(blockData) 400 if err != nil { 401 log.Error("sign paxos422 blockData occured error", "error", err) 402 return 403 } 404 p.sendCh <- &SendMsgEvent{ToPeer: comm.BroadCast, Msg: &comm.ConsedoneMsg{BlockNumber: p.partiCfg.BlkNum, View: p.partiCfg.View, BlockData: blockData, PublicKey: p.publicKey, SigData: sig}} 405 //fmt.Printf("success HandleP2b||||||||||p.ID():%v, p.ballot:%v, p.ab:%v,time:%v\n", p.index, p.ballot, p.ab, time.Now().String()) 406 } 407 } 408 } 409 410 func (p *Paxos) clean() { 411 time.Sleep(time.Millisecond * 500) 412 //fmt.Println("------------------------->>>>>>>>>>>>>>>>>>>>>>>>>>>clean 22222222") 413 p.done = false 414 p.active = false 415 p.candidateBlock = nil 416 p.partiCfg = nil 417 p.ballot = 0 418 p.dataPhase1 = nil 419 p.dataPhase2 = nil 420 p.totalGas = 0 421 p.ab = 0 422 p.av = nil 423 p.sigsMap = make(map[uint16][]byte) 424 if p.quorumPhase1 != nil { 425 p.quorumPhase1.Reset() 426 } 427 if p.quorumPhase2 != nil { 428 p.quorumPhase2.Reset() 429 } 430 }