github.com/intfoundation/intchain@v0.0.0-20220727031208-4316ad31ca73/consensus/ipbft/types/sign_aggr.go (about)

     1  package types
     2  
     3  import (
     4  	//"bytes"
     5  	//"errors"
     6  	"fmt"
     7  	"math/big"
     8  
     9  	. "github.com/intfoundation/go-common"
    10  	"github.com/intfoundation/go-crypto"
    11  	//"github.com/intfoundation/go-data"
    12  	"github.com/intfoundation/go-wire"
    13  	"io"
    14  )
    15  
    16  //------------------------ signature aggregation -------------------
    17  const MaxSignAggrSize = 22020096 // 21MB TODO make it configurable
    18  
    19  type SignAggr struct {
    20  	ChainID       string
    21  	Height        uint64    `json:"height"`
    22  	Round         int       `json:"round"`
    23  	Type          byte      `json:"type"`
    24  	NumValidators int       `json:"numValidators"`
    25  	BlockID       BlockID   `json:"blockid"`
    26  	Maj23         BlockID   `json:"maj23"`
    27  	BitArray      *BitArray `json:"bitarray"`
    28  	Sum           int64     `json:"sum"`
    29  
    30  	// BLS signature aggregation to be added here
    31  	SignatureAggr crypto.BLSSignature `json:"SignatureAggr"`
    32  	SignBytes     []byte              `json:"sign_bytes"`
    33  }
    34  
    35  func (sa *SignAggr) WriteSignBytes(chainID string, w io.Writer, n *int, err *error) {
    36  	wire.WriteJSON(CanonicalJSONOnceSignAggr{
    37  		chainID,
    38  		CanonicalJSONSignAggr{
    39  			sa.Height,
    40  			sa.Round,
    41  			sa.Type,
    42  			sa.NumValidators,
    43  			CanonicalBlockID(sa.BlockID),
    44  			CanonicalBlockID(sa.BlockID),
    45  			sa.Sum,
    46  		},
    47  	}, w, n, err)
    48  }
    49  
    50  func MakeSignAggr(height uint64, round int, mtype byte, numValidators int, blockID BlockID, chainID string, bitArray *BitArray, signAggr crypto.BLSSignature) *SignAggr {
    51  	return &SignAggr{
    52  		Height:        height,
    53  		Round:         round,
    54  		Type:          mtype,
    55  		NumValidators: numValidators,
    56  		BlockID:       blockID,
    57  		Maj23:         blockID,
    58  		ChainID:       chainID,
    59  		BitArray:      bitArray,
    60  		SignatureAggr: signAggr,
    61  		Sum:           0,
    62  	}
    63  }
    64  
    65  func (sa *SignAggr) SignAggr() crypto.BLSSignature {
    66  	if sa != nil {
    67  		return sa.SignatureAggr
    68  	} else {
    69  		return nil
    70  	}
    71  }
    72  
    73  func (sa *SignAggr) SignRound() int {
    74  	if sa == nil {
    75  		return -1
    76  	} else {
    77  		return sa.Round
    78  	}
    79  }
    80  
    81  func (sa *SignAggr) HasTwoThirdsMajority(valSet *ValidatorSet) bool {
    82  	if valSet == nil {
    83  		return false
    84  	}
    85  	_, votesSum, totalVotes, err := valSet.TalliedVotingPower(sa.BitArray)
    86  	if err != nil {
    87  		return false
    88  	}
    89  
    90  	/*
    91  		quorum := big.NewInt(0)
    92  		quorum.Mul(valSet.totalVotingPower, big.NewInt(2))
    93  		quorum.Div(quorum, big.NewInt(3))
    94  		quorum.Add(quorum, big.NewInt(1))
    95  	*/
    96  	//quorum := Loose23MajorThreshold(valSet.TotalVotingPower(), sa.Round)
    97  	quorum := Loose23MajorThreshold(totalVotes, sa.Round)
    98  
    99  	//return talliedVotingPower.Cmp(quorum) >= 0
   100  	return votesSum.Cmp(quorum) >= 0
   101  }
   102  
   103  func (sa *SignAggr) SetMaj23(blockID BlockID) {
   104  	if sa == nil {
   105  		sa.Maj23 = blockID
   106  	}
   107  }
   108  
   109  func (sa *SignAggr) Size() int {
   110  	if sa == nil {
   111  		return 0
   112  	}
   113  	return (int)(sa.NumValidators)
   114  }
   115  
   116  func (sa *SignAggr) SetBitArray(newBitArray *BitArray) {
   117  	if sa != nil {
   118  		sa.BitArray.Update(newBitArray)
   119  	}
   120  }
   121  
   122  func (sa *SignAggr) IsCommit() bool {
   123  	if sa == nil {
   124  		return false
   125  	}
   126  	if sa.Type != VoteTypePrecommit {
   127  		return false
   128  	}
   129  	return sa.Maj23.IsZero() != false
   130  }
   131  
   132  func (sa *SignAggr) MakeCommit() *Commit {
   133  	//        if sa.Type != types.VoteTypePrecommit {
   134  	//               PanicSanity("Cannot MakeCommit() unless SignAggr.Type is VoteTypePrecommit")
   135  	//        }
   136  
   137  	// Make sure we have a 2/3 majority
   138  	/*        if sa.HasTwoThirdsMajority()== false {
   139  	                  PanicSanity("Cannot MakeCommit() unless a blockhash has +2/3")
   140  	          }
   141  	*/
   142  	return &Commit{
   143  		BlockID:  sa.Maj23,
   144  		Height:   sa.Height,
   145  		Round:    sa.Round,
   146  		BitArray: sa.BitArray.Copy(),
   147  		SignAggr: sa.SignAggr(),
   148  	}
   149  }
   150  
   151  func (sa *SignAggr) SignAggrVerify(msg []byte, valSet *ValidatorSet) bool {
   152  	if msg == nil || valSet == nil {
   153  		return false
   154  	}
   155  	if (int)(sa.BitArray.Size()) != len(valSet.Validators) {
   156  		return false
   157  	}
   158  	pubKey := valSet.AggrPubKey(sa.BitArray)
   159  	return pubKey.VerifyBytes(msg, sa.SignatureAggr) && sa.HasTwoThirdsMajority(valSet)
   160  }
   161  
   162  //func (sa *SignAggr) HasTwoThirdsAny(valSet *ValidatorSet) bool {
   163  //	if sa == nil {
   164  //		return false
   165  //	}
   166  //
   167  //	/*
   168  //		twoThird := new(big.Int).Mul(voteSet.valSet.TotalVotingPower(), big.NewInt(2))
   169  //		twoThird.Div(twoThird, big.NewInt(3))sa
   170  //	*/
   171  //	twoThirdPlus1 := Loose23MajorThreshold(valSet.TotalVotingPower(), sa.Round)
   172  //	twoThird := twoThirdPlus1.Sub(twoThirdPlus1, big.NewInt(1))
   173  //
   174  //	return big.NewInt(sa.Sum).Cmp(twoThird) == 1
   175  //}
   176  
   177  func (sa *SignAggr) HasAll(valSet *ValidatorSet) bool {
   178  	return big.NewInt(sa.Sum).Cmp(valSet.TotalVotingPower()) == 0
   179  }
   180  
   181  // Returns either a blockhash (or nil) that received +2/3 majority.
   182  // If there exists no such majority, returns (nil, PartSetHeader{}, false).
   183  func (sa *SignAggr) TwoThirdsMajority() (blockID BlockID, ok bool) {
   184  	if sa == nil {
   185  		return BlockID{}, false
   186  	}
   187  	if sa.Maj23.IsZero() == true {
   188  		return BlockID{}, false
   189  	} else {
   190  		return sa.Maj23, true
   191  	}
   192  }
   193  
   194  func (va *SignAggr) StringShort() string {
   195  	return va.StringIndented("")
   196  }
   197  
   198  func (va *SignAggr) String() string {
   199  	return va.StringIndented("")
   200  }
   201  
   202  func (va *SignAggr) StringIndented(indent string) string {
   203  	if va == nil {
   204  		return "nil-SignAggr"
   205  	}
   206  	return fmt.Sprintf(`SignAggr{
   207  %s  %v
   208  %s  %v
   209  %s  %v
   210  %s  %v
   211  %s  %v
   212  }`,
   213  		indent, va.Height,
   214  		indent, va.Round,
   215  		indent, va.Type,
   216  		indent, va.NumValidators,
   217  		indent, va.BlockID)
   218  }