github.com/annchain/OG@v0.0.9/consensus/annsensus/adapter_bft.go (about)

     1  package annsensus
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"github.com/annchain/OG/consensus/bft"
     7  	ogcrypto2 "github.com/annchain/OG/deprecated/ogcrypto"
     8  	"github.com/annchain/OG/og/account"
     9  	"github.com/sirupsen/logrus"
    10  )
    11  
    12  type ProxyBftPeerCommunicator struct {
    13  	bftMessageAdapter BftMessageAdapter // either TrustfulBftAdapter or PlainBftAdapter
    14  	annsensusOutgoing AnnsensusPeerCommunicatorOutgoing
    15  	pipe              chan *bft.BftMessageEvent
    16  }
    17  
    18  func NewProxyBftPeerCommunicator(
    19  	bftMessageAdapter BftMessageAdapter,
    20  	annsensusOutgoing AnnsensusPeerCommunicatorOutgoing) *ProxyBftPeerCommunicator {
    21  	return &ProxyBftPeerCommunicator{
    22  		bftMessageAdapter: bftMessageAdapter,
    23  		annsensusOutgoing: annsensusOutgoing,
    24  		pipe:              make(chan *bft.BftMessageEvent),
    25  	}
    26  }
    27  
    28  func (p *ProxyBftPeerCommunicator) Broadcast(msg bft.BftMessage, peers []bft.BftPeer) {
    29  	annsensusMessage, err := p.bftMessageAdapter.AdaptBftMessage(msg)
    30  	if err != nil {
    31  		panic("adapt should never fail")
    32  	}
    33  	// adapt the interface so that the request can be handled by annsensus
    34  	annsensusPeers := make([]AnnsensusPeer, len(peers))
    35  	for i, peer := range peers {
    36  		adaptedValue, err := p.bftMessageAdapter.AdaptBftPeer(peer)
    37  		if err != nil {
    38  			panic("adapt should never fail")
    39  		}
    40  		annsensusPeers[i] = adaptedValue
    41  	}
    42  
    43  	p.annsensusOutgoing.Broadcast(annsensusMessage, annsensusPeers)
    44  }
    45  
    46  func (p *ProxyBftPeerCommunicator) Unicast(msg bft.BftMessage, peer bft.BftPeer) {
    47  	// adapt the interface so that the request can be handled by annsensus
    48  	annsensusMessage, err := p.bftMessageAdapter.AdaptBftMessage(msg)
    49  	if err != nil {
    50  		panic("adapt should never fail")
    51  	}
    52  	annsensusPeer, err := p.bftMessageAdapter.AdaptBftPeer(peer)
    53  	if err != nil {
    54  		panic("adapt should never fail")
    55  	}
    56  	p.annsensusOutgoing.Unicast(annsensusMessage, annsensusPeer)
    57  }
    58  
    59  func (p *ProxyBftPeerCommunicator) GetPipeOut() chan *bft.BftMessageEvent {
    60  	// the channel to be consumed by the downstream.
    61  	return p.pipe
    62  }
    63  
    64  func (p *ProxyBftPeerCommunicator) GetPipeIn() chan *bft.BftMessageEvent {
    65  	// the channel to be fed by other peers
    66  	return p.pipe
    67  }
    68  
    69  func (p *ProxyBftPeerCommunicator) Run() {
    70  	// nothing to do
    71  	return
    72  }
    73  
    74  type BftMessageUnmarshaller struct {
    75  }
    76  
    77  func (b *BftMessageUnmarshaller) Unmarshal(messageType bft.BftMessageType, message []byte) (outMsg bft.BftMessage, err error) {
    78  	switch messageType {
    79  	case bft.BftMessageTypeProposal:
    80  		m := &bft.BftMessageProposal{
    81  			Value: &bft.StringProposal{},
    82  		}
    83  		_, err = m.UnmarshalMsg(message)
    84  		outMsg = m
    85  	case bft.BftMessageTypePreVote:
    86  		m := &bft.BftMessagePreVote{}
    87  		_, err = m.UnmarshalMsg(message)
    88  		outMsg = m
    89  	case bft.BftMessageTypePreCommit:
    90  		m := &bft.BftMessagePreCommit{}
    91  		_, err = m.UnmarshalMsg(message)
    92  		outMsg = m
    93  	default:
    94  		err = errors.New("message type of Bft not supported")
    95  	}
    96  	return
    97  }
    98  
    99  // TrustfulBftAdapter signs and validate messages using pubkey/privkey given by DKG/BLS
   100  type TrustfulBftAdapter struct {
   101  	signatureProvider      account.SignatureProvider
   102  	termHolder             HistoricalTermsHolder
   103  	bftMessageUnmarshaller *BftMessageUnmarshaller
   104  }
   105  
   106  func (r *TrustfulBftAdapter) AdaptAnnsensusPeer(annPeer AnnsensusPeer) (bft.BftPeer, error) {
   107  	return bft.BftPeer{
   108  		Id:             annPeer.Id,
   109  		PublicKey:      annPeer.PublicKey,
   110  		Address:        annPeer.Address,
   111  		PublicKeyBytes: annPeer.PublicKeyBytes,
   112  	}, nil
   113  }
   114  
   115  func (r *TrustfulBftAdapter) AdaptBftPeer(bftPeer bft.BftPeer) (AnnsensusPeer, error) {
   116  	return AnnsensusPeer{
   117  		Id:             bftPeer.Id,
   118  		PublicKey:      bftPeer.PublicKey,
   119  		Address:        bftPeer.Address,
   120  		PublicKeyBytes: bftPeer.PublicKeyBytes,
   121  	}, nil
   122  }
   123  
   124  func (r *TrustfulBftAdapter) AdaptBftMessage(outgoingMsg bft.BftMessage) (msg AnnsensusMessage, err error) {
   125  	signed := r.Sign(outgoingMsg)
   126  	msg = &signed
   127  	return
   128  }
   129  
   130  func NewTrustfulBftAdapter(
   131  	signatureProvider account.SignatureProvider,
   132  	termHolder HistoricalTermsHolder) *TrustfulBftAdapter {
   133  	return &TrustfulBftAdapter{signatureProvider: signatureProvider, termHolder: termHolder}
   134  }
   135  
   136  func (r *TrustfulBftAdapter) Sign(rawMessage bft.BftMessage) AnnsensusMessageBftSigned {
   137  	publicKey, signature := r.signatureProvider.Sign(rawMessage.SignatureTargets())
   138  	signedMessage := AnnsensusMessageBftSigned{
   139  		InnerMessageType: uint16(rawMessage.GetType()),
   140  		InnerMessage:     rawMessage.SignatureTargets(),
   141  		Signature:        signature,
   142  		PublicKey:        publicKey,
   143  	}
   144  	//SessionId:     partner.CurrentTerm(),
   145  	//PublicKey: account.PublicKey.KeyBytes,
   146  	return signedMessage
   147  }
   148  
   149  // Multicast must be anonymous since it is actually among all partners, not all nodes.
   150  //func (r *TrustfulBftAdapter) Multicast(msg bft.BftMessage, peers []bft.BftPeer) {
   151  //	signed := r.Sign(msg)
   152  //	for _, peer := range peers {
   153  //		r.p2pSender.AnonymousSendMessage(message.BinaryMessageType(msg.Type), &signed, &peer.PublicKey)
   154  //	}
   155  //}
   156  //
   157  //// Unicast must be anonymous
   158  //func (r *TrustfulBftAdapter) Unicast(msg bft.BftMessage, peer bft.BftPeer) {
   159  //	signed := r.Sign(msg)
   160  //	r.p2pSender.AnonymousSendMessage(message.BinaryMessageType(msg.Type), &signed, &peer.PublicKey)
   161  //}
   162  
   163  func (b *TrustfulBftAdapter) VerifyParnterIdentity(signedMsg *AnnsensusMessageBftSigned) error {
   164  	term, ok := b.termHolder.GetTermById(signedMsg.TermId)
   165  	if !ok {
   166  		// this term is unknown.
   167  		return errors.New("term not found")
   168  	}
   169  
   170  	// use public key to find sourcePartner
   171  	for _, peer := range term.contextProvider.GetTerm().Senators {
   172  		if bytes.Equal(peer.PublicKey.KeyBytes, signedMsg.PublicKey) {
   173  			return nil
   174  		}
   175  	}
   176  	return errors.New("public key not found in current term")
   177  }
   178  
   179  func (b *TrustfulBftAdapter) VerifyMessageSignature(outMsg bft.BftMessage, publicKey []byte, signature []byte) error {
   180  	ok := ogcrypto2.VerifySignature(publicKey, outMsg.SignatureTargets(), signature)
   181  	if !ok {
   182  		return errors.New("signature invalid")
   183  	}
   184  	return nil
   185  }
   186  
   187  func (b *TrustfulBftAdapter) AdaptAnnsensusMessage(incomingMsg AnnsensusMessage) (msg bft.BftMessage, err error) { // Only allows SignedOgPartnerMessage
   188  	if incomingMsg.GetType() != AnnsensusMessageTypeBftSigned {
   189  		err = errors.New("TrustfulBftAdapter received a message of an unsupported type")
   190  		return
   191  	}
   192  
   193  	signedMsg, ok := incomingMsg.(*AnnsensusMessageBftSigned)
   194  	if !ok {
   195  		err = errors.New("TrustfulBftAdapter received a message of type AnnsensusMessageBftSigned but it is not.")
   196  		return
   197  	}
   198  
   199  	// check inner type
   200  	bftMessage, err := b.bftMessageUnmarshaller.Unmarshal(bft.BftMessageType(signedMsg.InnerMessageType), signedMsg.InnerMessage)
   201  	if err != nil {
   202  		return
   203  	}
   204  
   205  	err = b.VerifyParnterIdentity(signedMsg)
   206  	if err != nil {
   207  		logrus.WithField("term", signedMsg.TermId).WithError(err).Warn("bft message partner identity is not valid or unknown")
   208  		err = errors.New("bft message partner identity is not valid or unknown")
   209  		return
   210  	}
   211  
   212  	err = b.VerifyMessageSignature(bftMessage, signedMsg.PublicKey, signedMsg.Signature)
   213  	if err != nil {
   214  		logrus.WithError(err).Warn("bft message signature is not valid")
   215  		err = errors.New("bft message signature is not valid")
   216  		return
   217  	}
   218  
   219  	return bftMessage, nil
   220  }
   221  
   222  // PlainBftAdapter will not wrap the message using MessageTypeAnnsensusSigned
   223  type PlainBftAdapter struct {
   224  	BftMessageUnmarshaller *BftMessageUnmarshaller
   225  }
   226  
   227  func (p PlainBftAdapter) AdaptAnnsensusPeer(annPeer AnnsensusPeer) (bft.BftPeer, error) {
   228  	return bft.BftPeer{
   229  		Id:             annPeer.Id,
   230  		PublicKey:      annPeer.PublicKey,
   231  		Address:        annPeer.Address,
   232  		PublicKeyBytes: annPeer.PublicKeyBytes,
   233  	}, nil
   234  }
   235  
   236  func (p PlainBftAdapter) AdaptBftPeer(bftPeer bft.BftPeer) (AnnsensusPeer, error) {
   237  	return AnnsensusPeer{
   238  		Id:             bftPeer.Id,
   239  		PublicKey:      bftPeer.PublicKey,
   240  		Address:        bftPeer.Address,
   241  		PublicKeyBytes: bftPeer.PublicKeyBytes,
   242  	}, nil
   243  }
   244  
   245  func (p PlainBftAdapter) AdaptAnnsensusMessage(incomingMsg AnnsensusMessage) (msg bft.BftMessage, err error) {
   246  	if incomingMsg.GetType() != AnnsensusMessageTypeBftPlain {
   247  		err = errors.New("PlainBftAdapter received a message of an unsupported type")
   248  		return
   249  	}
   250  	iMsg := incomingMsg.(*AnnsensusMessageBftPlain)
   251  	innerMessageType := bft.BftMessageType(iMsg.InnerMessageType)
   252  
   253  	switch innerMessageType {
   254  	case bft.BftMessageTypeProposal:
   255  		fallthrough
   256  	case bft.BftMessageTypePreVote:
   257  		fallthrough
   258  	case bft.BftMessageTypePreCommit:
   259  		msg, err = p.BftMessageUnmarshaller.Unmarshal(innerMessageType, iMsg.InnerMessage)
   260  	default:
   261  		err = errors.New("PlainBftAdapter received a message of an unsupported inner type")
   262  	}
   263  	return
   264  
   265  }
   266  
   267  func (p PlainBftAdapter) AdaptBftMessage(outgoingMsg bft.BftMessage) (adaptedMessage AnnsensusMessage, err error) {
   268  	var msgBytes []byte
   269  	switch outgoingMsg.GetType() {
   270  	case bft.BftMessageTypeProposal:
   271  		omsg := outgoingMsg.(*bft.BftMessageProposal)
   272  		msgBytes, err = omsg.MarshalMsg(nil)
   273  		if err != nil {
   274  			return
   275  		}
   276  		adaptedMessage = &AnnsensusMessageBftPlain{
   277  			InnerMessageType: uint16(omsg.GetType()),
   278  			InnerMessage:     msgBytes,
   279  		}
   280  	case bft.BftMessageTypePreVote:
   281  		omsg := outgoingMsg.(*bft.BftMessagePreVote)
   282  		msgBytes, err = omsg.MarshalMsg(nil)
   283  		if err != nil {
   284  			return
   285  		}
   286  		adaptedMessage = &AnnsensusMessageBftPlain{
   287  			InnerMessageType: uint16(omsg.GetType()),
   288  			InnerMessage:     msgBytes,
   289  		}
   290  	case bft.BftMessageTypePreCommit:
   291  		omsg := outgoingMsg.(*bft.BftMessagePreCommit)
   292  		msgBytes, err = omsg.MarshalMsg(nil)
   293  		if err != nil {
   294  			return
   295  		}
   296  		adaptedMessage = &AnnsensusMessageBftPlain{
   297  			InnerMessageType: uint16(omsg.GetType()),
   298  			InnerMessage:     msgBytes,
   299  		}
   300  	default:
   301  		err = errors.New("PlainBftAdapter received a message of an unsupported type")
   302  	}
   303  	return
   304  }