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  }